源码整理
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
package cc.winboll.studio.powerbell.utils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @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&豆包大模型<zhangsken@qq.com>
|
||||
* @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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<BatteryInfoBean> mlBatteryInfo;
|
||||
// ===================== 静态属性区 =====================
|
||||
// 单例实例
|
||||
private static AppCacheUtils sInstance;
|
||||
|
||||
// 私有实例构造方法
|
||||
//
|
||||
AppCacheUtils(Context context) {
|
||||
mContext = context;
|
||||
//mAppCacheDataFilePath = context.getExternalFilesDir(TAG) + File.separator + "mlBatteryInfo.dat";
|
||||
mlBatteryInfo = new ArrayList<BatteryInfoBean>();
|
||||
loadAppCacheData();
|
||||
}
|
||||
// ===================== 成员属性区 =====================
|
||||
// 上下文环境(使用ApplicationContext避免内存泄漏)
|
||||
private Context mContext;
|
||||
// 电池信息缓存列表
|
||||
private ArrayList<BatteryInfoBean> 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<BatteryInfoBean>();
|
||||
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<BatteryInfoBean> 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() 完成,数据已持久化");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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&豆包大模型<zhangsken@qq.com>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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&豆包大模型<zhangsken@qq.com>
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user