From cf857c1359b99e387bafa6a74360a7a2a2390cd3 Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Wed, 4 Feb 2026 11:04:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E5=8F=AB=E8=B1=86=E5=8C=85?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=AF=8F=E5=A4=A910=E5=8D=8A=E5=B7=A6?= =?UTF-8?q?=E5=8F=B3=E4=BC=9A=E6=97=A0=E7=AB=AF=E7=AB=AF=E8=B0=83=E7=94=A8?= =?UTF-8?q?TTS=E6=9C=8D=E5=8A=A1=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- powerbell/build.properties | 4 +- .../ControlCenterServiceReceiver.java | 190 +++++------ .../powerbell/services/ThoughtfulService.java | 296 ++++++++++-------- 3 files changed, 242 insertions(+), 248 deletions(-) diff --git a/powerbell/build.properties b/powerbell/build.properties index 4efa800..1414aa2 100644 --- a/powerbell/build.properties +++ b/powerbell/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Sat Jan 24 20:41:05 HKT 2026 +#Wed Feb 04 02:57:22 GMT 2026 stageCount=8 libraryProject= baseVersion=15.15 publishVersion=15.15.7 -buildCount=0 +buildCount=1 baseBetaVersion=15.15.8 diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/receivers/ControlCenterServiceReceiver.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/receivers/ControlCenterServiceReceiver.java index 468d317..4fa10d8 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/receivers/ControlCenterServiceReceiver.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/receivers/ControlCenterServiceReceiver.java @@ -24,56 +24,55 @@ import cc.winboll.studio.powerbell.services.ThoughtfulService; * @Describe 统一处理系统与应用内广播,同步电池状态与配置,保障多线程数据一致性 */ public class ControlCenterServiceReceiver extends BroadcastReceiver { - // ====================== 静态常量区(置顶归类,消除魔法值) ====================== + // ====================== 静态常量区 ====================== public static final String TAG = "ControlCenterServiceReceiver"; - // 广播Action常量(带包名前缀防冲突) public static final String ACTION_UPDATE_FOREGROUND_NOTIFICATION = "cc.winboll.studio.powerbell.action.ACTION_UPDATE_FOREGROUND_NOTIFICATION"; public static final String ACTION_APPCONFIG_CHANGED = "cc.winboll.studio.powerbell.action.ACTION_APPCONFIG_CHANGED"; public static final String EXTRA_APP_CONFIG_BEAN = "extra_app_config_bean"; - // 广播优先级与电量范围常量 private static final int BROADCAST_PRIORITY = IntentFilter.SYSTEM_HIGH_PRIORITY - 10; private static final int BATTERY_LEVEL_MIN = 0; private static final int BATTERY_LEVEL_MAX = 100; - private static final int INVALID_BATTERY = -1; // 无效电量标识 + private static final int INVALID_BATTERY = -1; - // ====================== 静态状态标记(volatile保证多线程可见性) ====================== - private static volatile int sLastBatteryLevel = INVALID_BATTERY; // 上次电量(多线程可见) - private static volatile boolean sIsCharging = false; // 上次充电状态(多线程可见) + // ====================== 静态状态(防抖动 + 防重复播报) ====================== + private static volatile int sLastBatteryLevel = INVALID_BATTERY; + private static volatile boolean sIsCharging = false; - // ====================== 成员变量区(弱引用防泄漏,按功能分层) ====================== + // 【新增】防重复触发:3秒内只允许一次播报(关键修复) + private static final long MIN_TRIGGER_INTERVAL = 3000; + private static long sLastTriggerTime = 0; + + // ====================== 成员变量 ====================== private WeakReference mwrControlCenterService; - private boolean isRegistered = false; // 标记广播注册状态,避免冗余操作 + private boolean isRegistered = false; - // ====================== 构造方法(初始化弱引用,避免服务强引用泄漏) ====================== + // ====================== 构造 ====================== public ControlCenterServiceReceiver(ControlCenterService service) { - LogUtils.d(TAG, String.format("ControlCenterServiceReceiver() 构造 | 服务实例:%s", + LogUtils.d(TAG, String.format("ControlCenterServiceReceiver() 构造 | 服务:%s", service != null ? service.getClass().getSimpleName() : "null")); - this.mwrControlCenterService = new WeakReference(service); + this.mwrControlCenterService = new WeakReference<>(service); } - // ====================== 广播核心接收逻辑(入口方法,分Action分发处理) ====================== + // ====================== 广播入口 ====================== @Override public void onReceive(Context context, Intent intent) { String action = intent != null ? intent.getAction() : "null"; - LogUtils.d(TAG, String.format("onReceive() 执行 | 接收广播 Action:%s", action)); + LogUtils.d(TAG, String.format("onReceive() | Action=%s", action)); - // 基础参数校验 if (context == null || intent == null || action == null) { - LogUtils.e(TAG, "onReceive() 终止 | 参数无效(context=" + context + " | intent=" + intent + ")"); + LogUtils.e(TAG, "onReceive() 终止:参数无效"); return; } - // 弱引用获取服务,双重校验服务有效性 ControlCenterService service = mwrControlCenterService != null ? mwrControlCenterService.get() : null; if (service == null || service.isDestroyed()) { - LogUtils.e(TAG, "onReceive() 终止 | 服务已销毁或为空,执行注销"); + LogUtils.e(TAG, "onReceive() 终止:服务已销毁"); unregisterAction(context); return; } - // 分Action处理业务逻辑 switch (action) { case Intent.ACTION_BATTERY_CHANGED: handleBatteryStateChanged(service, intent); @@ -82,192 +81,145 @@ public class ControlCenterServiceReceiver extends BroadcastReceiver { handleUpdateForegroundNotification(service); break; case ACTION_APPCONFIG_CHANGED: - LogUtils.d(TAG, "onReceive() 分发 | 处理配置更新广播"); handleNotifyAppConfigUpdate(service); break; default: - LogUtils.w(TAG, String.format("onReceive() 警告 | 未知Action=%s", action)); + LogUtils.w(TAG, "未知Action:" + action); } - - LogUtils.d(TAG, "onReceive() 完成 | 广播处理结束"); } - // ====================== 业务处理方法(按功能拆分,强化容错与日志) ====================== - /** - * 处理电池状态变化广播 - * @param service 控制中心服务实例 - * @param intent 电池状态广播意图 - */ + // ====================== 电池状态(核心修复区) ====================== private void handleBatteryStateChanged(ControlCenterService service, Intent intent) { - LogUtils.d(TAG, "handleBatteryStateChanged() 执行 | 解析电池状态"); + LogUtils.d(TAG, "handleBatteryStateChanged() 解析电池状态"); try { - // 1. 解析并校验当前电池状态 boolean currentCharging = BatteryUtils.isCharging(intent); int currentBatteryLevel = BatteryUtils.getCurrentBatteryLevel(intent); currentBatteryLevel = Math.min(Math.max(currentBatteryLevel, BATTERY_LEVEL_MIN), BATTERY_LEVEL_MAX); - LogUtils.d(TAG, String.format("handleBatteryStateChanged() 解析 | 充电=%b | 电量=%d%%", currentCharging, currentBatteryLevel)); - // 2. 状态无变化则跳过,减少无效运算 + LogUtils.d(TAG, String.format("当前:充电=%b | 电量=%d%%", currentCharging, currentBatteryLevel)); + + // ================ 【关键修复1】状态没变直接跳过 ================ if (currentCharging == sIsCharging && currentBatteryLevel == sLastBatteryLevel) { - LogUtils.d(TAG, "handleBatteryStateChanged() 跳过 | 电池状态无变化"); + LogUtils.d(TAG, "状态无变化,跳过"); return; } - - // 在插拔充电线时,执行贴心服务 - if(currentCharging != sIsCharging && sLastBatteryLevel != INVALID_BATTERY) { - //App.notifyMessage(TAG, String.format("sLastBatteryLevel %d", sLastBatteryLevel)); - if(currentCharging) { - ThoughtfulService.startServiceWithType(service, ThoughtfulService.ServiceType.CHARGE_STATE); - } else { - ThoughtfulService.startServiceWithType(service, ThoughtfulService.ServiceType.DISCHARGE_STATE); - } - } - // 3. 更新静态缓存状态,保证多线程可见 + // ================ 【关键修复2】只有 真正插拔充电 才播报 ================ + boolean isRealPlugSwitch = (currentCharging != sIsCharging); + boolean isBatteryValid = (sLastBatteryLevel != INVALID_BATTERY); + + // ================ 【关键修复3】防抖动:3秒内不重复触发 ================ + long now = System.currentTimeMillis(); + boolean canTrigger = (now - sLastTriggerTime >= MIN_TRIGGER_INTERVAL); + + if (isRealPlugSwitch && isBatteryValid && canTrigger) { + LogUtils.d(TAG, "检测到充电状态切换 → 执行TTS提醒"); + + // 更新触发时间 + sLastTriggerTime = now; + + // 执行播报 + if (currentCharging) { + ThoughtfulService.startServiceWithType(service, ThoughtfulService.ServiceType.CHARGE_STATE); + } else { + ThoughtfulService.startServiceWithType(service, ThoughtfulService.ServiceType.DISCHARGE_STATE); + } + } + + // 更新缓存 sIsCharging = currentCharging; sLastBatteryLevel = currentBatteryLevel; - // 4. 同步缓存状态到配置 + // 同步配置 handleNotifyAppConfigUpdate(service); - LogUtils.d(TAG, String.format("handleBatteryStateChanged() 完成 | 缓存电量=%d%% | 缓存充电状态=%b", - sLastBatteryLevel, sIsCharging)); } catch (Exception e) { - LogUtils.e(TAG, "handleBatteryStateChanged() 失败", e); + LogUtils.e(TAG, "handleBatteryStateChanged 异常", e); } } - /** - * 处理配置变更通知,同步缓存状态到配置 - * @param service 控制中心服务实例 - */ + // ====================== 配置同步 ====================== private void handleNotifyAppConfigUpdate(ControlCenterService service) { - LogUtils.d(TAG, "handleNotifyAppConfigUpdate() 执行 | 同步缓存状态到配置"); + LogUtils.d(TAG, "handleNotifyAppConfigUpdate() 同步配置"); try { - // 加载最新配置 AppConfigBean latestConfig = AppConfigUtils.getInstance(service).loadAppConfig(); if (latestConfig == null) { - LogUtils.e(TAG, "handleNotifyAppConfigUpdate() 终止 | 最新配置为空"); + LogUtils.e(TAG, "配置为空,终止"); return; } - LogUtils.d(TAG, String.format("handleNotifyAppConfigUpdate() 加载 | 充电阈值=%d | 耗电阈值=%d", - latestConfig.getChargeReminderValue(), latestConfig.getUsageReminderValue())); - // 同步缓存的电池状态到配置 App.sQuantityOfElectricity = sLastBatteryLevel; latestConfig.setIsCharging(sIsCharging); service.notifyAppConfigUpdate(latestConfig); - LogUtils.d(TAG, String.format("handleNotifyAppConfigUpdate() 完成 | 缓存电量=%d%% | 充电状态=%b", - sLastBatteryLevel, sIsCharging)); } catch (Exception e) { - LogUtils.e(TAG, "handleNotifyAppConfigUpdate() 失败", e); + LogUtils.e(TAG, "handleNotifyAppConfigUpdate 异常", e); } } - /** - * 处理前台服务通知更新 - * @param service 控制中心服务实例 - */ + // ====================== 通知更新 ====================== private void handleUpdateForegroundNotification(ControlCenterService service) { - LogUtils.d(TAG, "handleUpdateForegroundNotification() 执行 | 更新前台通知"); + LogUtils.d(TAG, "handleUpdateForegroundNotification() 更新通知"); try { NotificationManagerUtils notifyUtils = service.getNotificationManager(); NotificationMessage notifyMsg = service.getForegroundNotifyMsg(); - // 非空校验,避免空指针 if (notifyUtils == null || notifyMsg == null) { - LogUtils.e(TAG, String.format("handleUpdateForegroundNotification() 终止 | 通知工具类或消息为空(notifyUtils=%s | notifyMsg=%s)", - notifyUtils, notifyMsg)); + LogUtils.e(TAG, "通知工具或消息为空"); return; } - notifyUtils.updateForegroundServiceNotify(notifyMsg); - LogUtils.d(TAG, String.format("handleUpdateForegroundNotification() 完成 | 标题=%s", notifyMsg.getTitle())); } catch (Exception e) { - LogUtils.e(TAG, "handleUpdateForegroundNotification() 失败", e); + LogUtils.e(TAG, "更新通知异常", e); } } - // ====================== 广播注册/注销(强化容错,避免重复操作) ====================== - /** - * 注册广播接收器 - * @param context 上下文 - */ + // ====================== 注册/注销 ====================== public void registerAction(Context context) { - LogUtils.d(TAG, "registerAction() 执行 | 注册广播接收器"); - if (context == null || isRegistered) { - LogUtils.e(TAG, "registerAction() 失败 | 上下文为空或已注册"); - return; - } - + if (context == null || isRegistered) return; try { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(ACTION_UPDATE_FOREGROUND_NOTIFICATION); filter.addAction(ACTION_APPCONFIG_CHANGED); filter.setPriority(BROADCAST_PRIORITY); - context.registerReceiver(this, filter); isRegistered = true; - LogUtils.d(TAG, String.format("registerAction() 完成 | 优先级=%d", BROADCAST_PRIORITY)); + LogUtils.d(TAG, "广播注册完成"); } catch (Exception e) { - LogUtils.e(TAG, "registerAction() 失败", e); + LogUtils.e(TAG, "注册异常", e); } } - /** - * 注销广播接收器 - * @param context 上下文 - */ public void unregisterAction(Context context) { - LogUtils.d(TAG, "unregisterAction() 执行 | 注销广播接收器"); - if (context == null || !isRegistered) { - LogUtils.e(TAG, "unregisterAction() 失败 | 上下文为空或未注册"); - return; - } - + if (context == null || !isRegistered) return; try { context.unregisterReceiver(this); isRegistered = false; - LogUtils.d(TAG, "unregisterAction() 完成 | 广播注销成功"); - } catch (IllegalArgumentException e) { - LogUtils.w(TAG, "unregisterAction() 警告 | 广播未注册,跳过注销"); + LogUtils.d(TAG, "广播已注销"); } catch (Exception e) { - LogUtils.e(TAG, "unregisterAction() 失败", e); + LogUtils.w(TAG, "注销异常", e); } } - // ====================== 资源释放与Getter方法(按需开放,防泄漏) ====================== - /** - * 主动释放资源,避免内存泄漏 - */ + // ====================== 释放 ====================== public void release() { - LogUtils.d(TAG, "release() 执行 | 释放广播接收器资源"); - // 清空弱引用,帮助GC回收 + LogUtils.d(TAG, "release() 释放资源"); if (mwrControlCenterService != null) { mwrControlCenterService.clear(); mwrControlCenterService = null; - LogUtils.d(TAG, "release() 步骤 | 弱引用已清空"); } - // 重置静态状态缓存 - sLastBatteryLevel = -1; + // 重置静态状态 + sLastBatteryLevel = INVALID_BATTERY; sIsCharging = false; - LogUtils.d(TAG, "release() 完成 | 静态状态缓存已重置"); + sLastTriggerTime = 0; // 【新增】重置防抖时间 } - /** - * 获取上次记录的电池电量 - * @return 电量值(0-100),未初始化返回-1 - */ + // ====================== Getter ====================== public static int getLastBatteryLevel() { return sLastBatteryLevel; } - /** - * 获取上次记录的充电状态 - * @return true=充电中,false=未充电 - */ public static boolean isLastCharging() { return sIsCharging; } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ThoughtfulService.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ThoughtfulService.java index f05d61f..4a3343d 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ThoughtfulService.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ThoughtfulService.java @@ -19,161 +19,203 @@ import cc.winboll.studio.powerbell.utils.AppConfigUtils; */ public class ThoughtfulService extends Service { - // ====================================== 常量区 - 置顶排序 ====================================== + // ====================================== 常量区 ====================================== public static final String TAG = "ThoughtfulService"; - /** Intent传递 服务类型 的Key值 */ public static final String EXTRA_SERVICE_TYPE = "EXTRA_SERVICE_TYPE"; - // ====================================== 枚举类 - 服务类型 充电/放电状态 ====================================== - /** - * 服务执行类型枚举 - * CHARGE_STATE : 充电状态服务 - * DISCHARGE_STATE : 放电(耗电)状态服务 - */ + // 防止重复播报的标志(静态,全局唯一) + private static boolean sIsPlaying = false; + + // ====================================== 枚举 ====================================== public enum ServiceType { - CHARGE_STATE, //充电状态服务 - DISCHARGE_STATE, //放电状态服务 + CHARGE_STATE, + DISCHARGE_STATE } - // ====================================== 对外公开静态启动函数【新增核心】入参Context + 枚举 ====================================== - /** - * 公开静态方法:传入上下文+服务类型枚举,一键构建意图并启动当前服务 - * @param context 上下文对象 - * @param serviceType 服务类型枚举【充电/放电】 - */ + // ====================================== 外部启动入口(加固) ====================================== public static void startServiceWithType(Context context, ServiceType serviceType) { - LogUtils.d(TAG, "【startServiceWithType】静态启动方法调用 | Context=" + context + " | ServiceType=" + (serviceType == null ? "null" : serviceType.name())); - - ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(context, ThoughtfulServiceBean.class); - if (thoughtfulServiceBean == null) { - thoughtfulServiceBean = new ThoughtfulServiceBean(); - } - - // 对应TTS服务提醒没有启用,就退出 - if((serviceType == ServiceType.CHARGE_STATE && !thoughtfulServiceBean.isEnableChargeTts()) - ||(serviceType == ServiceType.DISCHARGE_STATE && !thoughtfulServiceBean.isEnableUsePowerTts())){ - return; - } - - - // 判空健壮性校验 - if (context != null && serviceType != null) { - // 构建意图 + 封装枚举参数 - Intent intent = new Intent(context, ThoughtfulService.class); - intent.putExtra(EXTRA_SERVICE_TYPE, serviceType); - // 启动服务 - context.startService(intent); - LogUtils.d(TAG, "【startServiceWithType】服务启动成功,执行[" + serviceType.name() + "]任务"); - } else { - LogUtils.d(TAG, "【startServiceWithType】上下文为空 或 服务类型枚举为空,跳过启动服务"); + LogUtils.d(TAG, "【startServiceWithType】调用 | type=" + (serviceType == null ? "null" : serviceType.name())); + + if (context == null || serviceType == null) { + LogUtils.d(TAG, "【startServiceWithType】空参数,直接返回"); + return; } + + // 1. 预先读取配置,不满足直接不启动服务(最关键拦截) + ThoughtfulServiceBean ttsBean = ThoughtfulServiceBean.loadBean(context, ThoughtfulServiceBean.class); + if (ttsBean == null) { + ttsBean = new ThoughtfulServiceBean(); + } + + // 充电TTS未开 → 不启动 + if (serviceType == ServiceType.CHARGE_STATE && !ttsBean.isEnableChargeTts()) { + LogUtils.d(TAG, "【startServiceWithType】充电TTS未启用,不启动服务"); + return; + } + + // 用电TTS未开 → 不启动 + if (serviceType == ServiceType.DISCHARGE_STATE && !ttsBean.isEnableUsePowerTts()) { + LogUtils.d(TAG, "【startServiceWithType】用电TTS未启用,不启动服务"); + return; + } + + // 2. 防止重复启动导致叠加播报 + if (sIsPlaying) { + LogUtils.d(TAG, "【startServiceWithType】已有播报任务,跳过本次启动"); + return; + } + + // 3. 真正启动 + Intent intent = new Intent(context, ThoughtfulService.class); + intent.putExtra(EXTRA_SERVICE_TYPE, serviceType); + context.startService(intent); + LogUtils.d(TAG, "【startServiceWithType】服务启动成功"); } - // ====================================== 生命周期方法 - 绑定服务 (原逻辑保留) ====================================== + // ====================================== 生命周期 ====================================== @Override public IBinder onBind(Intent intent) { - LogUtils.d(TAG, "【onBind】服务绑定方法调用,入参Intent:" + intent); return null; } - // ====================================== 生命周期方法 - 启动服务【核心逻辑】接收枚举+分支执行任务 ====================================== @Override public int onStartCommand(Intent intent, int flags, int startId) { - LogUtils.d(TAG, "【onStartCommand】服务启动方法调用 | intent=" + intent + " | flags=" + flags + " | startId=" + startId); - // 判断意图非空,解析服务类型参数 - if (intent != null) { - LogUtils.d(TAG, "【onStartCommand】Intent不为空,开始解析服务类型枚举参数"); - // 获取传递的服务类型枚举 - ServiceType serviceType = (ServiceType) intent.getSerializableExtra(EXTRA_SERVICE_TYPE); - // 根据服务类型,执行对应任务 - if (serviceType != null) { - LogUtils.d(TAG, "【onStartCommand】解析到服务类型:" + serviceType.name()); - switch (serviceType) { - case CHARGE_STATE: - // 执行【充电状态】对应的业务任务 - executeChargeStateTask(); - break; - case DISCHARGE_STATE: - // 执行【放电状态】对应的业务任务 - executeDischargeStateTask(); - break; - default: - LogUtils.d(TAG, "【onStartCommand】未知的服务类型,不执行任何任务"); - break; - } - } else { - LogUtils.d(TAG, "【onStartCommand】未解析到有效服务类型参数,参数为空"); - } - } else { - LogUtils.d(TAG, "【onStartCommand】启动服务的Intent为空,直接返回"); + LogUtils.d(TAG, "【onStartCommand】进入"); + + if (intent == null) { + LogUtils.d(TAG, "【onStartCommand】intent = null,停止"); + stopSelf(); + return START_NOT_STICKY; } - // 返回默认策略,与原生逻辑一致 - int result = super.onStartCommand(intent, flags, startId); - LogUtils.d(TAG, "【onStartCommand】服务执行完成,返回值:" + result); - return result; + // 再次防止重复播报(双重保险) + if (sIsPlaying) { + LogUtils.d(TAG, "【onStartCommand】已有播报,直接停止服务"); + stopSelf(); + return START_NOT_STICKY; + } + + // 解析类型 + ServiceType type = (ServiceType) intent.getSerializableExtra(EXTRA_SERVICE_TYPE); + if (type == null) { + LogUtils.d(TAG, "【onStartCommand】type = null,停止"); + stopSelf(); + return START_NOT_STICKY; + } + + // 二次校验开关(防止外部绕过 startServiceWithType 直接启动) + ThoughtfulServiceBean ttsBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); + if (ttsBean == null) ttsBean = new ThoughtfulServiceBean(); + + boolean allowPlay = false; + if (type == ServiceType.CHARGE_STATE && ttsBean.isEnableChargeTts()) { + allowPlay = true; + } + if (type == ServiceType.DISCHARGE_STATE && ttsBean.isEnableUsePowerTts()) { + allowPlay = true; + } + + if (!allowPlay) { + LogUtils.d(TAG, "【onStartCommand】TTS开关已关闭,不执行播报"); + stopSelf(); + return START_NOT_STICKY; + } + + // 执行任务 + if (type == ServiceType.CHARGE_STATE) { + executeChargeStateTask(); + } else if (type == ServiceType.DISCHARGE_STATE) { + executeDischargeStateTask(); + } + + return START_NOT_STICKY; // 重要:执行完自动销毁,不保留服务 } - // ====================================== 私有业务方法 充电/放电 分任务执行 ====================================== - /** - * 执行【充电状态】的业务任务 - * 可在此方法内编写 充电时的逻辑(语音提醒/电量监控/弹窗等) - */ + // ====================================== 充电任务 ====================================== private void executeChargeStateTask() { - LogUtils.d(TAG, "【executeChargeStateTask】执行【充电状态】业务任务 >>> "); - //ToastUtils.show("【executeChargeStateTask】执行【充电状态】业务任务 >>> "); - // TODO 此处添加充电状态需要执行的业务逻辑代码 - // 加载最新配置 - AppConfigBean latestConfig = AppConfigUtils.getInstance(this).loadAppConfig(); - if (latestConfig == null) { - LogUtils.e(TAG, "handleNotifyAppConfigUpdate() 终止 | 最新配置为空"); - return; - } - - ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); - if (thoughtfulServiceBean == null) { - thoughtfulServiceBean = new ThoughtfulServiceBean(); - } - - if (latestConfig.isEnableChargeReminder()) { - int nChargeReminderValue = latestConfig.getChargeReminderValue(); - String szCurrentBattery = thoughtfulServiceBean.isEnableChargeTtsWithBattary()? String.format("现在电量为百分之%d。", App.sQuantityOfElectricity) : ""; - String szRemind = String.format("限量充电提醒已启用,限量值为百分之%d。", nChargeReminderValue); - szRemind = szCurrentBattery + szRemind + szRemind + szRemind; - TTSPlayService.startPlayTTS(this, szRemind); - } + LogUtils.d(TAG, "【executeChargeStateTask】执行充电任务"); + + sIsPlaying = true; // 锁定播报 + + try { + AppConfigBean config = AppConfigUtils.getInstance(this).loadAppConfig(); + if (config == null) { + LogUtils.e(TAG, "配置为空,停止"); + return; + } + + ThoughtfulServiceBean ttsBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); + if (ttsBean == null) ttsBean = new ThoughtfulServiceBean(); + + // 主提醒开关未开 → 直接不播 + if (!config.isEnableChargeReminder()) { + LogUtils.d(TAG, "充电提醒总开关关闭,不播报"); + return; + } + + int limit = config.getChargeReminderValue(); + int battery = App.sQuantityOfElectricity; + + // 电量无效值 → 不拼接电量 + String batteryStr = ""; + if (battery >= 0 && battery <= 100 && ttsBean.isEnableChargeTtsWithBattary()) { + batteryStr = String.format("当前电量百分之%d。", battery); + } + + String text = batteryStr + String.format("限量充电提醒已启用,限值百分之%d。", limit); + TTSPlayService.startPlayTTS(this, text); + LogUtils.d(TAG, "充电TTS已下发:" + text); + + } finally { + sIsPlaying = false; // 释放锁 + stopSelf(); + } } - /** - * 执行【放电(耗电)状态】的业务任务 - * 可在此方法内编写 放电时的逻辑(语音提醒/电量监控/弹窗等) - */ + // ====================================== 放电任务 ====================================== private void executeDischargeStateTask() { - LogUtils.d(TAG, "【executeDischargeStateTask】执行【放电状态】业务任务 >>> "); - //ToastUtils.show("【executeDischargeStateTask】执行【放电状态】业务任务 >>> "); - // TODO 此处添加放电状态需要执行的业务逻辑代码 - // 加载最新配置 - AppConfigBean latestConfig = AppConfigUtils.getInstance(this).loadAppConfig(); - if (latestConfig == null) { - LogUtils.e(TAG, "handleNotifyAppConfigUpdate() 终止 | 最新配置为空"); - return; - } - - ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); - if (thoughtfulServiceBean == null) { - thoughtfulServiceBean = new ThoughtfulServiceBean(); - } + LogUtils.d(TAG, "【executeDischargeStateTask】执行放电任务"); - if (latestConfig.isEnableUsageReminder()) { - int nUsageReminderValue = latestConfig.getUsageReminderValue(); - String szCurrentBattery = thoughtfulServiceBean.isEnableUseageTtsWithBattary()? String.format("现在电量为百分之%d。", App.sQuantityOfElectricity) : ""; - String szRemind = szCurrentBattery + String.format("电量不足提醒已启用,低电值为百分之%d。", nUsageReminderValue); + sIsPlaying = true; - //szRemind = szRemind + szRemind + szRemind; - TTSPlayService.startPlayTTS(this, szRemind); - } + try { + AppConfigBean config = AppConfigUtils.getInstance(this).loadAppConfig(); + if (config == null) { + LogUtils.e(TAG, "配置为空,停止"); + return; + } + + ThoughtfulServiceBean ttsBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); + if (ttsBean == null) ttsBean = new ThoughtfulServiceBean(); + + // 主提醒开关未开 → 不播 + if (!config.isEnableUsageReminder()) { + LogUtils.d(TAG, "低电提醒总开关关闭,不播报"); + return; + } + + int limit = config.getUsageReminderValue(); + int battery = App.sQuantityOfElectricity; + + String batteryStr = ""; + if (battery >= 0 && battery <= 100 && ttsBean.isEnableUseageTtsWithBattary()) { + batteryStr = String.format("当前电量百分之%d。", battery); + } + + String text = batteryStr + String.format("低电量提醒已启用,限值百分之%d。", limit); + TTSPlayService.startPlayTTS(this, text); + LogUtils.d(TAG, "放电TTS已下发:" + text); + + } finally { + sIsPlaying = false; + stopSelf(); + } } - + @Override + public void onDestroy() { + super.onDestroy(); + LogUtils.d(TAG, "【onDestroy】服务已销毁"); + } }