diff --git a/powerbell/build.properties b/powerbell/build.properties
index 37aa41a..26cebb6 100644
--- a/powerbell/build.properties
+++ b/powerbell/build.properties
@@ -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
diff --git a/powerbell/src/main/AndroidManifest.xml b/powerbell/src/main/AndroidManifest.xml
index 1f88863..4113f48 100644
--- a/powerbell/src/main/AndroidManifest.xml
+++ b/powerbell/src/main/AndroidManifest.xml
@@ -4,24 +4,12 @@
xmlns:tools="http://schemas.android.com/tools"
package="cc.winboll.studio.powerbell">
-
-
-
-
-
-
-
-
-
-
-
-
@@ -31,9 +19,6 @@
-
-
-
@@ -233,4 +218,4 @@
-
+
\ No newline at end of file
diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/App.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/App.java
index fddf7b6..cbdef5e 100644
--- a/powerbell/src/main/java/cc/winboll/studio/powerbell/App.java
+++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/App.java
@@ -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 {
diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java
index 807e871..a4a4b55 100644
--- a/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java
+++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java
@@ -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() {
diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java
index f44c487..0ffc69c 100644
--- a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java
+++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java
@@ -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());
+ }
}
};
diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/SettingsActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/SettingsActivity.java
index a8acf58..6dd136b 100644
--- a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/SettingsActivity.java
+++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/SettingsActivity.java
@@ -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&豆包大模型
@@ -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);
- }
- }
}
diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/NotificationManagerUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/NotificationManagerUtils.java
index dee3f4f..dbcf8f0 100644
--- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/NotificationManagerUtils.java
+++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/NotificationManagerUtils.java
@@ -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); // 不突破免打扰
diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/PermissionUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/PermissionUtils.java
index 924e0c9..a336d7f 100644
--- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/PermissionUtils.java
+++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/PermissionUtils.java
@@ -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&豆包大模型
+ * @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, "【电池优化权限】显示手动开启提示弹窗");
}
}