必要权限申请设置完成。
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Sat Dec 13 18:07:45 GMT 2025
|
||||
#Sat Dec 13 20:06:18 GMT 2025
|
||||
stageCount=2
|
||||
libraryProject=
|
||||
baseVersion=15.14
|
||||
publishVersion=15.14.1
|
||||
buildCount=3
|
||||
buildCount=39
|
||||
baseBetaVersion=15.14.2
|
||||
|
||||
@@ -4,24 +4,12 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="cc.winboll.studio.powerbell">
|
||||
|
||||
<!-- 拍摄照片和视频 -->
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
|
||||
<!-- 运行前台服务 -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
<!-- 读取您共享存储空间中的内容 -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
|
||||
<!-- 修改或删除您共享存储空间中的内容 -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<!-- 开机启动 -->
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
<!-- MANAGE_EXTERNAL_STORAGE -->
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<!-- 显示通知 -->
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
|
||||
@@ -31,9 +19,6 @@
|
||||
<!-- BATTERY_STATS -->
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS"/>
|
||||
|
||||
<!-- 计算应用存储空间 -->
|
||||
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera.autofocus"/>
|
||||
@@ -233,4 +218,4 @@
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
@@ -14,7 +14,6 @@ import cc.winboll.studio.powerbell.utils.AppCacheUtils;
|
||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
|
||||
import cc.winboll.studio.powerbell.utils.BitmapCacheUtils;
|
||||
import cc.winboll.studio.powerbell.utils.PermissionUtils;
|
||||
import java.io.File;
|
||||
|
||||
public class App extends GlobalApplication {
|
||||
|
||||
@@ -68,6 +68,7 @@ public class MainActivity extends WinBoLLActivity {
|
||||
public static MainActivity _mMainActivity;
|
||||
static MainViewFragment _mMainViewFragment;
|
||||
static Handler _mHandler;
|
||||
PermissionUtils permissionUtils = PermissionUtils.getInstance();
|
||||
|
||||
private App mApplication;
|
||||
private AppConfigUtils mAppConfigUtils;
|
||||
@@ -121,13 +122,18 @@ public class MainActivity extends WinBoLLActivity {
|
||||
initViewHolder();
|
||||
initCriticalView();
|
||||
loadNonCriticalViewDelayed();
|
||||
|
||||
// 权限申请
|
||||
PermissionUtils.getInstance().checkAndRequestMediaImagesPermission(this, REQUEST_READ_MEDIA_IMAGES);
|
||||
}
|
||||
|
||||
// 移除 onSaveInstanceState 方法
|
||||
// 移除 onRestoreInstanceState 方法
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
|
||||
// 电池优化权限(通用所有机型)
|
||||
if (!permissionUtils.checkIgnoreBatteryOptimizationPermission(this)) {
|
||||
// 未拥有权限,发起申请
|
||||
permissionUtils.requestIgnoreBatteryOptimizationPermission(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
@@ -189,7 +195,7 @@ public class MainActivity extends WinBoLLActivity {
|
||||
startActivity(new Intent(this, ClearRecordActivity.class));
|
||||
break;
|
||||
case R.id.action_changepicture:
|
||||
startActivity(new Intent(this, BackgroundSettingsActivity.class));
|
||||
startActivityForResult(new Intent(this, BackgroundSettingsActivity.class), REQUEST_READ_MEDIA_IMAGES);
|
||||
break;
|
||||
case R.id.action_unittestactivity:
|
||||
startActivity(new Intent(this, MainUnitTestActivity.class));
|
||||
@@ -209,20 +215,20 @@ public class MainActivity extends WinBoLLActivity {
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
|
||||
if (requestCode == PermissionUtils.REQUEST_IGNORE_BATTERY_OPTIMIZATION) {
|
||||
// 自启动权限(小米专属)
|
||||
if (permissionUtils.checkAutoStartPermission(this)) {
|
||||
// 小米机型,发起自启动权限申请
|
||||
permissionUtils.requestAutoStartPermission(this);
|
||||
}
|
||||
} else if (requestCode == REQUEST_READ_MEDIA_IMAGES) {
|
||||
if (_mHandler != null) {
|
||||
_mHandler.sendEmptyMessage(MSG_LOAD_BACKGROUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == REQUEST_READ_MEDIA_IMAGES) {
|
||||
PermissionUtils.getInstance().handleStoragePermissionResult(this, requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
||||
@@ -3,6 +3,7 @@ package cc.winboll.studio.powerbell.activities;
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.BitmapFactory;
|
||||
@@ -15,6 +16,7 @@ import android.os.Looper;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.FileProvider;
|
||||
@@ -29,7 +31,6 @@ import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
|
||||
import cc.winboll.studio.powerbell.utils.BitmapCacheUtils;
|
||||
import cc.winboll.studio.powerbell.utils.FileUtils;
|
||||
import cc.winboll.studio.powerbell.utils.ImageCropUtils;
|
||||
import cc.winboll.studio.powerbell.utils.PermissionUtils;
|
||||
import cc.winboll.studio.powerbell.utils.UriUtils;
|
||||
import cc.winboll.studio.powerbell.views.BackgroundView;
|
||||
import java.io.BufferedOutputStream;
|
||||
@@ -51,7 +52,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity {
|
||||
|
||||
// ====================== 成员变量 ======================
|
||||
private BackgroundSourceUtils mBgSourceUtils;
|
||||
private PermissionUtils mPermissionUtils;
|
||||
private BitmapCacheUtils mBitmapCache;
|
||||
|
||||
private Toolbar mToolbar;
|
||||
@@ -81,7 +81,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity {
|
||||
mBackgroundView = findViewById(R.id.background_view);
|
||||
mBgSourceUtils = BackgroundSourceUtils.getInstance(this);
|
||||
mBgSourceUtils.loadSettings();
|
||||
mPermissionUtils = PermissionUtils.getInstance();
|
||||
mBitmapCache = BitmapCacheUtils.getInstance();
|
||||
|
||||
// 初始化临时文件与目录
|
||||
@@ -126,11 +125,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity {
|
||||
LogUtils.d(TAG, "【回调触发】requestCode:" + requestCode + ",resultCode:" + resultCode);
|
||||
|
||||
try {
|
||||
if (requestCode == PermissionUtils.REQUEST_READ_MEDIA_IMAGES && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
handleStoragePermissionCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultCode != RESULT_OK) {
|
||||
handleOperationCancelOrFail();
|
||||
return;
|
||||
@@ -156,13 +150,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
LogUtils.d(TAG, "【权限回调】转发处理 requestCode:" + requestCode);
|
||||
mPermissionUtils.handleStoragePermissionResult(this, requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
LogUtils.d(TAG, "【生命周期】finish 触发,isCommitSettings:" + isCommitSettings + ",isPreviewBackgroundChanged:" + isPreviewBackgroundChanged);
|
||||
@@ -235,15 +222,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
LogUtils.d(TAG, "【按钮点击】选择图片");
|
||||
if (Build.VERSION.SDK_INT >= SDK_VERSION_TIRAMISU) {
|
||||
if (mPermissionUtils.checkAndRequestMediaImagesPermission(BackgroundSettingsActivity.this, REQUEST_READ_MEDIA)) {
|
||||
launchImageSelector();
|
||||
}
|
||||
} else {
|
||||
if (mPermissionUtils.checkAndRequestStoragePermission(BackgroundSettingsActivity.this)) {
|
||||
launchImageSelector();
|
||||
}
|
||||
}
|
||||
launchImageSelector();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -293,22 +272,17 @@ public class BackgroundSettingsActivity extends WinBoLLActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPermissionUtils.checkAndRequestStoragePermission(BackgroundSettingsActivity.this)) {
|
||||
LogUtils.d(TAG, "【拍照权限】已获取");
|
||||
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
try {
|
||||
Uri photoUri = getFileProviderUri(mfTakePhoto);
|
||||
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
|
||||
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
|
||||
LogUtils.d(TAG, "【拍照启动】Uri:" + photoUri.toString());
|
||||
} catch (Exception e) {
|
||||
String errMsg = "拍照启动异常:" + e.getMessage();
|
||||
ToastUtils.show(errMsg.substring(0, 20));
|
||||
LogUtils.e(TAG, "【拍照失败】" + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
LogUtils.d(TAG, "【拍照权限】已申请");
|
||||
}
|
||||
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
try {
|
||||
Uri photoUri = getFileProviderUri(mfTakePhoto);
|
||||
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
|
||||
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
|
||||
LogUtils.d(TAG, "【拍照启动】Uri:" + photoUri.toString());
|
||||
} catch (Exception e) {
|
||||
String errMsg = "拍照启动异常:" + e.getMessage();
|
||||
ToastUtils.show(errMsg.substring(0, 20));
|
||||
LogUtils.e(TAG, "【拍照失败】" + e.getMessage());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@ import android.view.View;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.utils.PermissionUtils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
@@ -50,18 +48,4 @@ public class SettingsActivity extends WinBoLLActivity implements IWinBoLLActivit
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onCheckPermission(View view) {
|
||||
//ToastUtils.show("onCheckPermission");
|
||||
PermissionUtils.getInstance().checkAndRequestMediaImagesPermission(this, REQUEST_READ_MEDIA_IMAGES);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == REQUEST_READ_MEDIA_IMAGES) {
|
||||
PermissionUtils.getInstance().handleStoragePermissionResult(this, requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public class NotificationManagerUtils {
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
);
|
||||
channel.setDescription(CHANNEL_DESC_BATTERY_REMIND);
|
||||
channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM), null); // 闹钟铃声
|
||||
channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), null); // 闹钟铃声
|
||||
channel.enableVibration(true);
|
||||
channel.setVibrationPattern(VIBRATE_PATTERN);
|
||||
channel.setBypassDnd(true); // 突破免打扰
|
||||
@@ -139,7 +139,8 @@ public class NotificationManagerUtils {
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
);
|
||||
channel.setDescription(CHANNEL_DESC_TEMP_ALERT);
|
||||
channel.setSound(null, null); // 仅震动,不发声
|
||||
//channel.setSound(null, null); // 仅震动,不发声
|
||||
channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), null); // 闹钟铃声
|
||||
channel.enableVibration(true);
|
||||
channel.setVibrationPattern(VIBRATE_PATTERN);
|
||||
channel.setBypassDnd(false); // 不突破免打扰
|
||||
|
||||
@@ -1,32 +1,35 @@
|
||||
package cc.winboll.studio.powerbell.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
|
||||
/**
|
||||
* 权限申请工具类
|
||||
* 适配 Android 13+ 媒体权限 & 低版本存储权限
|
||||
* 兼容 SDK 版本低于 33 的编译环境
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/12/14 03:05
|
||||
* @Describe 权限申请工具类(Java7兼容版)
|
||||
* 适配 小米手机+API30,专注自启动权限、电池优化权限检查与申请
|
||||
*/
|
||||
public class PermissionUtils {
|
||||
private static final String TAG = "PermissionUtils";
|
||||
// 存储权限请求码
|
||||
public static final int REQUEST_STORAGE = 1000;
|
||||
// 媒体图片权限请求码(Android 13+)
|
||||
public static final int REQUEST_READ_MEDIA_IMAGES = 1001;
|
||||
// ====================== 常量定义(统一管理,首屏可见)======================
|
||||
public static final String TAG = "PermissionUtils";
|
||||
// 权限请求码(仅保留核心权限场景)
|
||||
public static final int REQUEST_IGNORE_BATTERY_OPTIMIZATION = 1000; // 电池优化权限
|
||||
public static final int REQUEST_AUTO_START = 1001; // 自启动权限(小米专属)
|
||||
// SDK版本常量(适配API30,替代系统枚举)
|
||||
private static final int SDK_VERSION_R = 30; // Android 11(API30)
|
||||
// 小米手机自启动权限页面包名/类名(小米专属跳转路径)
|
||||
private static final String XIAOMI_AUTO_START_PACKAGE = "com.miui.securitycenter";
|
||||
private static final String XIAOMI_AUTO_START_CLASS = "com.miui.permcenter.autostart.AutoStartManagementActivity";
|
||||
|
||||
// 手动定义 Android 13+ 媒体图片权限常量(解决 SDK 低于 33 无法识别问题)
|
||||
private static final String READ_MEDIA_IMAGES = "android.permission.READ_MEDIA_IMAGES";
|
||||
// Android 13 对应的 SDK 版本号(替代 Build.VERSION_CODES.TIRAMISU)
|
||||
private static final int SDK_VERSION_TIRAMISU = 33;
|
||||
|
||||
// 单例模式
|
||||
// ====================== 单例模式(Java7标准双重校验锁)======================
|
||||
private static volatile PermissionUtils sInstance;
|
||||
|
||||
private PermissionUtils() {}
|
||||
@@ -36,99 +39,184 @@ public class PermissionUtils {
|
||||
synchronized (PermissionUtils.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new PermissionUtils();
|
||||
LogUtils.d(TAG, "【单例初始化】PermissionUtils 实例创建成功");
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
// ====================== 自启动权限(拆分检查+请求,小米专属)======================
|
||||
/**
|
||||
* 检查并请求 存储权限(Android 12及以下)
|
||||
* 检查是否拥有自启动权限(小米手机专属判断,API30适配)
|
||||
* 注:小米自启动无系统API直接校验,通过「是否为小米机型」+「功能场景间接判断」,此处返回机型适配状态
|
||||
* @param activity 上下文Activity(不可为null)
|
||||
* @return true:小米机型(需手动开启权限);false:非小米机型(无需申请)
|
||||
*/
|
||||
public boolean checkAndRequestStoragePermission(Activity activity) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
// Android 11+ 无需申请 READ_EXTERNAL_STORAGE,直接返回true
|
||||
return true;
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
String[] permissions = {
|
||||
android.Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
};
|
||||
if (ContextCompat.checkSelfPermission(activity, permissions[0]) != PackageManager.PERMISSION_GRANTED
|
||||
|| ContextCompat.checkSelfPermission(activity, permissions[1]) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(activity, permissions, REQUEST_STORAGE);
|
||||
return false;
|
||||
}
|
||||
public boolean checkAutoStartPermission(Activity activity) {
|
||||
if (activity == null) {
|
||||
LogUtils.e(TAG, "【自启动权限-检查】失败:Activity为空");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
LogUtils.d(TAG, "【自启动权限-检查】开始,设备品牌:" + Build.BRAND + ",系统版本:" + Build.VERSION.SDK_INT);
|
||||
|
||||
// 仅小米机型需要申请自启动权限,非小米直接返回false(无需处理)
|
||||
boolean isXiaomi = Build.BRAND.toLowerCase().contains("xiaomi");
|
||||
LogUtils.d(TAG, "【自启动权限-检查】结果:" + (isXiaomi ? "小米机型(需手动开启)" : "非小米机型(无需申请)"));
|
||||
return isXiaomi;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并请求 媒体图片权限(Android 13+)
|
||||
* 兼容 SDK 编译版本低于 33 的情况
|
||||
* 请求自启动权限(小米手机专属,API30适配,跳转系统页面引导开启)
|
||||
* @param activity 申请权限的Activity(不可为null)
|
||||
*/
|
||||
public boolean checkAndRequestMediaImagesPermission(Activity activity, int requestCode) {
|
||||
// 用数值 33 替代 Build.VERSION_CODES.TIRAMISU
|
||||
if (Build.VERSION.SDK_INT >= SDK_VERSION_TIRAMISU) {
|
||||
// 用手动定义的权限常量替代 android.Manifest.permission.READ_MEDIA_IMAGES
|
||||
if (ContextCompat.checkSelfPermission(activity, READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(activity, new String[]{READ_MEDIA_IMAGES}, requestCode);
|
||||
return false;
|
||||
}
|
||||
public void requestAutoStartPermission(Activity activity) {
|
||||
if (activity == null) {
|
||||
LogUtils.e(TAG, "【自启动权限-请求】失败:Activity为空");
|
||||
return;
|
||||
}
|
||||
// 低版本已通过存储权限覆盖,直接返回true
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限请求结果处理
|
||||
*/
|
||||
public void handleStoragePermissionResult(Activity activity, int requestCode, String[] permissions, int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_STORAGE:
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
LogUtils.d(TAG, "存储权限申请成功");
|
||||
} else {
|
||||
LogUtils.e(TAG, "存储权限申请失败");
|
||||
}
|
||||
break;
|
||||
case REQUEST_READ_MEDIA_IMAGES:
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
LogUtils.d(TAG, "媒体图片权限申请成功");
|
||||
} else {
|
||||
LogUtils.e(TAG, "媒体图片权限申请失败");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LogUtils.d(TAG, "未知权限请求码:" + requestCode);
|
||||
// 先检查机型,非小米不执行请求
|
||||
if (!checkAutoStartPermission(activity)) {
|
||||
LogUtils.d(TAG, "【自启动权限-请求】非小米机型,无需发起请求");
|
||||
return;
|
||||
}
|
||||
}
|
||||
LogUtils.d(TAG, "【自启动权限-请求】开始处理,系统版本:" + Build.VERSION.SDK_INT);
|
||||
|
||||
/**
|
||||
* 检查是否有管理所有文件权限(Android 11+)
|
||||
*/
|
||||
public boolean checkManageExternalStoragePermission(Activity activity) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
return android.os.Environment.isExternalStorageManager();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求管理所有文件权限(Android 11+)
|
||||
*/
|
||||
public void requestManageExternalStoragePermission(Activity activity, int requestCode) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
// API30+ 小米手机:优先精准跳转自启动管理页
|
||||
if (Build.VERSION.SDK_INT >= SDK_VERSION_R) {
|
||||
try {
|
||||
android.content.Intent intent = new android.content.Intent(
|
||||
android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
|
||||
);
|
||||
intent.setData(android.net.Uri.parse("package:" + activity.getPackageName()));
|
||||
activity.startActivityForResult(intent, requestCode);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "请求管理文件权限异常:" + e.getMessage());
|
||||
// 方案1:组件名精准跳转(成功率最高)
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(new ComponentName(XIAOMI_AUTO_START_PACKAGE, XIAOMI_AUTO_START_CLASS));
|
||||
activity.startActivityForResult(intent, REQUEST_AUTO_START);
|
||||
LogUtils.d(TAG, "【自启动权限-请求】跳转小米自启动管理页(组件名跳转)");
|
||||
} catch (Exception e1) {
|
||||
try {
|
||||
// 方案2:Action备用跳转(兼容机型差异)
|
||||
Intent intent = new Intent("miui.intent.action.OP_AUTO_START");
|
||||
intent.setClassName(XIAOMI_AUTO_START_PACKAGE, XIAOMI_AUTO_START_CLASS);
|
||||
activity.startActivityForResult(intent, REQUEST_AUTO_START);
|
||||
LogUtils.d(TAG, "【自启动权限-请求】跳转小米自启动管理页(Action跳转)");
|
||||
} catch (Exception e2) {
|
||||
// 方案3:终极备用(跳转系统设置,引导手动操作)
|
||||
Intent intent = new Intent(Settings.ACTION_SETTINGS);
|
||||
activity.startActivityForResult(intent, REQUEST_AUTO_START);
|
||||
LogUtils.w(TAG, "【自启动权限-请求】跳转系统设置页(引导手动开启)");
|
||||
showAutoStartTipsDialog(activity);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// API30以下小米手机:兼容低版本跳转逻辑
|
||||
LogUtils.d(TAG, "【自启动权限-请求】API30以下小米机型,执行低版本跳转");
|
||||
try {
|
||||
Intent intent = new Intent(XIAOMI_AUTO_START_CLASS);
|
||||
intent.setPackage(XIAOMI_AUTO_START_PACKAGE);
|
||||
activity.startActivityForResult(intent, REQUEST_AUTO_START);
|
||||
} catch (Exception e) {
|
||||
Intent intent = new Intent(Settings.ACTION_SETTINGS);
|
||||
activity.startActivityForResult(intent, REQUEST_AUTO_START);
|
||||
showAutoStartTipsDialog(activity);
|
||||
}
|
||||
}
|
||||
|
||||
// ====================== 电池优化权限(拆分检查+请求,通用所有机型)======================
|
||||
/**
|
||||
* 检查是否拥有「忽略电池优化」权限(API30适配,通用所有机型,精准返回权限状态)
|
||||
* @param activity 上下文Activity(不可为null)
|
||||
* @return true:已拥有(忽略优化);false:未拥有(需申请)
|
||||
*/
|
||||
public boolean checkIgnoreBatteryOptimizationPermission(Activity activity) {
|
||||
if (activity == null) {
|
||||
LogUtils.e(TAG, "【电池优化权限-检查】失败:Activity为空");
|
||||
return false;
|
||||
}
|
||||
LogUtils.d(TAG, "【电池优化权限-检查】开始,系统版本:" + Build.VERSION.SDK_INT);
|
||||
|
||||
// API23以下无电池优化权限,直接视为已拥有
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
LogUtils.d(TAG, "【电池优化权限-检查】API23以下无此权限,视为已拥有");
|
||||
return true;
|
||||
}
|
||||
|
||||
// API23+ 精准校验权限状态
|
||||
PowerManager powerManager = (PowerManager) activity.getSystemService(Activity.POWER_SERVICE);
|
||||
if (powerManager == null) {
|
||||
LogUtils.e(TAG, "【电池优化权限-检查】获取PowerManager失败,无法校验");
|
||||
return false;
|
||||
}
|
||||
boolean isIgnored = powerManager.isIgnoringBatteryOptimizations(activity.getPackageName());
|
||||
LogUtils.d(TAG, "【电池优化权限-检查】结果:" + (isIgnored ? "已拥有(忽略优化)" : "未拥有(需申请)"));
|
||||
return isIgnored;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求「忽略电池优化」权限(API30适配,通用所有机型,自动判断是否需要申请)
|
||||
* @param activity 申请权限的Activity(不可为null)
|
||||
*/
|
||||
public void requestIgnoreBatteryOptimizationPermission(Activity activity) {
|
||||
if (activity == null) {
|
||||
LogUtils.e(TAG, "【电池优化权限-请求】失败:Activity为空");
|
||||
return;
|
||||
}
|
||||
// 先检查权限,已拥有则直接返回
|
||||
if (checkIgnoreBatteryOptimizationPermission(activity)) {
|
||||
LogUtils.d(TAG, "【电池优化权限-请求】已拥有权限,无需发起申请");
|
||||
return;
|
||||
}
|
||||
LogUtils.w(TAG, "【电池优化权限-请求】未拥有权限,开始发起申请");
|
||||
|
||||
try {
|
||||
// 方案1:直接跳转权限申请页(用户一键同意,优先使用)
|
||||
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
|
||||
intent.setData(Uri.parse("package:" + activity.getPackageName()));
|
||||
activity.startActivityForResult(intent, REQUEST_IGNORE_BATTERY_OPTIMIZATION);
|
||||
LogUtils.d(TAG, "【电池优化权限-请求】跳转系统权限申请页");
|
||||
} catch (Exception e) {
|
||||
// 方案2:备用跳转(跳转优化管理列表,引导手动选择)
|
||||
Intent intent = new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS);
|
||||
activity.startActivityForResult(intent, REQUEST_IGNORE_BATTERY_OPTIMIZATION);
|
||||
LogUtils.w(TAG, "【电池优化权限-请求】跳转优化管理页(引导手动开启)");
|
||||
showBatteryOptTipsDialog(activity);
|
||||
}
|
||||
}
|
||||
|
||||
// ====================== 辅助方法(提示弹窗+结果处理)======================
|
||||
/**
|
||||
* 显示自启动权限手动开启提示弹窗(小米机型跳转失败时使用)
|
||||
*/
|
||||
private void showAutoStartTipsDialog(final Activity activity) {
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle("权限申请提示")
|
||||
.setMessage("请手动开启自启动权限,否则应用后台功能可能异常:\n1. 进入安全中心 → 应用管理 → 自启动管理\n2. 找到本应用,开启「允许自启动」开关")
|
||||
.setPositiveButton("知道了", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.setCancelable(false)
|
||||
.show();
|
||||
LogUtils.d(TAG, "【自启动权限】显示手动开启提示弹窗");
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示电池优化权限手动开启提示弹窗(跳转失败时使用)
|
||||
*/
|
||||
private void showBatteryOptTipsDialog(final Activity activity) {
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle("权限申请提示")
|
||||
.setMessage("请手动忽略电池优化,否则应用后台运行可能被限制:\n1. 进入设置 → 电池 → 电池优化\n2. 找到本应用,选择「不优化」")
|
||||
.setPositiveButton("知道了", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.setCancelable(false)
|
||||
.show();
|
||||
LogUtils.d(TAG, "【电池优化权限】显示手动开启提示弹窗");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user