From 796d826331c8dbe253c195765bf5e0a4fe76cc8d Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Thu, 18 Dec 2025 13:14:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BA=90=E7=A0=81=E6=95=B4=E7=90=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/ControlCenterService.java | 603 ++++++------------ 1 file changed, 180 insertions(+), 423 deletions(-) diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ControlCenterService.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ControlCenterService.java index 705892b..2bf4621 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ControlCenterService.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ControlCenterService.java @@ -26,7 +26,7 @@ import java.util.List; /** * @Author ZhanGSKen&豆包大模型 * @Date 2025/12/17 15:48 - * @Describe 电池提醒核心服务:修复前台服务超时异常,优先在onCreate发送通知,适配Java7+API36 + * @Describe 电池提醒核心服务:修复前台服务超时异常,优先在onCreate发送通知,适配Java7+API30 */ public class ControlCenterService extends Service { // ================================== 静态常量(置顶统一管理,避免魔法值)================================= @@ -34,28 +34,22 @@ public class ControlCenterService extends Service { // 服务指令常量(带包名前缀,防止冲突) public static final String ACTION_RESTART_REMIND_THREAD = "cc.winboll.studio.powerbell.action.RESTART_REMIND_THREAD"; public static final String EXTRA_APP_CONFIG_BEAN = "cc.winboll.studio.powerbell.extra.APP_CONFIG_BEAN"; - // 新增:应用前台/后台状态同步指令(用于MainActivity与服务联动) -// public static final String ACTION_SYNC_APP_FOREGROUND_STATE = "cc.winboll.studio.powerbell.action.SYNC_APP_FOREGROUND_STATE"; -// public static final String EXTRA_APP_FOREGROUND_STATE = "cc.winboll.studio.powerbell.extra.APP_FOREGROUND_STATE"; - // ================================== 核心成员变量(按依赖优先级排序,私有封装)================================= - // 服务控制核心(本地持久化管理,替代Intent传递) + // ================================== 成员变量(按功能分类,私有封装+并发锁保护)================================= + // 服务控制核心 private ControlCenterServiceBean mServiceControlBean; // 业务核心组件 - private ControlCenterServiceHandler mServiceHandler; // 服务通信Handler - private RemindThread mRemindThread; // 电量提醒线程 - private NotificationManagerUtils mNotificationManager; // 通知管理工具类 - private AppConfigBean mCurrentConfigBean; // 当前应用配置 - // 前台服务相关 - private NotificationMessage mForegroundNotifyMsg; // 前台保活通知模型 - // 新增:应用前台状态标记(内存缓存,同步MainActivity状态) - private boolean mIsAppForeground = false; - // 状态标记(并发安全) - private boolean isServiceRunning = false; // 服务运行状态 - private boolean mIsDestroyed = false; // 服务销毁标记 - private final Object mServiceLock = new Object(); // 全局并发锁 + private ControlCenterServiceHandler mServiceHandler; + private RemindThread mRemindThread; + private NotificationManagerUtils mNotificationManager; + private AppConfigBean mCurrentConfigBean; + private NotificationMessage mForegroundNotifyMsg; + // 状态标记 + private boolean isServiceRunning; + private boolean mIsDestroyed; + private final Object mServiceLock = new Object(); - // ================================== 服务生命周期方法(核心修复:onCreate优先发送通知)================================= + // ================================== 服务生命周期方法(核心流程入口)================================= @Override public void onCreate() { super.onCreate(); @@ -63,45 +57,33 @@ public class ControlCenterService extends Service { synchronized (mServiceLock) { isServiceRunning = true; mIsDestroyed = false; - - // ================================== 【修复点1:最优先执行前台通知发送】================================= + // 优先发送前台通知,避免5秒超时异常 initForegroundNotificationImmediately(); - - // 原有逻辑:读取本地服务控制配置 + // 加载本地服务控制配置 mServiceControlBean = ControlCenterServiceBean.loadBean(this, ControlCenterServiceBean.class); if (mServiceControlBean == null) { mServiceControlBean = new ControlCenterServiceBean(false); - ControlCenterServiceBean.saveBean(this, mServiceControlBean); // 持久化默认配置 - LogUtils.d(TAG, "onCreate: 本地无控制配置,创建默认禁用配置并持久化"); - } else { - LogUtils.d(TAG, "onCreate: 从本地读取服务控制配置,启用状态=" + mServiceControlBean.isEnableService()); + ControlCenterServiceBean.saveBean(this, mServiceControlBean); + LogUtils.d(TAG, "onCreate: 本地无配置,创建默认禁用配置并持久化"); } } - LogUtils.d(TAG, "onCreate: 服务创建完成,前台通知已发送,当前服务控制状态:" + (mServiceControlBean.isEnableService() ? "启用" : "禁用")); + LogUtils.d(TAG, "onCreate: 服务创建完成,前台通知已发送,启用状态=" + mServiceControlBean.isEnableService()); } @Override public int onStartCommand(Intent intent, int flags, int startId) { - LogUtils.d(TAG, "onStartCommand: 服务启动指令触发,flags=" + flags); - // 第一步:读取本地最新控制配置(优先级最高,实时同步用户设置) + LogUtils.d(TAG, "onStartCommand: 服务启动指令触发"); + // 读取最新控制配置 loadLatestServiceControlConfig(); - // 第二步:根据控制状态,分支执行逻辑 synchronized (mServiceLock) { if (mServiceControlBean.isEnableService()) { - LogUtils.d(TAG, "onStartCommand: 服务已启用,执行核心逻辑"); - // 启用状态:处理指令+启动业务,返回START_STICKY(回收后重启) + LogUtils.d(TAG, "onStartCommand: 服务已启用,处理外部指令并初始化业务"); handleExternalCommand(intent); - // ================================== 【修复点2:删除rebindForegroundNotify(),避免重复调用】================================= - initServiceBusinessIfNeed(); // 按需初始化业务(避免重复初始化) -// // 新增:业务初始化完成后,同步应用前台状态到线程(防止状态丢失) -// syncAppForegroundStateToThread(); - LogUtils.d(TAG, "onStartCommand: 核心逻辑执行完成,返回START_STICKY"); + initServiceBusinessIfNeed(); return START_STICKY; } else { - LogUtils.d(TAG, "onStartCommand: 服务已禁用,不执行核心逻辑"); - // 禁用状态:停止所有业务+释放资源,返回父类默认值(回收后不主动重启) + LogUtils.d(TAG, "onStartCommand: 服务已禁用,停止所有业务"); stopAllBusinessSafely(); - LogUtils.d(TAG, "onStartCommand: 已停止所有业务,返回父类默认onStartCommand结果"); return super.onStartCommand(intent, flags, startId); } } @@ -110,13 +92,12 @@ public class ControlCenterService extends Service { @Override public void onDestroy() { super.onDestroy(); - LogUtils.d(TAG, "onDestroy: 服务开始销毁,释放所有资源"); + LogUtils.d(TAG, "onDestroy: 服务开始销毁"); synchronized (mServiceLock) { isServiceRunning = false; mIsDestroyed = true; - mIsAppForeground = false; // 新增:重置前台状态 } - // 顺序释放资源(前台服务→线程→Handler→通知→配置→控制Bean) + // 顺序释放资源 stopForegroundService(); stopRemindThreadSafely(); destroyHandler(); @@ -127,109 +108,95 @@ public class ControlCenterService extends Service { @Override public IBinder onBind(Intent intent) { - return null; // 无需绑定服务,返回null + return null; } - // ================================== 【新增核心方法:优先发送前台通知,带兜底方案】================================= + // ================================== 前台通知核心方法(优先执行,防止超时)================================= /** - * 独立初始化前台通知并立即发送,不依赖任何业务逻辑,确保5秒内完成startForeground() - * 防止工具类异常导致超时,内置兜底方案 + * 立即初始化前台通知,内置兜底方案 */ private void initForegroundNotificationImmediately() { - LogUtils.d(TAG, "initForegroundNotificationImmediately: 强制初始化前台通知"); + LogUtils.d(TAG, "initForegroundNotificationImmediately: 初始化前台通知"); try { - // 1. 初始化通知工具类 if (mNotificationManager == null) { mNotificationManager = new NotificationManagerUtils(this); } - // 2. 构建极简前台通知模型(不依赖业务配置,确保最快速度发送) if (mForegroundNotifyMsg == null) { mForegroundNotifyMsg = new NotificationMessage(); mForegroundNotifyMsg.setTitle("电池监测服务"); mForegroundNotifyMsg.setContent("后台运行中"); mForegroundNotifyMsg.setRemindMSG("service_running"); } - // 3. 立即调用工具类发送前台通知 mNotificationManager.startForegroundServiceNotify(this, mForegroundNotifyMsg); LogUtils.d(TAG, "initForegroundNotificationImmediately: 前台通知发送成功,ID=" + NotificationManagerUtils.NOTIFY_ID_FOREGROUND_SERVICE); } catch (Exception e) { LogUtils.e(TAG, "initForegroundNotificationImmediately: 工具类发送失败,执行兜底方案", e); - // 兜底方案:绕过工具类,直接构建Notification调用startForeground fallbackStartForeground(); } } /** - * 前台通知兜底方案:当工具类异常时,直接创建通知,确保不触发超时异常 + * 前台通知兜底方案,直接构建Notification */ private void fallbackStartForeground() { try { Notification notification = new NotificationCompat.Builder(this, NotificationManagerUtils.CHANNEL_ID_FOREGROUND) .setContentTitle("电池监测服务") .setContentText("后台运行中") - .setSmallIcon(R.drawable.ic_launcher) // 必须设置小图标,否则通知不显示 + .setSmallIcon(R.drawable.ic_launcher) .setPriority(NotificationCompat.PRIORITY_LOW) .build(); - // 直接调用startForeground,不依赖任何外部工具 startForeground(NotificationManagerUtils.NOTIFY_ID_FOREGROUND_SERVICE, notification); LogUtils.d(TAG, "fallbackStartForeground: 兜底前台通知发送成功"); } catch (Exception e) { - LogUtils.e(TAG, "fallbackStartForeground: 兜底发送失败,服务会被系统强制杀死", e); + LogUtils.e(TAG, "fallbackStartForeground: 兜底发送失败,服务会被系统杀死", e); } } - // ================================== 核心:服务控制配置(本地持久化读写,替代Intent传递)================================= + // ================================== 服务控制配置管理(本地持久化+内存同步)================================= /** - * 读取本地最新服务控制配置(实时同步,确保与用户设置一致) + * 读取本地最新服务控制配置 */ private void loadLatestServiceControlConfig() { - LogUtils.d(TAG, "loadLatestServiceControlConfig: 读取本地最新服务控制配置"); + LogUtils.d(TAG, "loadLatestServiceControlConfig: 读取本地配置"); synchronized (mServiceLock) { - ControlCenterServiceBean latestControlBean = ControlCenterServiceBean.loadBean(this, ControlCenterServiceBean.class); - if (latestControlBean != null) { - boolean oldState = mServiceControlBean.isEnableService(); - boolean newState = latestControlBean.isEnableService(); - mServiceControlBean = latestControlBean; - LogUtils.d(TAG, "loadLatestServiceControlConfig: 控制配置更新完成,旧状态=" + oldState + ",新状态=" + newState); + ControlCenterServiceBean latestBean = ControlCenterServiceBean.loadBean(this, ControlCenterServiceBean.class); + if (latestBean != null) { + mServiceControlBean = latestBean; + LogUtils.d(TAG, "loadLatestServiceControlConfig: 配置更新完成,启用状态=" + mServiceControlBean.isEnableService()); } else { - LogUtils.w(TAG, "loadLatestServiceControlConfig: 本地无控制配置,沿用当前状态=" + mServiceControlBean.isEnableService()); + LogUtils.w(TAG, "loadLatestServiceControlConfig: 本地无配置,沿用当前状态"); } } - LogUtils.d(TAG, "loadLatestServiceControlConfig: 控制配置读取完成,当前服务启用状态=" + mServiceControlBean.isEnableService()); } /** - * 更新服务控制配置(本地持久化+内存同步,对外提供统一入口) + * 更新并持久化服务控制配置 */ private void updateAndSaveServiceControlConfig(ControlCenterServiceBean newControlBean) { - LogUtils.d(TAG, "updateAndSaveServiceControlConfig: 更新服务控制配置,新状态=" + newControlBean.isEnableService()); if (newControlBean == null) { - LogUtils.e(TAG, "updateAndSaveServiceControlConfig: 新控制配置为空,更新失败"); + LogUtils.e(TAG, "updateAndSaveServiceControlConfig: 配置为空,更新失败"); return; } - + LogUtils.d(TAG, "updateAndSaveServiceControlConfig: 更新配置,启用状态=" + newControlBean.isEnableService()); synchronized (mServiceLock) { - // 内存同步+本地持久化(原子操作,确保一致性) mServiceControlBean = newControlBean; ControlCenterServiceBean.saveBean(this, mServiceControlBean); - LogUtils.d(TAG, "updateAndSaveServiceControlConfig: 控制配置更新并持久化完成"); } } - // ================================== 业务按需初始化/停止方法(适配启用/禁用状态切换)================================= + // ================================== 业务初始化与停止(按需加载,避免重复)================================= /** - * 按需初始化核心业务(仅服务启用且未初始化时执行,避免重复创建) + * 按需初始化核心业务 */ private void initServiceBusinessIfNeed() { - LogUtils.d(TAG, "initServiceBusinessIfNeed: 按需初始化业务"); + LogUtils.d(TAG, "initServiceBusinessIfNeed: 校验业务初始化条件"); synchronized (mServiceLock) { - // 校验:服务启用+未初始化+服务运行中 if (!mServiceControlBean.isEnableService() || mServiceHandler != null || !isServiceRunning || mIsDestroyed) { - LogUtils.w(TAG, "initServiceBusinessIfNeed: 无需初始化业务(禁用/已初始化/服务未运行)"); + LogUtils.w(TAG, "initServiceBusinessIfNeed: 无需初始化业务"); return; } - - // 初始化通知+配置+业务逻辑(完整启动核心流程) + // 初始化通知+配置+业务逻辑 initNotificationManager(); loadDefaultConfig(); initServiceBusinessLogic(); @@ -238,85 +205,38 @@ public class ControlCenterService extends Service { } /** - * 安全停止所有核心业务(服务禁用时执行,释放所有业务资源) + * 安全停止所有核心业务 */ private void stopAllBusinessSafely() { - LogUtils.d(TAG, "stopAllBusinessSafely: 停止所有核心业务"); + LogUtils.d(TAG, "stopAllBusinessSafely: 停止所有业务"); synchronized (mServiceLock) { - // 停止线程+销毁Handler+释放通知+置空业务引用 stopRemindThreadSafely(); destroyHandler(); stopForegroundService(); releaseNotificationResource(); mCurrentConfigBean = null; mForegroundNotifyMsg = null; - mIsAppForeground = false; // 新增:重置前台状态 - LogUtils.d(TAG, "stopAllBusinessSafely: 所有核心业务已停止"); } } - // ================================== 核心业务初始化方法(按依赖顺序排列)================================= /** - * 初始化通知管理工具类,构建前台保活通知模型 - * 【修复点3:移除内部的startForegroundNotifyImmediately()调用,避免重复发送】 + * 初始化通知管理工具类 */ private void initNotificationManager() { - LogUtils.d(TAG, "initNotificationManager: 初始化通知工具类"); - try { - if (mNotificationManager == null) { - mNotificationManager = new NotificationManagerUtils(this); - } - if (mForegroundNotifyMsg == null) { - mForegroundNotifyMsg = new NotificationMessage(); - mForegroundNotifyMsg.setTitle("电池提醒服务运行中"); - mForegroundNotifyMsg.setContent("后台持续监测电池状态,确保提醒及时"); - mForegroundNotifyMsg.setRemindMSG("service_running"); - // 移除:此处不再发送通知,通知已在onCreate中发送 - } - LogUtils.d(TAG, "initNotificationManager: 通知工具类初始化完成"); - } catch (Exception e) { - LogUtils.e(TAG, "initNotificationManager: 初始化失败", e); + LogUtils.d(TAG, "initNotificationManager: 初始化通知工具"); + if (mNotificationManager == null) { + mNotificationManager = new NotificationManagerUtils(this); + } + if (mForegroundNotifyMsg == null) { + mForegroundNotifyMsg = new NotificationMessage(); + mForegroundNotifyMsg.setTitle("电池提醒服务运行中"); + mForegroundNotifyMsg.setContent("后台持续监测电池状态"); + mForegroundNotifyMsg.setRemindMSG("service_running"); } } /** - * 立即启动前台保活通知(API26+ 前台服务必需) - * 注:当前仅作为备用方法,实际已在initForegroundNotificationImmediately中调用 - */ - private void startForegroundNotifyImmediately() { - LogUtils.d(TAG, "startForegroundNotifyImmediately: 启动前台保活通知"); - if (mNotificationManager == null || mForegroundNotifyMsg == null) { - LogUtils.e(TAG, "startForegroundNotifyImmediately: 通知工具类/模型为空,启动失败"); - return; - } - - try { - mNotificationManager.startForegroundServiceNotify(this, mForegroundNotifyMsg); - LogUtils.d(TAG, "startForegroundNotifyImmediately: 前台通知启动成功,ID=" + NotificationManagerUtils.NOTIFY_ID_FOREGROUND_SERVICE); - } catch (Exception e) { - LogUtils.e(TAG, "startForegroundNotifyImmediately: 前台通知启动异常", e); - } - } - - /** - * 重新绑定前台通知(已删除调用,防止重复执行startForeground) - */ - private void rebindForegroundNotify() { - if (mNotificationManager == null || mNotificationManager.getForegroundServiceNotify() == null) { - LogUtils.w(TAG, "rebindForegroundNotify: 通知工具类/前台通知为空,跳过绑定"); - return; - } - - try { - startForeground(NotificationManagerUtils.NOTIFY_ID_FOREGROUND_SERVICE, mNotificationManager.getForegroundServiceNotify()); - LogUtils.d(TAG, "rebindForegroundNotify: 前台通知重新绑定成功"); - } catch (Exception e) { - LogUtils.e(TAG, "rebindForegroundNotify: 重新绑定前台通知异常", e); - } - } - - /** - * 加载默认应用配置(服务启动时兜底) + * 加载默认应用配置 */ private void loadDefaultConfig() { LogUtils.d(TAG, "loadDefaultConfig: 加载默认配置"); @@ -327,93 +247,71 @@ public class ControlCenterService extends Service { mCurrentConfigBean.setEnableUsageReminder(true); mCurrentConfigBean.setUsageReminderValue(20); mCurrentConfigBean.setBatteryDetectInterval(1000); - LogUtils.d(TAG, "loadDefaultConfig: 默认配置加载完成,充电阈值80%,耗电阈值20%"); - } else { - LogUtils.d(TAG, "loadDefaultConfig: 配置已存在,无需重复加载"); + LogUtils.d(TAG, "loadDefaultConfig: 默认配置加载完成"); } } /** - * 初始化业务核心逻辑(Handler+提醒线程) + * 初始化业务核心逻辑(Handler+线程) */ private void initServiceBusinessLogic() { - LogUtils.d(TAG, "initServiceBusinessLogic: 初始化业务逻辑"); + LogUtils.d(TAG, "initServiceBusinessLogic: 初始化Handler与线程"); if (mServiceHandler == null) { mServiceHandler = new ControlCenterServiceHandler(this); } - // 复用线程重启方法,统一启动逻辑 restartRemindThreadSafely(); - LogUtils.d(TAG, "initServiceBusinessLogic: 业务逻辑初始化完成"); } - // ================================== 线程管理方法(安全启动/停止/重启,保障并发安全)================================= + // ================================== 提醒线程管理(安全启停,并发保护)================================= /** - * 安全重启提醒线程(彻底销毁旧线程,创建全新实例,避免重复启动) + * 安全重启提醒线程 */ public void restartRemindThreadSafely() { - LogUtils.d(TAG, "restartRemindThreadSafely: 开始重启提醒线程"); + LogUtils.d(TAG, "restartRemindThreadSafely: 开始重启线程"); synchronized (mServiceLock) { - // 服务禁用/已销毁,直接返回 if (!isServiceRunning || mIsDestroyed || !mServiceControlBean.isEnableService()) { - LogUtils.e(TAG, "restartRemindThreadSafely: 服务未运行/已销毁/已禁用,启动失败"); + LogUtils.e(TAG, "restartRemindThreadSafely: 服务状态异常,启动失败"); return; } - - // 先停止旧线程 + // 停止旧线程 stopRemindThreadSafely(); - - // 校验Handler,避免无效启动 if (mServiceHandler == null) { LogUtils.e(TAG, "restartRemindThreadSafely: Handler为空,启动失败"); return; } - - // 销毁旧单例,创建新线程实例 + // 创建新线程实例 RemindThread.destroyInstance(); mRemindThread = RemindThread.getInstance(this, mServiceHandler); - // 同步配置并开启提醒 syncConfigToRemindThread(); -// // 新增:同步应用前台状态(确保新线程启动时状态正确) -// syncAppForegroundStateToThread(); - - // 双重校验,避免线程重复启动 + // 启动线程 if (mRemindThread != null && !mRemindThread.isAlive() && !mRemindThread.isThreadStarted()) { try { mRemindThread.start(); - LogUtils.d(TAG, "restartRemindThreadSafely: 新线程启动成功,ID=" + mRemindThread.getId() + ",前台状态=" + mIsAppForeground); + LogUtils.d(TAG, "restartRemindThreadSafely: 新线程启动成功,ID=" + mRemindThread.getId()); } catch (IllegalThreadStateException e) { LogUtils.e(TAG, "restartRemindThreadSafely: 线程重复启动异常", e); mRemindThread = null; - } catch (Exception e) { - LogUtils.e(TAG, "restartRemindThreadSafely: 启动线程异常", e); - mRemindThread = null; } } else { - LogUtils.w(TAG, "restartRemindThreadSafely: 线程已启动/实例异常,跳过启动"); - mRemindThread = null; + LogUtils.w(TAG, "restartRemindThreadSafely: 线程状态异常,跳过启动"); } } - LogUtils.d(TAG, "restartRemindThreadSafely: 线程重启流程结束"); } /** - * 安全停止提醒线程(中断休眠+等待终止+释放资源,无残留) + * 安全停止提醒线程 */ private void stopRemindThreadSafely() { - LogUtils.d(TAG, "stopRemindThreadSafely: 开始停止提醒线程"); + LogUtils.d(TAG, "stopRemindThreadSafely: 停止提醒线程"); if (mRemindThread == null) { - LogUtils.w(TAG, "stopRemindThreadSafely: 线程实例为空,跳过停止"); + LogUtils.w(TAG, "stopRemindThreadSafely: 线程实例为空"); return; } - try { - // 触发线程内部停止逻辑 if (mRemindThread.isThreadStarted() || mRemindThread.isAlive()) { mRemindThread.setIsReminding(false); mRemindThread.stopThread(); - LogUtils.d(TAG, "stopRemindThreadSafely: 触发线程内部停止"); - - // 等待线程终止(超时1秒,避免阻塞服务) + // 等待线程终止,超时1秒强制中断 long waitStartTime = System.currentTimeMillis(); while (mRemindThread.isAlive()) { if (System.currentTimeMillis() - waitStartTime > 1000) { @@ -427,140 +325,95 @@ public class ControlCenterService extends Service { } catch (Exception e) { LogUtils.e(TAG, "stopRemindThreadSafely: 停止线程异常", e); } finally { - // 彻底释放资源 mRemindThread = null; RemindThread.destroyInstance(); - LogUtils.d(TAG, "stopRemindThreadSafely: 线程停止完成,资源已释放"); } } /** - * 同步配置到提醒线程(原子操作,避免并发修改) + * 同步配置到提醒线程 */ private void syncConfigToRemindThread() { - LogUtils.d(TAG, "syncConfigToRemindThread: 同步配置到线程"); + LogUtils.d(TAG, "syncConfigToRemindThread: 同步配置"); synchronized (mServiceLock) { if (mRemindThread == null || mCurrentConfigBean == null) { - LogUtils.e(TAG, "syncConfigToRemindThread: 线程/配置为空,同步失败"); + LogUtils.e(TAG, "syncConfigToRemindThread: 线程或配置为空,同步失败"); return; } mRemindThread.setAppConfigBean(mCurrentConfigBean); mRemindThread.setIsReminding(true); - LogUtils.d(TAG, "syncConfigToRemindThread: 配置同步完成"); } } + // ================================== 外部指令处理(接收Intent指令)================================= /** - * 新增:同步应用前台状态到RemindThread(核心联动逻辑) - * 确保线程实时感知应用前台/后台状态,控制提醒开关 - */ -// private void syncAppForegroundStateToThread() { -// LogUtils.d(TAG, "syncAppForegroundStateToThread: 同步前台状态,当前状态=" + mIsAppForeground); -// synchronized (mServiceLock) { -// if (mRemindThread == null || mIsDestroyed || !isServiceRunning) { -// LogUtils.w(TAG, "syncAppForegroundStateToThread: 线程未启动/服务已销毁,同步失败"); -// return; -// } -// // 调用RemindThread新增方法,同步前台状态(线程安全) -// mRemindThread.setAppForeground(mIsAppForeground); -// LogUtils.d(TAG, "syncAppForegroundStateToThread: 前台状态同步完成"); -// } -// } - - // ================================== 外部指令处理方法(新增前台状态同步指令,完善链路)================================= - /** - * 处理外部发送的服务指令(如重启线程、更新配置、同步前台状态) + * 处理外部发送的服务指令 */ private void handleExternalCommand(Intent intent) { - LogUtils.d(TAG, "handleExternalCommand: 开始处理外部指令"); - if (intent == null) { - LogUtils.e(TAG, "handleExternalCommand: Intent为空,跳过处理"); + LogUtils.d(TAG, "handleExternalCommand: 处理外部指令"); + if (intent == null || TextUtils.isEmpty(intent.getAction())) { + LogUtils.e(TAG, "handleExternalCommand: Intent或Action为空"); return; } - String action = intent.getAction(); - if (TextUtils.isEmpty(action)) { - LogUtils.e(TAG, "handleExternalCommand: 指令Action为空,跳过处理"); - return; - } - - // 1. 处理线程重启指令(仅同步业务配置,服务控制配置从本地读取) if (ACTION_RESTART_REMIND_THREAD.equals(action)) { - // 读取本地最新控制配置,确保状态同步 - loadLatestServiceControlConfig(); - // 仅启用状态下,更新业务配置并重启线程 synchronized (mServiceLock) { if (mServiceControlBean.isEnableService()) { AppConfigBean newConfig = (AppConfigBean) intent.getSerializableExtra(EXTRA_APP_CONFIG_BEAN); if (newConfig != null) { mCurrentConfigBean = newConfig; - LogUtils.d(TAG, "handleExternalCommand: 收到线程重启指令,已更新业务配置"); + LogUtils.d(TAG, "handleExternalCommand: 收到配置更新,重启线程"); restartRemindThreadSafely(); } else { - LogUtils.e(TAG, "handleExternalCommand: 新业务配置为空,重启线程失败"); + LogUtils.e(TAG, "handleExternalCommand: 配置为空,重启失败"); } } else { - LogUtils.w(TAG, "handleExternalCommand: 服务已禁用,忽略线程重启指令"); + LogUtils.w(TAG, "handleExternalCommand: 服务已禁用,忽略指令"); } } - } -// else if (ACTION_SYNC_APP_FOREGROUND_STATE.equals(action)) { -// boolean isForeground = intent.getBooleanExtra(EXTRA_APP_FOREGROUND_STATE, false); -// synchronized (mServiceLock) { -// mIsAppForeground = isForeground; -// LogUtils.d(TAG, "handleExternalCommand: 收到前台状态同步指令,更新状态=" + isForeground); -// // 同步状态到线程(实时生效) -// syncAppForegroundStateToThread(); -// } -// } - LogUtils.d(TAG, "handleExternalCommand: 外部指令处理完成"); + } } - // ================================== 服务资源释放方法(顺序化释放,防内存泄漏)================================= + // ================================== 资源释放方法(防止内存泄漏)================================= /** - * 停止前台服务(取消通知+移除前台状态) + * 停止前台服务 */ private void stopForegroundService() { LogUtils.d(TAG, "stopForegroundService: 停止前台服务"); - // 取消前台通知 if (mNotificationManager != null) { mNotificationManager.cancelForegroundServiceNotify(); } - // 移除前台服务状态 try { stopForeground(STOP_FOREGROUND_REMOVE); - LogUtils.d(TAG, "stopForegroundService: 前台服务状态移除成功"); } catch (Exception e) { - LogUtils.e(TAG, "stopForegroundService: 移除前台状态异常", e); + LogUtils.e(TAG, "stopForegroundService: 停止前台状态异常", e); } } /** - * 销毁Handler(移除所有任务,避免内存泄漏) + * 销毁Handler */ private void destroyHandler() { - LogUtils.d(TAG, "destroyHandler: 销毁服务Handler"); + LogUtils.d(TAG, "destroyHandler: 销毁Handler"); if (mServiceHandler != null) { mServiceHandler.removeCallbacksAndMessages(null); mServiceHandler = null; - LogUtils.d(TAG, "destroyHandler: Handler销毁完成"); } } /** - * 释放通知资源(调用工具类释放方法) + * 释放通知资源 */ private void releaseNotificationResource() { LogUtils.d(TAG, "releaseNotificationResource: 释放通知资源"); if (mNotificationManager != null) { mNotificationManager.release(); mNotificationManager = null; - LogUtils.d(TAG, "releaseNotificationResource: 通知资源释放完成"); } } /** - * 置空所有引用,帮助GC回收 + * 置空所有引用 */ private void clearAllReferences() { mForegroundNotifyMsg = null; @@ -569,142 +422,135 @@ public class ControlCenterService extends Service { LogUtils.d(TAG, "clearAllReferences: 所有引用已置空"); } - // ================================== 静态工具方法(修复启停逻辑颠倒问题)================================= + // ================================== 静态工具方法(对外提供服务入口)================================= /** - * 启动服务(静态入口,从本地读取控制配置,显式绑定包名,适配API30+) - * 【修复点4:统一使用startForegroundService,适配API26+】 + * 启动服务 */ public static void startControlCenterService(Context context) { - LogUtils.d(TAG, "startControlCenterService: 启动服务入口"); + LogUtils.d(TAG, "startControlCenterService: 启动服务"); if (context == null) { - LogUtils.e(TAG, "startControlCenterService: Context为空,启动失败"); + LogUtils.e(TAG, "startControlCenterService: Context为空"); return; } Intent intent = new Intent(context, ControlCenterService.class); - // 修复:API26+必须调用startForegroundService,避免系统异常 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(intent); } else { context.startService(intent); } - LogUtils.d(TAG, "startControlCenterService: 服务启动指令发送成功"); } /** - * 停止服务(静态入口,显式绑定包名) + * 停止服务 */ public static void stopControlCenterService(Context context) { - LogUtils.d(TAG, "stopControlCenterService: 停止服务入口"); + LogUtils.d(TAG, "stopControlCenterService: 停止服务"); if (context == null) { - LogUtils.e(TAG, "stopControlCenterService: Context为空,停止失败"); + LogUtils.e(TAG, "stopControlCenterService: Context为空"); return; } Intent intent = new Intent(context, ControlCenterService.class); context.stopService(intent); - LogUtils.d(TAG, "stopControlCenterService: 服务停止指令发送成功"); } /** - * 新增:更新服务控制配置(本地持久化,动态切换服务启用/禁用状态) - * 【修复点5:修复启停逻辑颠倒问题】 + * 更新服务控制配置并启停服务 */ public static void updateServiceControlConfig(Context context, ControlCenterServiceBean controlBean) { - LogUtils.d(TAG, "updateServiceControlConfig: 更新服务控制配置,新状态=" + controlBean.isEnableService()); + LogUtils.d(TAG, "updateServiceControlConfig: 更新控制配置,启用状态=" + controlBean.isEnableService()); if (context == null || controlBean == null) { - LogUtils.e(TAG, "updateServiceControlConfig: Context/控制配置为空,更新失败"); + LogUtils.e(TAG, "updateServiceControlConfig: 参数为空"); return; } - - // 第一步:本地持久化配置 ControlCenterServiceBean.saveBean(context, controlBean); - LogUtils.d(TAG, "updateServiceControlConfig: 控制配置已持久化"); - - // 第二步:启停服务(修复:启用则启动,禁用则停止) if (controlBean.isEnableService()) { - stopControlCenterService(context); + stopControlCenterService(context); startControlCenterService(context); - LogUtils.d(TAG, "updateServiceControlConfig: 服务已设置启动"); } else { stopControlCenterService(context); - LogUtils.d(TAG, "updateServiceControlConfig: 服务已设置停止"); } } /** - * 新增:同步应用前台/后台状态到服务(MainActivity专用入口) - * @param context 上下文 - * @param isForeground true=前台,false=后台 + * 更新业务配置并触发线程重启 */ -// public static void syncAppForegroundState(Context context, boolean isForeground) { -// LogUtils.d(TAG, "syncAppForegroundState: 发送前台状态同步指令,状态=" + isForeground); -// if (context == null) { -// LogUtils.e(TAG, "syncAppForegroundState: Context为空,同步失败"); -// return; -// } -// if (!isServiceRunning(context, ControlCenterService.class)) { -// LogUtils.w(TAG, "syncAppForegroundState: 服务未运行,跳过同步"); -// return; -// } -// -// Intent intent = new Intent(context, ControlCenterService.class); -// intent.setAction(ACTION_SYNC_APP_FOREGROUND_STATE); -// intent.putExtra(EXTRA_APP_FOREGROUND_STATE, isForeground); -// intent.setPackage(context.getPackageName()); -// intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); -// -// try { -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { -// context.startForegroundService(intent); -// } else { -// context.startService(intent); -// } -// LogUtils.d(TAG, "syncAppForegroundState: 前台状态同步指令发送成功"); -// } catch (Exception e) { -// LogUtils.e(TAG, "syncAppForegroundState: 发送同步指令异常", e); -// } -// } + public static void updateStatus(Context context, AppConfigBean configBean) { + LogUtils.d(TAG, "updateStatus: 发送配置更新指令"); + if (context == null || configBean == null) { + LogUtils.e(TAG, "updateStatus: 参数为空"); + return; + } + Intent intent = new Intent(context, ControlCenterService.class); + intent.setAction(ACTION_RESTART_REMIND_THREAD); + intent.putExtra(EXTRA_APP_CONFIG_BEAN, (Serializable) configBean); + intent.setPackage(context.getPackageName()); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(intent); + } else { + context.startService(intent); + } + } catch (Exception e) { + LogUtils.e(TAG, "updateStatus: 发送指令异常", e); + } + } /** - * 判断服务是否运行(适配API30+ ActivityManager限制,优化判断逻辑) + * 检查并引导用户开启忽略电池优化 + */ + public static void checkIgnoreBatteryOptimization(Context context) { + LogUtils.d(TAG, "checkIgnoreBatteryOptimization: 检查电池优化状态"); + if (context == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return; + } + PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (powerManager == null) { + LogUtils.e(TAG, "checkIgnoreBatteryOptimization: PowerManager获取失败"); + return; + } + try { + boolean isIgnored = powerManager.isIgnoringBatteryOptimizations(context.getPackageName()); + if (!isIgnored) { + Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + intent.setData(Uri.parse("package:" + context.getPackageName())); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + context.startActivity(intent); + LogUtils.d(TAG, "checkIgnoreBatteryOptimization: 引导用户开启忽略电池优化"); + } + } catch (Exception e) { + LogUtils.e(TAG, "checkIgnoreBatteryOptimization: 引导异常", e); + } + } + + /** + * 判断服务是否运行(适配API30+) */ private static boolean isServiceRunning(Context context, Class serviceClass) { if (context == null || serviceClass == null) { - LogUtils.w(TAG, "isServiceRunning: Context/服务类为空,返回false"); return false; } - ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); if (am == null) { - LogUtils.e(TAG, "isServiceRunning: ActivityManager获取失败,返回false"); + LogUtils.e(TAG, "isServiceRunning: ActivityManager获取失败"); return false; } - - // API30+ 兼容:getRunningServices失效,通过进程状态判断(优化兜底逻辑) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - try { - String packageName = context.getPackageName(); - List processes = am.getRunningAppProcesses(); - if (processes != null && !processes.isEmpty()) { - for (ActivityManager.RunningAppProcessInfo process : processes) { - if (packageName.equals(process.processName)) { - // 前台服务/前台进程均视为服务运行(适配部分机型保活机制) - if (process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE - || process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { - return true; - } - } + String packageName = context.getPackageName(); + List processes = am.getRunningAppProcesses(); + if (processes != null) { + for (ActivityManager.RunningAppProcessInfo process : processes) { + if (packageName.equals(process.processName) && + (process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE || + process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)) { + return true; } } - // 兜底:检查服务是否已启动(避免进程后台时误判) - return isServiceStarted(context, serviceClass); - } catch (Exception e) { - LogUtils.e(TAG, "isServiceRunning: API30+ 判断服务状态异常", e); - return false; } + return isServiceStarted(context, serviceClass); } else { - // API30-:通过RunningServiceInfo判断 List runningServices = am.getRunningServices(100); - if (runningServices != null && !runningServices.isEmpty()) { + if (runningServices != null) { String serviceClassName = serviceClass.getName(); for (ActivityManager.RunningServiceInfo info : runningServices) { if (serviceClassName.equals(info.service.getClassName())) { @@ -717,87 +563,19 @@ public class ControlCenterService extends Service { } /** - * 新增:辅助判断服务是否已启动(API30+ 兜底,避免进程后台误判) + * 兜底判断服务是否已启动 */ private static boolean isServiceStarted(Context context, Class serviceClass) { try { - // 通过ServiceControlBean状态兜底(服务启动时会初始化配置) ControlCenterServiceBean controlBean = ControlCenterServiceBean.loadBean(context, ControlCenterServiceBean.class); return controlBean != null && controlBean.isEnableService(); } catch (Exception e) { - LogUtils.e(TAG, "isServiceStarted: 兜底判断服务状态异常", e); + LogUtils.e(TAG, "isServiceStarted: 兜底判断异常", e); return false; } } - /** - * 引导用户开启忽略电池优化(避免服务被后台杀死,适配API23+,优化机型兼容) - */ - public static void checkIgnoreBatteryOptimization(Context context) { - LogUtils.d(TAG, "checkIgnoreBatteryOptimization: 检查电池优化状态"); - if (context == null) { - LogUtils.e(TAG, "checkIgnoreBatteryOptimization: Context为空,跳过检查"); - return; - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - if (powerManager == null) { - LogUtils.e(TAG, "checkIgnoreBatteryOptimization: PowerManager获取失败,跳过检查"); - return; - } - - try { - boolean isIgnored = powerManager.isIgnoringBatteryOptimizations(context.getPackageName()); - if (!isIgnored) { - Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); - intent.setData(Uri.parse("package:" + context.getPackageName())); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - // 适配部分机型限制,添加异常捕获 - context.startActivity(intent); - LogUtils.d(TAG, "checkIgnoreBatteryOptimization: 已引导用户开启忽略电池优化"); - } else { - LogUtils.d(TAG, "checkIgnoreBatteryOptimization: 已开启忽略电池优化,无需操作"); - } - } catch (SecurityException e) { - LogUtils.e(TAG, "checkIgnoreBatteryOptimization: 机型限制,无法引导电池优化(系统权限管控)", e); - } catch (Exception e) { - LogUtils.e(TAG, "checkIgnoreBatteryOptimization: 引导优化异常(部分机型限制)", e); - } - } else { - LogUtils.d(TAG, "checkIgnoreBatteryOptimization: API<23,无需检查电池优化"); - } - } - - /** - * 更新服务配置(对外静态入口,触发线程重启,控制配置从本地读取) - */ - public static void updateStatus(Context context, AppConfigBean configBean) { - LogUtils.d(TAG, "updateStatus: 发送业务配置更新指令"); - if (context == null || configBean == null) { - LogUtils.e(TAG, "updateStatus: Context/业务配置为空,发送失败"); - return; - } - - Intent intent = new Intent(context, ControlCenterService.class); - intent.setAction(ACTION_RESTART_REMIND_THREAD); - intent.putExtra(EXTRA_APP_CONFIG_BEAN, (Serializable) configBean); - intent.setPackage(context.getPackageName()); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.startForegroundService(intent); - } else { - context.startService(intent); - } - LogUtils.d(TAG, "updateStatus: 业务配置更新指令发送成功"); - } catch (Exception e) { - LogUtils.e(TAG, "updateStatus: 发送指令异常", e); - } - } - - // ================================== Getter/Setter 方法(新增前台状态相关,线程安全)================================= + // ================================== Getter/Setter 方法(线程安全)================================= public RemindThread getRemindThread() { synchronized (mServiceLock) { return mRemindThread; @@ -805,29 +583,24 @@ public class ControlCenterService extends Service { } public void setCurrentConfigBean(AppConfigBean configBean) { - LogUtils.d(TAG, "setCurrentConfigBean: 更新服务配置"); - if (configBean != null) { - synchronized (mServiceLock) { - this.mCurrentConfigBean = configBean; - syncConfigToRemindThread(); - } - LogUtils.d(TAG, "setCurrentConfigBean: 配置更新成功"); - } else { - LogUtils.e(TAG, "setCurrentConfigBean: 配置为空,更新失败"); + LogUtils.d(TAG, "setCurrentConfigBean: 更新业务配置"); + if (configBean == null) { + LogUtils.e(TAG, "setCurrentConfigBean: 配置为空"); + return; + } + synchronized (mServiceLock) { + this.mCurrentConfigBean = configBean; + syncConfigToRemindThread(); } } - // 更新服务控制配置(内存+本地持久化同步) public void setServiceControlBean(ControlCenterServiceBean controlBean) { - LogUtils.d(TAG, "setServiceControlBean: 更新服务控制配置"); + LogUtils.d(TAG, "setServiceControlBean: 更新控制配置"); if (controlBean != null) { updateAndSaveServiceControlConfig(controlBean); - } else { - LogUtils.e(TAG, "setServiceControlBean: 控制配置为空,更新失败"); } } - // 获取服务控制配置(外部查询启用状态) public ControlCenterServiceBean getServiceControlBean() { synchronized (mServiceLock) { return mServiceControlBean; @@ -857,21 +630,5 @@ public class ControlCenterService extends Service { return mIsDestroyed; } } - - // 新增:获取应用前台状态(外部查询,线程安全) - public boolean isAppForeground() { - synchronized (mServiceLock) { - return mIsAppForeground; - } - } - - // 新增:设置应用前台状态(内部/外部调用,同步到线程) -// public void setAppForeground(boolean isForeground) { -// LogUtils.d(TAG, "setAppForeground: 更新应用前台状态=" + isForeground); -// synchronized (mServiceLock) { -// mIsAppForeground = isForeground; -// syncAppForegroundStateToThread(); -// } -// } }