必要权限申请设置完成。

This commit is contained in:
2025-12-14 04:08:10 +08:00
parent 2d12397f5e
commit 3d3301064c
8 changed files with 221 additions and 184 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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() {

View File

@@ -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());
}
}
};

View File

@@ -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);
}
}
}

View File

@@ -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); // 不突破免打扰

View File

@@ -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 11API30
// 小米手机自启动权限页面包名/类名(小米专属跳转路径)
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 {
// 方案2Action备用跳转兼容机型差异
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, "【电池优化权限】显示手动开启提示弹窗");
}
}