From c2def0bb3bf1101a64357e949cb90d1ecbda1f36 Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Mon, 22 Dec 2025 23:19:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BA=90=E7=A0=81=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- powerbell/build.properties | 4 +- .../studio/powerbell/utils/APPPlusUtils.java | 89 ++++++--- .../studio/powerbell/utils/AppCacheUtils.java | 160 +++++++++------ .../powerbell/utils/AppConfigUtils.java | 182 ++++++++++-------- .../powerbell/utils/AssetsCopyUtils.java | 48 +++-- 5 files changed, 298 insertions(+), 185 deletions(-) diff --git a/powerbell/build.properties b/powerbell/build.properties index a689707..4b7b160 100644 --- a/powerbell/build.properties +++ b/powerbell/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Mon Dec 22 15:02:15 GMT 2025 +#Mon Dec 22 15:19:14 GMT 2025 stageCount=24 libraryProject= baseVersion=15.14 publishVersion=15.14.23 -buildCount=2 +buildCount=3 baseBetaVersion=15.14.24 diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/APPPlusUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/APPPlusUtils.java index 162c5ea..be5cc9b 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/APPPlusUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/APPPlusUtils.java @@ -1,10 +1,5 @@ package cc.winboll.studio.powerbell.utils; -/** - * @Author ZhanGSKen&豆包大模型 - * @Date 2025/11/26 15:54 - * @Describe 应用图标切换工具类(启用组件时创建对应快捷方式) - */ import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -13,58 +8,73 @@ import android.os.Build; import android.widget.Toast; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.App; -import cc.winboll.studio.powerbell.MainActivity; import cc.winboll.studio.powerbell.R; +/** + * @Author ZhanGSKen&豆包大模型 + * @Date 2025/11/26 15:54 + * @Describe 应用图标切换工具类(启用组件时创建对应快捷方式) + * 适配:Java7 | API30 | 高低版本快捷方式创建兼容 + */ public class APPPlusUtils { + // ======================== 静态常量区 ======================== public static final String TAG = "APPPlusUtils"; + // 快捷方式配置(名称+图标,需与实际资源匹配,预留扩展) + // private static final String PLUS_SHORTCUT_NAME = "位置服务-Laojun"; + // private static final int PLUS_SHORTCUT_ICON = R.mipmap.ic_launcher; // Laojun 图标资源 - // 快捷方式配置(名称+图标,需与实际资源匹配) -// private static final String PLUS_SHORTCUT_NAME = "位置服务-Laojun"; -// private static final int PLUS_SHORTCUT_ICON = R.mipmap.ic_launcher; // Laojun 图标资源 - + // ======================== 公共业务方法区 ======================== /** - * 添加Plus组件与图标 + * 切换应用启动器组件(禁用其他组件,启用目标组件) + * @param context 上下文 + * @param componentName 目标组件完整类名 + * @return 切换是否成功 */ public static boolean switchAppLauncherToComponent(Context context, String componentName) { + LogUtils.d(TAG, "switchAppLauncherToComponent() 调用,传入组件名:" + componentName); if (context == null) { - LogUtils.d(TAG, "切换失败:上下文为空"); - Toast.makeText(context, context.getString(R.string.app_name) + "图标切换失败", Toast.LENGTH_SHORT).show(); + LogUtils.e(TAG, "switchAppLauncherToComponent() 切换失败:上下文为空"); return false; } PackageManager pm = context.getPackageManager(); - - ComponentName plusComponentSwitchTo = new ComponentName(context, componentName); - ComponentName plusComponentEN1 = new ComponentName(context, App.COMPONENT_EN1); - ComponentName plusComponentCN1 = new ComponentName(context, App.COMPONENT_CN1); - ComponentName plusComponentCN2 = new ComponentName(context, App.COMPONENT_CN2); + ComponentName targetComponent = new ComponentName(context, componentName); + ComponentName en1Component = new ComponentName(context, App.COMPONENT_EN1); + ComponentName cn1Component = new ComponentName(context, App.COMPONENT_CN1); + ComponentName cn2Component = new ComponentName(context, App.COMPONENT_CN2); try { - disableComponent(pm, plusComponentEN1); - disableComponent(pm, plusComponentCN1); - disableComponent(pm, plusComponentCN2); - enableComponent(pm, plusComponentSwitchTo); + // 禁用所有其他启动器组件 + disableComponent(pm, en1Component); + disableComponent(pm, cn1Component); + disableComponent(pm, cn2Component); + // 启用目标组件 + enableComponent(pm, targetComponent); + LogUtils.d(TAG, "switchAppLauncherToComponent() 图标切换成功,目标组件:" + componentName); + Toast.makeText(context, context.getString(R.string.app_name) + "图标切换成功", Toast.LENGTH_SHORT).show(); return true; } catch (Exception e) { - LogUtils.e(TAG, "图标切换失败:" + e.getMessage()); - Toast.makeText(context, context.getString(R.string.app_name) + "图标切换失败" + e.getMessage(), Toast.LENGTH_SHORT).show(); + LogUtils.e(TAG, "switchAppLauncherToComponent() 图标切换失败:" + e.getMessage(), e); + Toast.makeText(context, context.getString(R.string.app_name) + "图标切换失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); return false; } } + // ======================== 私有辅助方法区(快捷方式创建) ======================== /** * 创建指定组件的桌面快捷方式(自动去重,兼容 Android 8.0+) - * @param component 目标组件(如 LAOJUN_ACTIVITY) + * @param context 上下文 + * @param component 目标组件 * @param name 快捷方式名称 * @param iconRes 快捷方式图标资源ID * @return 是否创建成功 */ private static boolean createComponentShortcut(Context context, ComponentName component, String name, int iconRes) { + LogUtils.d(TAG, "createComponentShortcut() 调用,组件:" + component.getClassName() + ",名称:" + name); if (context == null || component == null || name == null || iconRes == 0) { - LogUtils.d(TAG, "快捷方式创建失败:参数为空"); + LogUtils.e(TAG, "createComponentShortcut() 快捷方式创建失败:参数为空"); return false; } @@ -74,14 +84,14 @@ public class APPPlusUtils { PackageManager pm = context.getPackageManager(); android.content.pm.ShortcutManager shortcutManager = context.getSystemService(android.content.pm.ShortcutManager.class); if (shortcutManager == null || !shortcutManager.isRequestPinShortcutSupported()) { - LogUtils.d(TAG, "系统不支持创建快捷方式"); + LogUtils.w(TAG, "createComponentShortcut() 系统不支持创建快捷方式"); return false; } // 检查是否已存在该组件的快捷方式(去重) for (android.content.pm.ShortcutInfo info : shortcutManager.getPinnedShortcuts()) { if (component.getClassName().equals(info.getIntent().getComponent().getClassName())) { - LogUtils.d(TAG, "快捷方式已存在:" + component.getClassName()); + LogUtils.d(TAG, "createComponentShortcut() 快捷方式已存在:" + component.getClassName()); return true; } } @@ -102,10 +112,11 @@ public class APPPlusUtils { // 请求创建快捷方式(需用户确认) shortcutManager.requestPinShortcut(shortcutInfo, null); + LogUtils.d(TAG, "createComponentShortcut() Android O+ 快捷方式创建请求已发送"); return true; } catch (Exception e) { - LogUtils.d(TAG, "Android O+ 快捷方式创建失败:" + e.getMessage()); + LogUtils.e(TAG, "createComponentShortcut() Android O+ 快捷方式创建失败:" + e.getMessage(), e); return false; } } else { @@ -126,38 +137,52 @@ public class APPPlusUtils { installIntent.putExtra("duplicate", false); // 禁止重复创建 context.sendBroadcast(installIntent); + LogUtils.d(TAG, "createComponentShortcut() Android O- 快捷方式创建广播已发送"); return true; } catch (Exception e) { - LogUtils.d(TAG, "Android O- 快捷方式创建失败:" + e.getMessage()); + LogUtils.e(TAG, "createComponentShortcut() Android O- 快捷方式创建失败:" + e.getMessage(), e); return false; } } } + // ======================== 私有辅助方法区(组件状态控制) ======================== /** * 启用组件(带状态检查,避免重复操作) + * @param pm 包管理器 + * @param component 目标组件 */ private static void enableComponent(PackageManager pm, ComponentName component) { - if (pm.getComponentEnabledSetting(component) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { + int currentState = pm.getComponentEnabledSetting(component); + if (currentState != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { pm.setComponentEnabledSetting( component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS ); + LogUtils.d(TAG, "enableComponent() 组件已启用:" + component.getClassName()); + } else { + LogUtils.d(TAG, "enableComponent() 组件无需操作,已启用:" + component.getClassName()); } } /** * 禁用组件(带状态检查,避免重复操作) + * @param pm 包管理器 + * @param component 目标组件 */ private static void disableComponent(PackageManager pm, ComponentName component) { - if (pm.getComponentEnabledSetting(component) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { + int currentState = pm.getComponentEnabledSetting(component); + if (currentState != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { pm.setComponentEnabledSetting( component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS ); + LogUtils.d(TAG, "disableComponent() 组件已禁用:" + component.getClassName()); + } else { + LogUtils.d(TAG, "disableComponent() 组件无需操作,已禁用:" + component.getClassName()); } } } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppCacheUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppCacheUtils.java index 7749d4c..168dd38 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppCacheUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppCacheUtils.java @@ -5,81 +5,129 @@ import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.models.BatteryInfoBean; import java.util.ArrayList; +/** + * 应用缓存工具类(适配Android API 30,基于Java 7编写) + * 负责电池信息的缓存、持久化与管理 + */ public class AppCacheUtils { + // ===================== 常量定义区 ===================== public static final String TAG = "AppCacheUtils"; - // 保存唯一配置实例 - static AppCacheUtils _mAppCacheUtils; - // 配置实例引用的上下文环境 - Context mContext; - // 配置实例的数据的存储文件路径 - //volatile String mAppCacheDataFilePath = null; - ArrayList mlBatteryInfo; + // ===================== 静态属性区 ===================== + // 单例实例 + private static AppCacheUtils sInstance; - // 私有实例构造方法 - // - AppCacheUtils(Context context) { - mContext = context; - //mAppCacheDataFilePath = context.getExternalFilesDir(TAG) + File.separator + "mlBatteryInfo.dat"; - mlBatteryInfo = new ArrayList(); - loadAppCacheData(); - } + // ===================== 成员属性区 ===================== + // 上下文环境(使用ApplicationContext避免内存泄漏) + private Context mContext; + // 电池信息缓存列表 + private ArrayList mBatteryInfoList; - // 返回唯一实例 - // + // ===================== 单例方法区 ===================== + /** + * 获取单例实例 + * @param context 上下文(内部会转换为ApplicationContext) + * @return 唯一AppCacheUtils实例 + */ public static synchronized AppCacheUtils getInstance(Context context) { - if (_mAppCacheUtils == null) { - _mAppCacheUtils = new AppCacheUtils(context); + LogUtils.d(TAG, "getInstance() 调用,传入Context类型:" + (context != null ? context.getClass().getSimpleName() : "null")); + if (sInstance == null) { + sInstance = new AppCacheUtils(context.getApplicationContext()); + LogUtils.d(TAG, "getInstance():单例实例已初始化"); } - return _mAppCacheUtils; + return sInstance; } - // 添加电量改变时间 - // - public void addChangingTime(int nBattetyValue) { - if (mlBatteryInfo.size() == 0) { - addChangingTimeToList(nBattetyValue); - //LogUtils.d(TAG, "nBattetyValue is "+Integer.toString(nBattetyValue)); + // ===================== 构造方法区(私有) ===================== + /** + * 私有构造方法,禁止外部实例化 + * @param context ApplicationContext + */ + private AppCacheUtils(Context context) { + LogUtils.d(TAG, "AppCacheUtils() 构造方法调用"); + mContext = context; + mBatteryInfoList = new ArrayList(); + loadAppCacheData(); + LogUtils.d(TAG, "AppCacheUtils() 构造完成,初始电池信息数量:" + mBatteryInfoList.size()); + } + + // ===================== 公共业务方法区 ===================== + /** + * 添加电池电量变化记录(仅当电量变化时添加) + * @param batteryValue 电池电量值 + */ + public void addChangingTime(int batteryValue) { + LogUtils.d(TAG, "addChangingTime() 调用,传入电量值:" + batteryValue); + if (mBatteryInfoList.isEmpty()) { + addChangingTimeToList(batteryValue); + LogUtils.d(TAG, "addChangingTime():缓存列表为空,直接添加记录"); return; } - if (mlBatteryInfo.get(mlBatteryInfo.size() - 1).getBattetyValue() != nBattetyValue) { - addChangingTimeToList(nBattetyValue); - //LogUtils.d(TAG, "nBattetyValue is "+Integer.toString(nBattetyValue)); - + // 对比最后一条记录的电量值,避免重复添加 + int lastBatteryValue = mBatteryInfoList.get(mBatteryInfoList.size() - 1).getBattetyValue(); + if (lastBatteryValue != batteryValue) { + addChangingTimeToList(batteryValue); + LogUtils.d(TAG, "addChangingTime():电量变化,添加新记录(原电量:" + lastBatteryValue + ",新电量:" + batteryValue + ")"); + } else { + LogUtils.d(TAG, "addChangingTime():电量未变化,跳过添加"); } } - void addChangingTimeToList(int nBattetyValue) { - if (mlBatteryInfo.size() > 180) { - mlBatteryInfo.remove(0); - } - BatteryInfoBean batteryInfo = new BatteryInfoBean(System.currentTimeMillis(), nBattetyValue); - LogUtils.d(TAG, "getBattetyValue is " + Integer.toString(batteryInfo.getBattetyValue())); - LogUtils.d(TAG, "getTimeStamp is " + Long.toString(batteryInfo.getTimeStamp())); - mlBatteryInfo.add(batteryInfo); - saveAppCacheData(); - } - + /** + * 获取电池信息缓存列表 + * @return 完整的电池信息列表 + */ public ArrayList getArrayListBatteryInfo() { + LogUtils.d(TAG, "getArrayListBatteryInfo() 调用,当前缓存数量:" + mBatteryInfoList.size()); loadAppCacheData(); - return mlBatteryInfo; - } - - // 读取文件存储的数据 - // - void saveAppCacheData() { - BatteryInfoBean.saveBeanList(mContext, mlBatteryInfo, BatteryInfoBean.class); - } - - // 保存数据到文件 - // - void loadAppCacheData() { - mlBatteryInfo.clear(); - BatteryInfoBean.loadBeanList(mContext, mlBatteryInfo, BatteryInfoBean.class); + return mBatteryInfoList; } + /** + * 清除所有电池历史记录 + */ public void clearBatteryHistory() { - mlBatteryInfo.clear(); + LogUtils.d(TAG, "clearBatteryHistory() 调用,清除前缓存数量:" + mBatteryInfoList.size()); + mBatteryInfoList.clear(); saveAppCacheData(); + LogUtils.d(TAG, "clearBatteryHistory() 完成,缓存已清空"); + } + + // ===================== 私有辅助方法区 ===================== + /** + * 内部方法:添加电量记录到列表并持久化 + * @param batteryValue 电池电量值 + */ + private void addChangingTimeToList(int batteryValue) { + LogUtils.d(TAG, "addChangingTimeToList() 调用,传入电量值:" + batteryValue); + // 限制列表最大长度为180条,避免内存溢出 + if (mBatteryInfoList.size() > 180) { + mBatteryInfoList.remove(0); + LogUtils.d(TAG, "addChangingTimeToList():列表超过180条,移除最旧记录"); + } + BatteryInfoBean batteryInfo = new BatteryInfoBean(System.currentTimeMillis(), batteryValue); + mBatteryInfoList.add(batteryInfo); + LogUtils.d(TAG, "addChangingTimeToList():添加新记录 - 电量:" + batteryInfo.getBattetyValue() + ",时间戳:" + batteryInfo.getTimeStamp()); + saveAppCacheData(); + } + + /** + * 从文件加载缓存数据 + */ + private void loadAppCacheData() { + LogUtils.d(TAG, "loadAppCacheData() 调用,开始加载持久化数据"); + mBatteryInfoList.clear(); + BatteryInfoBean.loadBeanList(mContext, mBatteryInfoList, BatteryInfoBean.class); + LogUtils.d(TAG, "loadAppCacheData() 完成,加载数据数量:" + mBatteryInfoList.size()); + } + + /** + * 保存缓存数据到文件 + */ + private void saveAppCacheData() { + LogUtils.d(TAG, "saveAppCacheData() 调用,保存数据数量:" + mBatteryInfoList.size()); + BatteryInfoBean.saveBeanList(mContext, mBatteryInfoList, BatteryInfoBean.class); + LogUtils.d(TAG, "saveAppCacheData() 完成,数据已持久化"); } } + diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java index 5eba73d..f4e0e40 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java @@ -1,13 +1,10 @@ package cc.winboll.studio.powerbell.utils; -import android.app.Activity; import android.content.Context; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.App; -import cc.winboll.studio.powerbell.MainActivity; import cc.winboll.studio.powerbell.models.AppConfigBean; import cc.winboll.studio.powerbell.models.ControlCenterServiceBean; -import cc.winboll.studio.powerbell.services.ControlCenterService; /** * @Author ZhanGSKen&豆包大模型 @@ -16,7 +13,7 @@ import cc.winboll.studio.powerbell.services.ControlCenterService; * 适配:Java7 | API30 | 小米手机,单例模式,线程安全,配置持久化 */ public class AppConfigUtils { - // ======================== 静态常量(顶部统一管理,抽离魔法值)======================== + // ======================== 静态常量区(魔法值统一管理)======================== public static final String TAG = "AppConfigUtils"; public static final String BACKGROUND_DIR = "Background"; // 背景图片存储目录 private static final int MIN_REMINDER_VALUE = 0; // 提醒阈值最小值 @@ -24,90 +21,93 @@ public class AppConfigUtils { private static final int MIN_INTERVAL_TIME = 1000; // 最小提醒间隔(ms) private static final int MIN_DETECT_INTERVAL = 500; // 最小电量检测间隔(ms) - // ======================== 静态成员(单例实例,严格控制初始化)======================== + // ======================== 静态属性区(单例实例)======================== private static AppConfigUtils sInstance; // 单例实例(私有,禁止外部直接创建) - // ======================== 核心依赖属性(优先排列,final保障安全)======================== - private final Context mContext; // 应用上下文(避免内存泄漏) + // ======================== 成员属性区(按依赖优先级排序)======================== + private final Context mContext; // 应用上下文(避免内存泄漏,final保障) private App mApplication; // 应用Application实例 + public volatile AppConfigBean mAppConfigBean; // 应用配置Bean(持久化核心,volatile保障线程安全) + private volatile boolean mIsServiceEnabled = false; // 服务开关缓存状态(减少Bean读取次数) - // ======================== 配置Bean属性(持久化核心,volatile保障线程安全)======================== - public volatile AppConfigBean mAppConfigBean; // 应用配置Bean - - // ======================== 缓存状态属性(减少Bean读取次数,提升性能)======================== - private volatile boolean mIsServiceEnabled = false; // 服务开关缓存状态 - - - // ======================== 单例构造方法(私有,禁止外部实例化)======================== + // ======================== 单例相关方法区(构造+获取)======================== + /** + * 私有构造方法,禁止外部实例化 + * @param context 上下文(内部转换为ApplicationContext) + */ private AppConfigUtils(Context context) { - LogUtils.d(TAG, "初始化配置工具类"); + LogUtils.d(TAG, "AppConfigUtils() 构造方法调用"); this.mContext = context.getApplicationContext(); // 强制取应用上下文,杜绝内存泄漏 this.mApplication = (App) context.getApplicationContext(); - // 初始化配置Bean mAppConfigBean = new AppConfigBean(); - // 加载持久化配置 - loadAppConfig(); - LogUtils.d(TAG, "配置工具类初始化完成"); + loadAppConfig(); // 加载持久化配置 + LogUtils.d(TAG, "AppConfigUtils() 构造完成,配置初始化成功"); } - // ======================== 单例获取方法(双重校验锁,线程安全,适配多线程)======================== + /** + * 双重校验锁单例获取方法,线程安全 + * @param context 上下文(不可为null) + * @return 单例实例 + */ public static AppConfigUtils getInstance(Context context) { + LogUtils.d(TAG, "getInstance() 调用,传入Context类型:" + (context != null ? context.getClass().getSimpleName() : "null")); if (context == null) { - LogUtils.e(TAG, "getInstance: Context不能为空,获取实例失败"); + LogUtils.e(TAG, "getInstance() Context不能为空,获取实例失败"); throw new IllegalArgumentException("Context cannot be null"); } if (sInstance == null) { synchronized (AppConfigUtils.class) { if (sInstance == null) { sInstance = new AppConfigUtils(context); - LogUtils.d(TAG, "getInstance: 单例实例创建成功"); + LogUtils.d(TAG, "getInstance() 单例实例创建成功"); } } } + LogUtils.d(TAG, "getInstance() 单例实例获取成功"); return sInstance; } - - // ======================== 核心配置加载/保存方法(内部核心逻辑,优先排列)======================== + // ======================== 核心配置持久化方法区(加载+保存)======================== /** - * 加载所有配置(应用配置+服务配置,统一入口,初始化/重载通用) + * 加载应用配置(初始化/重载通用入口) + * @return 加载后的应用配置Bean */ public AppConfigBean loadAppConfig() { - LogUtils.d(TAG, "loadAllConfig: 开始加载所有配置"); - // 加载应用配置 + LogUtils.d(TAG, "loadAppConfig() 开始加载应用配置"); AppConfigBean savedAppBean = (AppConfigBean) AppConfigBean.loadBean(mContext, AppConfigBean.class); if (savedAppBean != null) { mAppConfigBean = savedAppBean; - LogUtils.d(TAG, "loadAllConfig: 应用配置加载成功"); + LogUtils.d(TAG, "loadAppConfig() 应用配置加载成功,阈值:充电" + mAppConfigBean.getChargeReminderValue() + "%,耗电" + mAppConfigBean.getUsageReminderValue() + "%"); } else { - mAppConfigBean = new AppConfigBean(); + mAppConfigBean = new AppConfigBean(); AppConfigBean.saveBean(mContext, mAppConfigBean); - LogUtils.d(TAG, "loadAllConfig: 无已保存应用配置,使用默认值并持久化"); + LogUtils.d(TAG, "loadAppConfig() 无已保存配置,使用默认值并持久化"); } - return mAppConfigBean; + return mAppConfigBean; } /** - * 保存应用配置(内部核心方法,直接持久化,同步通知服务+Activity) + * 保存应用配置(内部核心方法,直接持久化) */ private void saveAppConfig() { AppConfigBean.saveBean(mContext, mAppConfigBean); - LogUtils.d(TAG, "saveAppConfig: 应用配置保存成功,已同步服务和Activity"); + LogUtils.d(TAG, "saveAppConfig() 应用配置保存成功"); } - // ======================== 充电提醒配置方法(单独归类,逻辑聚焦)======================== + // ======================== 充电提醒配置方法区(开关+阈值)======================== /** - * 设置充电提醒开关状态(直接生效,无弹窗) + * 设置充电提醒开关状态 * @param isEnabled 目标状态(true=开启,false=关闭) */ public void setChargeReminderEnabled(final boolean isEnabled) { + LogUtils.d(TAG, "setChargeReminderEnabled() 调用,传入状态:" + isEnabled); if (isEnabled == mAppConfigBean.isEnableChargeReminder()) { - LogUtils.d(TAG, "setChargeReminderEnabled: 充电提醒状态无变化,无需操作"); + LogUtils.d(TAG, "setChargeReminderEnabled() 充电提醒状态无变化,无需操作"); return; } mAppConfigBean.setEnableChargeReminder(isEnabled); saveAppConfig(); - LogUtils.d(TAG, "setChargeReminderEnabled: 充电提醒状态更新为=" + (isEnabled ? "开启" : "关闭")); + LogUtils.d(TAG, "setChargeReminderEnabled() 充电提醒状态更新为:" + (isEnabled ? "开启" : "关闭")); } /** @@ -116,23 +116,24 @@ public class AppConfigUtils { */ public boolean isChargeReminderEnabled() { boolean isEnabled = mAppConfigBean.isEnableChargeReminder(); - LogUtils.d(TAG, "isChargeReminderEnabled: 获取充电提醒状态=" + (isEnabled ? "开启" : "关闭")); + LogUtils.d(TAG, "isChargeReminderEnabled() 获取充电提醒状态:" + (isEnabled ? "开启" : "关闭")); return isEnabled; } /** - * 设置充电提醒阈值(直接生效,无弹窗,自动校准范围,适配API30数据安全) - * @param value 目标阈值(自动校准0-100) + * 设置充电提醒阈值(自动校准0-100) + * @param value 目标阈值 */ public void setChargeReminderValue(final int value) { + LogUtils.d(TAG, "setChargeReminderValue() 调用,传入阈值:" + value); final int calibratedValue = Math.min(Math.max(value, MIN_REMINDER_VALUE), MAX_REMINDER_VALUE); if (calibratedValue == mAppConfigBean.getChargeReminderValue()) { - LogUtils.d(TAG, "setChargeReminderValue: 充电提醒阈值无变化,无需操作"); + LogUtils.d(TAG, "setChargeReminderValue() 充电提醒阈值无变化,无需操作"); return; } mAppConfigBean.setChargeReminderValue(calibratedValue); saveAppConfig(); - LogUtils.d(TAG, "setChargeReminderValue: 充电提醒阈值更新为=" + calibratedValue + "%"); + LogUtils.d(TAG, "setChargeReminderValue() 充电提醒阈值更新为:" + calibratedValue + "%"); } /** @@ -141,24 +142,24 @@ public class AppConfigUtils { */ public int getChargeReminderValue() { int value = mAppConfigBean.getChargeReminderValue(); - LogUtils.d(TAG, "getChargeReminderValue: 获取充电提醒阈值=" + value + "%"); + LogUtils.d(TAG, "getChargeReminderValue() 获取充电提醒阈值:" + value + "%"); return value; } - - // ======================== 耗电提醒配置方法(单独归类,逻辑聚焦)======================== + // ======================== 耗电提醒配置方法区(开关+阈值)======================== /** - * 设置耗电提醒开关状态(直接生效,无弹窗) + * 设置耗电提醒开关状态 * @param isEnabled 目标状态(true=开启,false=关闭) */ public void setUsageReminderEnabled(final boolean isEnabled) { + LogUtils.d(TAG, "setUsageReminderEnabled() 调用,传入状态:" + isEnabled); if (isEnabled == mAppConfigBean.isEnableUsageReminder()) { - LogUtils.d(TAG, "setUsageReminderEnabled: 耗电提醒状态无变化,无需操作"); + LogUtils.d(TAG, "setUsageReminderEnabled() 耗电提醒状态无变化,无需操作"); return; } mAppConfigBean.setEnableUsageReminder(isEnabled); saveAppConfig(); - LogUtils.d(TAG, "setUsageReminderEnabled: 耗电提醒状态更新为=" + (isEnabled ? "开启" : "关闭")); + LogUtils.d(TAG, "setUsageReminderEnabled() 耗电提醒状态更新为:" + (isEnabled ? "开启" : "关闭")); } /** @@ -167,23 +168,24 @@ public class AppConfigUtils { */ public boolean isUsageReminderEnabled() { boolean isEnabled = mAppConfigBean.isEnableUsageReminder(); - LogUtils.d(TAG, "isUsageReminderEnabled: 获取耗电提醒状态=" + (isEnabled ? "开启" : "关闭")); + LogUtils.d(TAG, "isUsageReminderEnabled() 获取耗电提醒状态:" + (isEnabled ? "开启" : "关闭")); return isEnabled; } /** - * 设置耗电提醒阈值(直接生效,无弹窗,自动校准范围,适配小米手机电量跳变) - * @param value 目标阈值(自动校准0-100) + * 设置耗电提醒阈值(自动校准0-100) + * @param value 目标阈值 */ public void setUsageReminderValue(final int value) { + LogUtils.d(TAG, "setUsageReminderValue() 调用,传入阈值:" + value); final int calibratedValue = Math.min(Math.max(value, MIN_REMINDER_VALUE), MAX_REMINDER_VALUE); if (calibratedValue == mAppConfigBean.getUsageReminderValue()) { - LogUtils.d(TAG, "setUsageReminderValue: 耗电提醒阈值无变化,无需操作"); + LogUtils.d(TAG, "setUsageReminderValue() 耗电提醒阈值无变化,无需操作"); return; } mAppConfigBean.setUsageReminderValue(calibratedValue); saveAppConfig(); - LogUtils.d(TAG, "setUsageReminderValue: 耗电提醒阈值更新为=" + calibratedValue + "%"); + LogUtils.d(TAG, "setUsageReminderValue() 耗电提醒阈值更新为:" + calibratedValue + "%"); } /** @@ -192,23 +194,23 @@ public class AppConfigUtils { */ public int getUsageReminderValue() { int value = mAppConfigBean.getUsageReminderValue(); - LogUtils.d(TAG, "getUsageReminderValue: 获取耗电提醒阈值=" + value + "%"); + LogUtils.d(TAG, "getUsageReminderValue() 获取耗电提醒阈值:" + value + "%"); return value; } - - // ======================== 实时电池状态配置方法(临时缓存,不持久化,无需弹窗)======================== + // ======================== 实时电池状态配置方法区(内存缓存,不持久化)======================== /** - * 设置当前充电状态(仅内存缓存,不持久化) + * 设置当前充电状态(仅内存缓存) * @param isCharging 充电状态(true=充电中,false=未充电) */ public void setCharging(boolean isCharging) { + LogUtils.d(TAG, "setCharging() 调用,传入状态:" + isCharging); if (isCharging == mAppConfigBean.isCharging()) { - LogUtils.d(TAG, "setCharging: 充电状态无变化,无需操作"); + LogUtils.d(TAG, "setCharging() 充电状态无变化,无需操作"); return; } mAppConfigBean.setIsCharging(isCharging); - LogUtils.d(TAG, "setCharging: 充电状态更新为=" + (isCharging ? "充电中" : "未充电")); + LogUtils.d(TAG, "setCharging() 充电状态更新为:" + (isCharging ? "充电中" : "未充电")); } /** @@ -217,22 +219,23 @@ public class AppConfigUtils { */ public boolean isCharging() { boolean isCharging = mAppConfigBean.isCharging(); - LogUtils.d(TAG, "isCharging: 获取充电状态=" + (isCharging ? "充电中" : "未充电")); + LogUtils.d(TAG, "isCharging() 获取充电状态:" + (isCharging ? "充电中" : "未充电")); return isCharging; } /** - * 设置当前电池电量(仅内存缓存,不持久化,自动校准范围) - * @param value 当前电量(自动校准0-100) + * 设置当前电池电量(仅内存缓存,自动校准0-100) + * @param value 当前电量 */ public void setCurrentBatteryValue(int value) { + LogUtils.d(TAG, "setCurrentBatteryValue() 调用,传入电量:" + value); int calibratedValue = Math.min(Math.max(value, MIN_REMINDER_VALUE), MAX_REMINDER_VALUE); if (calibratedValue == mAppConfigBean.getCurrentBatteryValue()) { - LogUtils.d(TAG, "setCurrentBatteryValue: 电池电量无变化,无需操作"); + LogUtils.d(TAG, "setCurrentBatteryValue() 电池电量无变化,无需操作"); return; } mAppConfigBean.setCurrentBatteryValue(calibratedValue); - LogUtils.d(TAG, "setCurrentBatteryValue: 电池电量更新为=" + calibratedValue + "%"); + LogUtils.d(TAG, "setCurrentBatteryValue() 电池电量更新为:" + calibratedValue + "%"); } /** @@ -241,25 +244,25 @@ public class AppConfigUtils { */ public int getCurrentBatteryValue() { int value = mAppConfigBean.getCurrentBatteryValue(); - LogUtils.d(TAG, "getCurrentBatteryValue: 获取电池电量=" + value + "%"); + LogUtils.d(TAG, "getCurrentBatteryValue() 获取电池电量:" + value + "%"); return value; } - - // ======================== 间隔配置方法(持久化存储,直接生效,无弹窗)======================== + // ======================== 间隔配置方法区(持久化)======================== /** - * 设置提醒间隔时间(直接生效,无弹窗,自动校准最小1000ms) + * 设置提醒间隔时间(自动校准最小1000ms) * @param interval 目标间隔(单位:ms) */ public void setReminderIntervalTime(final int interval) { + LogUtils.d(TAG, "setReminderIntervalTime() 调用,传入间隔:" + interval + "ms"); final int calibratedInterval = Math.max(interval, MIN_INTERVAL_TIME); if (calibratedInterval == mAppConfigBean.getReminderIntervalTime()) { - LogUtils.d(TAG, "setReminderIntervalTime: 提醒间隔无变化,无需操作"); + LogUtils.d(TAG, "setReminderIntervalTime() 提醒间隔无变化,无需操作"); return; } mAppConfigBean.setReminderIntervalTime(calibratedInterval); saveAppConfig(); - LogUtils.d(TAG, "setReminderIntervalTime: 提醒间隔更新为=" + calibratedInterval + "ms"); + LogUtils.d(TAG, "setReminderIntervalTime() 提醒间隔更新为:" + calibratedInterval + "ms"); } /** @@ -268,23 +271,24 @@ public class AppConfigUtils { */ public int getReminderIntervalTime() { int interval = mAppConfigBean.getReminderIntervalTime(); - LogUtils.d(TAG, "getReminderIntervalTime: 获取提醒间隔=" + interval + "ms"); + LogUtils.d(TAG, "getReminderIntervalTime() 获取提醒间隔:" + interval + "ms"); return interval; } /** - * 设置电量检测间隔(直接生效,无弹窗,自动校准最小500ms,与RemindThread同步) + * 设置电量检测间隔(自动校准最小500ms) * @param interval 目标间隔(单位:ms) */ public void setBatteryDetectInterval(final int interval) { + LogUtils.d(TAG, "setBatteryDetectInterval() 调用,传入间隔:" + interval + "ms"); final int calibratedInterval = Math.max(interval, MIN_DETECT_INTERVAL); if (calibratedInterval == mAppConfigBean.getBatteryDetectInterval()) { - LogUtils.d(TAG, "setBatteryDetectInterval: 检测间隔无变化,无需操作"); + LogUtils.d(TAG, "setBatteryDetectInterval() 检测间隔无变化,无需操作"); return; } mAppConfigBean.setBatteryDetectInterval(calibratedInterval); saveAppConfig(); - LogUtils.d(TAG, "setBatteryDetectInterval: 电量检测间隔更新为=" + calibratedInterval + "ms"); + LogUtils.d(TAG, "setBatteryDetectInterval() 电量检测间隔更新为:" + calibratedInterval + "ms"); } /** @@ -293,23 +297,37 @@ public class AppConfigUtils { */ public int getBatteryDetectInterval() { int interval = mAppConfigBean.getBatteryDetectInterval(); - LogUtils.d(TAG, "getBatteryDetectInterval: 获取电量检测间隔=" + interval + "ms"); + LogUtils.d(TAG, "getBatteryDetectInterval() 获取电量检测间隔:" + interval + "ms"); return interval; } - public boolean isServiceEnabled() { - // 加载服务配置 + // ======================== 服务开关配置方法区(独立Bean)======================== + /** + * 获取服务开关状态 + * @return 服务开关状态(true=开启,false=关闭) + */ + public boolean isServiceEnabled() { + LogUtils.d(TAG, "isServiceEnabled() 开始获取服务开关状态"); ControlCenterServiceBean savedServiceBean = (ControlCenterServiceBean) ControlCenterServiceBean.loadBean(mContext, ControlCenterServiceBean.class); if (savedServiceBean != null) { - return savedServiceBean.isEnableService(); + boolean isEnabled = savedServiceBean.isEnableService(); + LogUtils.d(TAG, "isServiceEnabled() 服务开关状态:" + isEnabled); + return isEnabled; } else { ControlCenterServiceBean.saveBean(mContext, new ControlCenterServiceBean(false)); + LogUtils.d(TAG, "isServiceEnabled() 无已保存服务配置,默认关闭并持久化"); return false; } - } + } - public void setIsServiceEnabled(boolean isServiceEnabled) { + /** + * 设置服务开关状态 + * @param isServiceEnabled 目标状态(true=开启,false=关闭) + */ + public void setIsServiceEnabled(boolean isServiceEnabled) { + LogUtils.d(TAG, "setIsServiceEnabled() 调用,传入状态:" + isServiceEnabled); ControlCenterServiceBean.saveBean(mContext, new ControlCenterServiceBean(isServiceEnabled)); - } + LogUtils.d(TAG, "setIsServiceEnabled() 服务开关状态更新为:" + isServiceEnabled); + } } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AssetsCopyUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AssetsCopyUtils.java index b275dd4..bc479e4 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AssetsCopyUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AssetsCopyUtils.java @@ -1,23 +1,26 @@ package cc.winboll.studio.powerbell.utils; import android.content.Context; -import android.util.Log; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import cc.winboll.studio.libappbase.LogUtils; /** * @Author ZhanGSKen&豆包大模型 * @Date 2025/12/11 09:14 * @Describe Assets 目录拷贝工具类 * 支持将 assets/images/ 下所有文件、子目录拷贝到指定路径 + * 适配:Java7 | API30 | 递归拷贝 | 覆盖写入 */ public class AssetsCopyUtils { + // ======================== 静态常量区 ======================== public static final String TAG = "AssetsCopyUtils"; - private static final int BUFFER_SIZE = 1024 * 8; + private static final int BUFFER_SIZE = 1024 * 8; // 8KB 缓冲区,平衡性能与内存占用 + // ======================== 公共快捷方法区(对外入口) ======================== /** * 拷贝 assets/images/ 目录到指定目标目录 * @param context 上下文 @@ -25,10 +28,14 @@ public class AssetsCopyUtils { * @return 拷贝是否成功 */ public static boolean copyAssetsImagesToDir(Context context, String targetDirPath) { + LogUtils.d(TAG, "copyAssetsImagesToDir() 调用,目标路径:" + targetDirPath); // 拷贝 assets/images 根目录 - return copyAssetsDirToDir(context, "images", targetDirPath); + boolean result = copyAssetsDirToDir(context, "images", targetDirPath); + LogUtils.d(TAG, "copyAssetsImagesToDir() 执行完成,结果:" + result); + return result; } + // ======================== 公共核心方法区(递归拷贝目录) ======================== /** * 递归拷贝 assets 下指定目录到目标目录 * @param context 上下文 @@ -37,10 +44,16 @@ public class AssetsCopyUtils { * @return 拷贝是否成功 */ public static boolean copyAssetsDirToDir(Context context, String assetsDir, String targetDirPath) { + LogUtils.d(TAG, "copyAssetsDirToDir() 调用,源目录:" + assetsDir + ",目标路径:" + targetDirPath); + if (context == null) { + LogUtils.e(TAG, "copyAssetsDirToDir() 拷贝失败:上下文为空"); + return false; + } + File targetDir = new File(targetDirPath); // 创建目标目录(含多级父目录) if (!targetDir.exists() && !targetDir.mkdirs()) { - Log.e(TAG, "创建目标目录失败:" + targetDirPath); + LogUtils.e(TAG, "copyAssetsDirToDir() 创建目标目录失败:" + targetDirPath); return false; } @@ -48,7 +61,7 @@ public class AssetsCopyUtils { // 获取 assets 目录下的文件/子目录列表 String[] fileList = context.getAssets().list(assetsDir); if (fileList == null || fileList.length == 0) { - Log.d(TAG, "assets 目录为空:" + assetsDir); + LogUtils.d(TAG, "copyAssetsDirToDir() assets 目录为空:" + assetsDir); return true; } @@ -61,23 +74,26 @@ public class AssetsCopyUtils { if (subFileList != null && subFileList.length > 0) { // 是子目录,递归拷贝 if (!copyAssetsDirToDir(context, assetsFilePath, targetFilePath)) { + LogUtils.e(TAG, "copyAssetsDirToDir() 递归拷贝子目录失败:" + assetsFilePath); return false; } } else { // 是文件,直接拷贝 if (!copyAssetsFileToDir(context, assetsFilePath, targetFilePath)) { + LogUtils.e(TAG, "copyAssetsDirToDir() 拷贝文件失败:" + assetsFilePath); return false; } } } - Log.d(TAG, "assets 目录拷贝完成:" + assetsDir + " -> " + targetDirPath); + LogUtils.d(TAG, "copyAssetsDirToDir() assets 目录拷贝完成:" + assetsDir + " -> " + targetDirPath); return true; } catch (IOException e) { - Log.e(TAG, "拷贝 assets 目录异常:" + e.getMessage()); + LogUtils.e(TAG, "copyAssetsDirToDir() 拷贝 assets 目录异常:" + e.getMessage(), e); return false; } } + // ======================== 私有辅助方法区(单个文件拷贝) ======================== /** * 拷贝 assets 下单个文件到指定路径 * @param context 上下文 @@ -86,14 +102,16 @@ public class AssetsCopyUtils { * @return 拷贝是否成功 */ public static boolean copyAssetsFileToDir(Context context, String assetsFilePath, String targetFilePath) { + LogUtils.d(TAG, "copyAssetsFileToDir() 调用,源文件:" + assetsFilePath + ",目标文件:" + targetFilePath); InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = context.getAssets().open(assetsFilePath); File targetFile = new File(targetFilePath); + // 覆盖已存在的文件 if (targetFile.exists() && !targetFile.delete()) { - Log.w(TAG, "覆盖目标文件失败,跳过:" + targetFilePath); + LogUtils.w(TAG, "copyAssetsFileToDir() 覆盖目标文件失败,跳过:" + targetFilePath); return true; } @@ -103,18 +121,22 @@ public class AssetsCopyUtils { while ((length = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, length); } - Log.d(TAG, "文件拷贝成功:" + assetsFilePath + " -> " + targetFilePath); + LogUtils.d(TAG, "copyAssetsFileToDir() 文件拷贝成功:" + assetsFilePath + " -> " + targetFilePath); return true; } catch (IOException e) { - Log.e(TAG, "拷贝文件失败:" + assetsFilePath + ",异常:" + e.getMessage()); + LogUtils.e(TAG, "copyAssetsFileToDir() 拷贝文件失败:" + assetsFilePath + ",异常:" + e.getMessage(), e); return false; } finally { // 关闭流 try { - if (inputStream != null) inputStream.close(); - if (outputStream != null) outputStream.close(); + if (inputStream != null) { + inputStream.close(); + } + if (outputStream != null) { + outputStream.close(); + } } catch (IOException e) { - Log.e(TAG, "关闭流异常:" + e.getMessage()); + LogUtils.e(TAG, "copyAssetsFileToDir() 关闭流异常:" + e.getMessage(), e); } } }