Compare commits

...

8 Commits

10 changed files with 971 additions and 778 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sun Dec 21 09:22:26 HKT 2025 #Sun Dec 21 17:57:40 HKT 2025
stageCount=14 stageCount=17
libraryProject= libraryProject=
baseVersion=15.14 baseVersion=15.14
publishVersion=15.14.13 publishVersion=15.14.16
buildCount=0 buildCount=0
baseBetaVersion=15.14.14 baseBetaVersion=15.14.17

View File

@@ -4,54 +4,73 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="cc.winboll.studio.powerbell"> package="cc.winboll.studio.powerbell">
<!-- ====================== 原有权限保留 + 补充核心权限 ====================== --> <!-- 运行前台服务 -->
<!-- 运行前台服务(原有保留,补充 Android 12+ 特殊前台服务权限) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<!-- 开机启动(原有保留,确保自启广播生效) --> <!-- 运行“specialUse”类型的前台服务 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
<!-- 开机启动 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- 显示通知(原有保留,前台服务/保活必备) --> <!-- 显示通知 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<!-- 应用使用统计相关(原有保留,忽略保护权限警告) --> <!-- PACKAGE_USAGE_STATS -->
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
<!-- BATTERY_STATS -->
<uses-permission android:name="android.permission.BATTERY_STATS"/> <uses-permission android:name="android.permission.BATTERY_STATS"/>
<!-- 计算应用存储空间 -->
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
<!-- 读取您共享存储空间中的内容 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 修改或删除您共享存储空间中的内容 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- MANAGE_EXTERNAL_STORAGE -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<!-- 请求忽略电池优化 -->
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<!-- 拍摄照片和视频 -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission <uses-permission
android:name="android.permission.ACCESS_PACKAGE_USAGE_STATS" android:name="android.permission.ACCESS_PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/> tools:ignore="ProtectedPermissions"/>
<!-- 相机相关(原有保留,补充权限等级声明,避免安装警告) -->
<uses-feature <uses-feature
android:name="android.hardware.camera" android:name="android.hardware.camera"
android:required="false"/> <!-- 非核心功能设为非必须,兼容无相机设备 --> android:required="false"/>
<uses-feature <uses-feature
android:name="android.hardware.camera.autofocus" android:name="android.hardware.camera.autofocus"
android:required="false"/> android:required="false"/>
<uses-permission android:name="android.permission.CAMERA" /> <!-- 补充相机权限原有仅声明feature无权限 -->
<!-- 应用信息相关(原有保留) --> <uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/> <uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
<uses-permission <uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES" android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission"/> tools:ignore="QueryAllPackagesPermission"/>
<!-- 新增:文件管理权限(对应 PermissionUtils 全文件管理逻辑) --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <!-- API30+ 全文件权限 -->
<!-- 新增:忽略电池优化权限(对应 PermissionUtils 电池优化逻辑,必须声明) --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<!-- 新增API30+ 跳转系统权限页兼容(避免自启/文件权限跳转失败) -->
<queries> <queries>
<!-- 全文件管理权限跳转兼容 -->
<!-- 小米自启权限跳转兼容(精准匹配安全中心包名) --> <package android:name="com.miui.securitycenter"/>
<package android:name="com.miui.securitycenter" />
<!-- 电池优化权限跳转兼容 -->
</queries> </queries>
@@ -68,17 +87,17 @@
android:supportsRtl="true" android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute"> tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
<!-- ====================== 页面配置(原有保留,优化 exported 安全) ====================== -->
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:exported="true" android:exported="true"
android:launchMode="singleTask"> android:launchMode="singleTask">
</activity> </activity>
<activity <activity
android:name=".activities.CrashActivity" android:name=".activities.CrashActivity"
android:exported="false"/> <!-- 新增:非外部调用,设为 false提升安全 --> android:exported="false"/>
<activity-alias <activity-alias
android:name=".MainActivityEN1" android:name=".MainActivityEN1"
@@ -87,13 +106,19 @@
android:label="@string/app_name" android:label="@string/app_name"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:enabled="true"> android:enabled="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.app.shortcuts" android:name="android.app.shortcuts"
android:resource="@xml/shortcutsmainen1"/> android:resource="@xml/shortcutsmainen1"/>
</activity-alias> </activity-alias>
<activity-alias <activity-alias
@@ -103,13 +128,19 @@
android:label="@string/app_name_cn1" android:label="@string/app_name_cn1"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:enabled="false"> android:enabled="false">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.app.shortcuts" android:name="android.app.shortcuts"
android:resource="@xml/shortcutsmaincn1"/> android:resource="@xml/shortcutsmaincn1"/>
</activity-alias> </activity-alias>
<activity-alias <activity-alias
@@ -119,53 +150,71 @@
android:label="@string/app_name_cn2" android:label="@string/app_name_cn2"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:enabled="false"> android:enabled="false">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.app.shortcuts" android:name="android.app.shortcuts"
android:resource="@xml/shortcutsmaincn2"/> android:resource="@xml/shortcutsmaincn2"/>
</activity-alias> </activity-alias>
<activity <activity
android:name=".activities.ClearRecordActivity" android:name=".activities.ClearRecordActivity"
android:parentActivityName="cc.winboll.studio.powerbell.MainActivity" android:parentActivityName="cc.winboll.studio.powerbell.MainActivity"
android:launchMode="singleTask" android:launchMode="singleTask"
android:exported="false"/> <!-- 新增:非外部调用,设为 false --> android:exported="false"/>
<activity <activity
android:name=".activities.BackgroundSettingsActivity" android:name=".activities.BackgroundSettingsActivity"
android:parentActivityName="cc.winboll.studio.powerbell.MainActivity" android:parentActivityName="cc.winboll.studio.powerbell.MainActivity"
android:exported="true" android:exported="true"
android:launchMode="singleTask"> android:launchMode="singleTask">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.SEND"/> <action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/jpeg"/> <data android:mimeType="image/jpeg"/>
<data android:mimeType="image/jpg"/> <data android:mimeType="image/jpg"/>
<data android:mimeType="image/png"/> <data android:mimeType="image/png"/>
<data android:mimeType="image/webp"/> <data android:mimeType="image/webp"/>
<data android:mimeType="image/*"/> <data android:mimeType="image/*"/>
</intent-filter> </intent-filter>
</activity> </activity>
<!-- ====================== 广播接收器(优化自启广播,提升保活成功率) ====================== -->
<receiver <receiver
android:name=".receivers.MainReceiver" android:name=".receivers.MainReceiver"
android:enabled="true" android:enabled="true"
android:exported="true" android:exported="true"
android:directBootAware="true"> android:directBootAware="true">
<intent-filter android:priority="1000"> <!-- 新增:广播优先级最高,确保优先接收开机广播 -->
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.BOOT_COMPLETED"/>
<!-- 补充:充电/解锁广播,增强后台唤醒机会 -->
<action android:name="android.intent.action.POWER_CONNECTED"/> <action android:name="android.intent.action.POWER_CONNECTED"/>
<action android:name="android.intent.action.USER_PRESENT"/> <action android:name="android.intent.action.USER_PRESENT"/>
</intent-filter> </intent-filter>
</receiver> </receiver>
<!-- ====================== 服务配置(核心优化:前台服务保活,适配 API29-30 ====================== -->
<!-- 核心前台服务ControlCenterService保活核心重点优化 -->
<service <service
android:name=".services.ControlCenterService" android:name=".services.ControlCenterService"
android:priority="1000" android:priority="1000"
@@ -173,67 +222,72 @@
android:exported="false" android:exported="false"
android:process=".controlcenterservice" android:process=".controlcenterservice"
android:foregroundServiceType="dataSync"> android:foregroundServiceType="dataSync">
<!-- 新增Android 12+ 前台服务用途声明(系统强制,否则拦截服务启动) -->
<property <property
android:name="android.app.PROPERTY_SPECIAL_USE_FOREGROUND_SERVICE" android:name="android.app.PROPERTY_SPECIAL_USE_FOREGROUND_SERVICE"
android:value="后台核心功能运行、持续保活" /> <!-- 按实际用途填写,不可空 --> android:value="后台核心功能运行、持续保活"/>
</service> </service>
<!-- 辅助服务AssistantService按需优化增强稳定性 -->
<service <service
android:name=".services.AssistantService" android:name=".services.AssistantService"
android:enabled="true" android:enabled="true"
android:exported="false" android:exported="false"
android:process=".assistantservice"> <!-- 若需前台启动,添加此配置;纯后台可移除 --> android:process=".assistantservice">
<property <property
android:name="android.app.PROPERTY_SPECIAL_USE_FOREGROUND_SERVICE" android:name="android.app.PROPERTY_SPECIAL_USE_FOREGROUND_SERVICE"
android:value="辅助核心功能运行" /> android:value="辅助核心功能运行"/>
</service> </service>
<!-- ====================== 其他配置(原有保留,补充优化) ====================== -->
<meta-data <meta-data
android:name="android.max_aspect" android:name="android.max_aspect"
android:value="4.0"/> android:value="4.0"/>
<!-- 所有非外部调用的 Activity统一设 exported=false提升安全 -->
<activity <activity
android:name=".activities.BatteryReporterActivity" android:name=".activities.BatteryReporterActivity"
android:exported="false"/> android:exported="false"/>
<activity <activity
android:name=".activities.PixelPickerActivity" android:name=".activities.PixelPickerActivity"
android:exported="false"/> android:exported="false"/>
<activity <activity
android:name=".activities.BatteryReportActivity" android:name=".activities.BatteryReportActivity"
android:exported="false"/> android:exported="false"/>
<activity <activity
android:name=".unittest.MainUnitTestActivity" android:name=".unittest.MainUnitTestActivity"
android:exported="false"/> android:exported="false"/>
<activity <activity
android:name=".activities.ShortcutActionActivity" android:name=".activities.ShortcutActionActivity"
android:exported="false"/> android:exported="false"/>
<activity <activity
android:name=".activities.SettingsActivity" android:name=".activities.SettingsActivity"
android:exported="false"/> android:exported="false"/>
<!-- 文件提供者(原有保留,正常使用) -->
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider" android:authorities="${applicationId}.fileprovider"
android:exported="false" android:exported="false"
android:grantUriPermissions="true"> android:grantUriPermissions="true">
<meta-data <meta-data
android:name="android.support.FILE_PROVIDER_PATHS" android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider"/> android:resource="@xml/file_provider"/>
</provider> </provider>
<!-- UCrop 第三方页面原有保留exported=true 正常) -->
<activity <activity
android:name="com.yalantis.ucrop.UCropActivity" android:name="com.yalantis.ucrop.UCropActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:exported="true"> android:exported="true">
</activity> </activity>
</application> </application>
</manifest> </manifest>

View File

@@ -9,220 +9,330 @@ import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
import cc.winboll.studio.libappbase.GlobalApplication; import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.ToastUtils; import cc.winboll.studio.libappbase.ToastUtils;
import cc.winboll.studio.powerbell.models.BackgroundBean;
import cc.winboll.studio.powerbell.models.NotificationMessage; import cc.winboll.studio.powerbell.models.NotificationMessage;
import cc.winboll.studio.powerbell.receivers.GlobalApplicationReceiver; import cc.winboll.studio.powerbell.receivers.GlobalApplicationReceiver;
import cc.winboll.studio.powerbell.utils.AppCacheUtils; import cc.winboll.studio.powerbell.utils.AppCacheUtils;
import cc.winboll.studio.powerbell.utils.AppConfigUtils; import cc.winboll.studio.powerbell.utils.AppConfigUtils;
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
import cc.winboll.studio.powerbell.utils.BitmapCacheUtils; import cc.winboll.studio.powerbell.utils.BitmapCacheUtils;
import cc.winboll.studio.powerbell.utils.NotificationManagerUtils; import cc.winboll.studio.powerbell.utils.NotificationManagerUtils;
import java.io.File; import java.io.File;
import java.util.concurrent.TimeUnit;
/**
* 应用全局入口类适配Android API 30基于Java 7编写
*/
public class App extends GlobalApplication { public class App extends GlobalApplication {
// ===================== 常量定义区 =====================
public static final String TAG = "App"; public static final String TAG = "App";
// 组件跳转常量
public static final String COMPONENT_EN1 = "cc.winboll.studio.powerbell.MainActivityEN1"; public static final String COMPONENT_EN1 = "cc.winboll.studio.powerbell.MainActivityEN1";
public static final String COMPONENT_CN1 = "cc.winboll.studio.powerbell.MainActivityCN1"; public static final String COMPONENT_CN1 = "cc.winboll.studio.powerbell.MainActivityCN1";
public static final String COMPONENT_CN2 = "cc.winboll.studio.powerbell.MainActivityCN2"; public static final String COMPONENT_CN2 = "cc.winboll.studio.powerbell.MainActivityCN2";
// 动作跳转常量
public static final String ACTION_SWITCHTO_EN1 = "cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_EN1"; public static final String ACTION_SWITCHTO_EN1 = "cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_EN1";
public static final String ACTION_SWITCHTO_CN1 = "cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_CN1"; public static final String ACTION_SWITCHTO_CN1 = "cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_CN1";
public static final String ACTION_SWITCHTO_CN2 = "cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_CN2"; public static final String ACTION_SWITCHTO_CN2 = "cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_CN2";
// 内存紧张通知常量 // 内存紧张通知文案常量
private static final String TRIM_MEMORY_NOTIFY_TITLE = "应用使用时内存紧张提醒"; private static final String TRIM_MEMORY_NOTIFY_TITLE = "应用使用时内存紧张提醒";
private static final String TRIM_MEMORY_NOTIFY_CONTENT = "由于本应用使用时,系统通知内存紧张程度级别较高,图片缓存功能暂时不启用。"; private static final String TRIM_MEMORY_NOTIFY_CONTENT = "由于本应用使用时,系统通知内存紧张程度级别较高,图片缓存功能暂时不启用。";
// 数据配置存储工具 // 定时任务间隔常量(分钟)
static AppConfigUtils _mAppConfigUtils; private static final long TIMER_INTERVAL_MINUTES = 1;
static AppCacheUtils _mAppCacheUtils;
// 全局 Bitmap 缓存工具(常驻内存)
public static BitmapCacheUtils _mBitmapCacheUtils;
GlobalApplicationReceiver mReceiver; // ===================== 静态属性区 =====================
static String szTempDir = ""; // 数据配置工具
// 通知工具类实例(用于发送内存紧张通知) private static AppConfigUtils sAppConfigUtils;
private static AppCacheUtils sAppCacheUtils;
// 全局Bitmap缓存工具
public static BitmapCacheUtils sBitmapCacheUtils;
// 临时文件夹路径
private static String sTempDirPath = "";
// 定时任务静态属性(全局唯一)
private static Handler sTimerHandler;
private static Runnable sTimerRunnable;
private static boolean sIsTimerRunning = false;
// ===================== 成员属性区 =====================
// 全局广播接收器
private GlobalApplicationReceiver mGlobalReceiver;
// 通知管理工具
private NotificationManagerUtils mNotificationManager; private NotificationManagerUtils mNotificationManager;
// ===================== 公共方法区 =====================
/**
* 获取临时文件夹路径
*/
public static String getTempDirPath() { public static String getTempDirPath() {
return szTempDir; return sTempDirPath;
} }
/**
* 获取应用配置工具实例
*/
public static AppConfigUtils getAppConfigUtils(Context context) {
LogUtils.d(TAG, "getAppConfigUtils() 调用传入Context" + context.getClass().getSimpleName());
if (sAppConfigUtils == null) {
sAppConfigUtils = AppConfigUtils.getInstance(context);
LogUtils.d(TAG, "getAppConfigUtils()AppConfigUtils实例已初始化");
}
return sAppConfigUtils;
}
/**
* 获取应用缓存工具实例
*/
public static AppCacheUtils getAppCacheUtils(Context context) {
LogUtils.d(TAG, "getAppCacheUtils() 调用传入Context" + context.getClass().getSimpleName());
if (sAppCacheUtils == null) {
sAppCacheUtils = AppCacheUtils.getInstance(context);
LogUtils.d(TAG, "getAppCacheUtils()AppCacheUtils实例已初始化");
}
return sAppCacheUtils;
}
/**
* 清除电池历史数据
*/
public void clearBatteryHistory() {
LogUtils.d(TAG, "clearBatteryHistory() 调用");
sAppCacheUtils.clearBatteryHistory();
}
// ===================== 生命周期方法区 =====================
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
LogUtils.d(TAG, "onCreate() 应用启动,开始初始化");
// 初始化调试模式
setIsDebugging(BuildConfig.DEBUG); setIsDebugging(BuildConfig.DEBUG);
LogUtils.d(TAG, "onCreate() 调试模式:" + BuildConfig.DEBUG);
// 初始化活动窗口管理 // 初始化基础工具
WinBoLLActivityManager.init(this); initBaseTools();
// 初始化 Toast 框架 // 初始化临时文件夹
ToastUtils.init(this); initTempDir();
// 初始化工具类实例
initUtils();
// 初始化广播接收器
initReceiver();
// 启动定时任务
initTimerTask();
// 临时文件夹初始化(保持原有逻辑) LogUtils.d(TAG, "onCreate() 应用初始化完成");
File picturesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File powerBellDir = new File(picturesDir, "PowerBell");
if (!powerBellDir.exists()) {
powerBellDir.mkdirs();
}
szTempDir = powerBellDir.getAbsolutePath();
// 设置数据配置存储工具
_mAppConfigUtils = getAppConfigUtils(this);
_mAppCacheUtils = getAppCacheUtils(this);
// 初始化全局 Bitmap 缓存工具
_mBitmapCacheUtils = BitmapCacheUtils.getInstance();
// 初始化通知工具类(使用整理后的 NotificationManagerUtils
mNotificationManager = new NotificationManagerUtils(this);
LogUtils.d(TAG, "onCreate: 通知工具类初始化完成");
mReceiver = new GlobalApplicationReceiver(this);
mReceiver.registerAction();
// 异步预加载背景图(保持原有逻辑)
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
new Thread(new Runnable() {
@Override
public void run() {
try {
BackgroundSourceUtils bgSourceUtils = BackgroundSourceUtils.getInstance(App.this);
if (bgSourceUtils == null) {
LogUtils.e(TAG, "preloadBitmap: BackgroundSourceUtils 实例为空");
return;
}
BackgroundBean bgBean = bgSourceUtils.getCurrentBackgroundBean();
if (bgBean == null || !bgBean.isUseBackgroundFile()) {
LogUtils.d(TAG, "preloadBitmap: 无有效背景文件,跳过预加载");
return;
}
String bgPath = bgBean.isUseBackgroundScaledCompressFile()
? bgBean.getBackgroundScaledCompressFilePath()
: bgBean.getBackgroundFilePath();
if (_mBitmapCacheUtils != null) {
_mBitmapCacheUtils.cacheBitmap(bgPath);
LogUtils.d(TAG, "preloadBitmap: 应用启动时预加载成功 - " + bgPath);
} else {
LogUtils.e(TAG, "preloadBitmap: 全局 BitmapCacheUtils 未初始化");
}
} catch (Exception e) {
LogUtils.e(TAG, "preloadBitmap: 预加载失败 - " + e.getMessage());
}
}
}).start();
}
}, 1000);
}
// 保持原有方法不变
public static AppConfigUtils getAppConfigUtils(Context context) {
if (_mAppConfigUtils == null) {
_mAppConfigUtils = AppConfigUtils.getInstance(context);
}
return _mAppConfigUtils;
}
public static AppCacheUtils getAppCacheUtils(Context context) {
if (_mAppCacheUtils == null) {
_mAppCacheUtils = AppCacheUtils.getInstance(context);
}
return _mAppCacheUtils;
}
public void clearBatteryHistory() {
_mAppCacheUtils.clearBatteryHistory();
} }
@Override @Override
public void onTerminate() { public void onTerminate() {
super.onTerminate(); super.onTerminate();
LogUtils.d(TAG, "onTerminate() 应用终止,开始释放资源");
// 释放Toast工具
ToastUtils.release(); ToastUtils.release();
// 释放通知工具类资源,避免内存泄漏 // 释放通知工具
releaseNotificationManager();
// 停止定时任务
stopTimerTask();
LogUtils.d(TAG, "onTerminate() 应用资源释放完成");
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
LogUtils.d(TAG, "onTrimMemory() 调用内存等级level" + level);
// 初始化通知工具(若未初始化)
if (mNotificationManager == null) {
mNotificationManager = new NotificationManagerUtils(this);
LogUtils.d(TAG, "onTrimMemory()NotificationManagerUtils实例已初始化");
}
// 内存紧张等级判断
if (level > ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
sendTrimMemoryNotification(level);
} else {
sBitmapCacheUtils = BitmapCacheUtils.getInstance();
LogUtils.d(TAG, "onTrimMemory()Bitmap缓存已启用");
}
}
// ===================== 私有初始化方法区 =====================
/**
* 初始化基础工具Activity管理、Toast
*/
private void initBaseTools() {
LogUtils.d(TAG, "initBaseTools() 开始初始化基础工具");
WinBoLLActivityManager.init(this);
ToastUtils.init(this);
LogUtils.d(TAG, "initBaseTools() 基础工具初始化完成");
}
/**
* 初始化临时文件夹适配API 30外部存储访问
*/
private void initTempDir() {
LogUtils.d(TAG, "initTempDir() 开始初始化临时文件夹");
File picturesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File powerBellDir = new File(picturesDir, "PowerBell");
if (!powerBellDir.exists()) {
boolean isMkSuccess = powerBellDir.mkdirs();
LogUtils.d(TAG, "initTempDir() 文件夹创建结果:" + isMkSuccess);
}
sTempDirPath = powerBellDir.getAbsolutePath();
LogUtils.d(TAG, "initTempDir() 临时文件夹路径:" + sTempDirPath);
}
/**
* 初始化工具类实例
*/
private void initUtils() {
LogUtils.d(TAG, "initUtils() 开始初始化工具类");
sAppConfigUtils = getAppConfigUtils(this);
sAppCacheUtils = getAppCacheUtils(this);
sBitmapCacheUtils = BitmapCacheUtils.getInstance();
mNotificationManager = new NotificationManagerUtils(this);
LogUtils.d(TAG, "initUtils() 工具类初始化完成");
}
/**
* 初始化广播接收器
*/
private void initReceiver() {
LogUtils.d(TAG, "initReceiver() 开始初始化广播接收器");
mGlobalReceiver = new GlobalApplicationReceiver(this);
mGlobalReceiver.registerAction();
LogUtils.d(TAG, "initReceiver() 广播接收器注册完成");
}
/**
* 初始化定时任务(全局唯一实例)
*/
private void initTimerTask() {
LogUtils.d(TAG, "initTimerTask() 开始初始化定时任务,当前运行状态:" + sIsTimerRunning);
// 已运行则直接返回
if (sIsTimerRunning) {
LogUtils.d(TAG, "initTimerTask() 定时任务已在运行,无需重复启动");
return;
}
// 初始化Handler
if (sTimerHandler == null) {
sTimerHandler = new Handler(Looper.getMainLooper());
LogUtils.d(TAG, "initTimerTask() 定时任务Handler已初始化");
}
// 初始化Runnable
if (sTimerRunnable == null) {
sTimerRunnable = new Runnable() {
@Override
public void run() {
try {
LogUtils.d(TAG, "定时任务执行,间隔:" + TIMER_INTERVAL_MINUTES + "分钟");
sBitmapCacheUtils = BitmapCacheUtils.getInstance();
LogUtils.d(TAG, "定时任务Bitmap缓存已重新初始化");
} catch (Exception e) {
LogUtils.e(TAG, "定时任务执行异常:" + e.getMessage());
} finally {
if (sIsTimerRunning) {
long delayMillis = TimeUnit.MINUTES.toMillis(TIMER_INTERVAL_MINUTES);
sTimerHandler.postDelayed(this, delayMillis);
LogUtils.d(TAG, "定时任务已预约下次执行,延迟:" + delayMillis + "ms");
}
}
}
};
LogUtils.d(TAG, "initTimerTask() 定时任务Runnable已初始化");
}
// 启动任务
sTimerHandler.post(sTimerRunnable);
sIsTimerRunning = true;
LogUtils.d(TAG, "initTimerTask() 定时任务已启动,间隔:" + TIMER_INTERVAL_MINUTES + "分钟");
}
// ===================== 私有工具方法区 =====================
/**
* 停止定时任务
*/
private void stopTimerTask() {
LogUtils.d(TAG, "stopTimerTask() 开始停止定时任务");
if (sTimerHandler != null && sTimerRunnable != null) {
sTimerHandler.removeCallbacks(sTimerRunnable);
sIsTimerRunning = false;
LogUtils.d(TAG, "stopTimerTask() 定时任务已停止运行状态重置为false");
} else {
LogUtils.d(TAG, "stopTimerTask() 定时任务未初始化,无需停止");
}
}
/**
* 释放通知管理工具资源
*/
private void releaseNotificationManager() {
LogUtils.d(TAG, "releaseNotificationManager() 开始释放通知工具");
if (mNotificationManager != null) { if (mNotificationManager != null) {
mNotificationManager.release(); mNotificationManager.release();
mNotificationManager = null; mNotificationManager = null;
LogUtils.d(TAG, "onTerminate: 通知工具资源已释放"); LogUtils.d(TAG, "releaseNotificationManager() 通知工具资源已释放");
} else {
LogUtils.d(TAG, "releaseNotificationManager() 通知工具未初始化,无需释放");
} }
} }
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
LogUtils.d(TAG, "onTrimMemory: 内存等级变化 | level=" + getTrimMemoryLevelDesc(level));
// 仅在中等及以上内存紧张等级发送通知,避免频繁打扰
if (mNotificationManager == null) {
mNotificationManager = new NotificationManagerUtils(this);
}
if (level > ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
sendTrimMemoryNotification(level);
} else {
// 再次缓存 Bitmap 缓存工具
_mBitmapCacheUtils = BitmapCacheUtils.getInstance();
LogUtils.d(TAG, "Bitmap 缓存启用中。");
}
}
/** /**
* 发送内存紧张通知(完全复用 NotificationManagerUtils 的 showRemindNotification 方法) * 发送内存紧张通知
*/ */
private void sendTrimMemoryNotification(int level) { private void sendTrimMemoryNotification(int level) {
LogUtils.d(TAG, "sendTrimMemoryNotification: 准备发送内存紧张通知"); LogUtils.d(TAG, "sendTrimMemoryNotification() 调用内存等级level" + level);
// 构建通知消息体
NotificationMessage message = new NotificationMessage(); NotificationMessage message = new NotificationMessage();
message.setTitle(TRIM_MEMORY_NOTIFY_TITLE); message.setTitle(TRIM_MEMORY_NOTIFY_TITLE);
message.setContent(String.format("%s [ 缓存紧张级别描述: Level %d | %s ]",TRIM_MEMORY_NOTIFY_CONTENT, level, getTrimMemoryLevelDesc(level))); String content = String.format("%s [ 缓存紧张级别描述: Level %d | %s ]",
// 使用整理后的 NotificationManagerUtils 发送通知(复用提醒渠道配置) TRIM_MEMORY_NOTIFY_CONTENT, level, getTrimMemoryLevelDesc(level));
message.setContent(content);
mNotificationManager.showConfigNotification(this, message); mNotificationManager.showConfigNotification(this, message);
LogUtils.d(TAG, "sendTrimMemoryNotification: 通知已通过 NotificationManagerUtils 发送"); LogUtils.d(TAG, "sendTrimMemoryNotification() 内存紧张通知已发送,内容:" + content);
} }
/** /**
* 转换内存等级为可读描述,便于日志调试 * 转换内存等级为可读描述
* 排序规则:按 ComponentCallbacks2 枚举数值从高到低排列(数值越高,内存越紧张) */
*/ private String getTrimMemoryLevelDesc(int level) {
/** LogUtils.d(TAG, "getTrimMemoryLevelDesc() 调用传入level" + level);
* 转换内存等级为可读描述,便于日志调试 String desc;
* 排序规则:按 ComponentCallbacks2 枚举实际数值10进制从高到低排列 switch (level) {
* 数值来源:接口中定义的 16进制注释10进制数值 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
*/ desc = "TRIM_MEMORY_COMPLETE应用内存完全紧张";
private String getTrimMemoryLevelDesc(int level) { break;
switch (level) { case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
// 数值 800x50应用内存完全紧张补充接口中实际存在的枚举项 desc = "MODERATE中等内存紧张";
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: break;
return "TRIM_MEMORY_COMPLETE应用内存完全紧张"; case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
// 数值 600x3c中等内存紧张 desc = "BACKGROUND应用进入后台";
case ComponentCallbacks2.TRIM_MEMORY_MODERATE: break;
return "MODERATE中等内存紧张"; case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
// 数值 400x28应用进入后台 desc = "BACKGROUND应用UI隐藏";
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND: break;
return "BACKGROUND应用进入后台"; case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
// 数值 200x14应用UI隐藏 desc = "RUNNING_CRITICAL应用运行关键级紧张";
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN: break;
return "BACKGROUND应用UI隐藏"; case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
// 数值 150xf应用运行时关键级紧张 desc = "RUNNING_LOW应用运行低内存";
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL: break;
return "RUNNING_CRITICAL应用运行关键级紧张"; case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
// 数值 100xa应用运行时低内存 desc = "RUNNING_MODERATE应用运行中等内存紧张";
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW: break;
return "RUNNING_LOW应用运行低内存"; default:
// 数值 50x5应用运行时中等紧张 desc = "UNKNOWN(" + level + ")";
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE: break;
return "RUNNING_MODERATE应用运行中等内存紧张"; }
LogUtils.d(TAG, "getTrimMemoryLevelDesc() 内存等级描述结果:" + desc);
// 以下为注释备用项(接口中未提供,按你的原有注释保留) return desc;
// 数值 100内存极度紧张系统可能强制杀死应用 }
// case ComponentCallbacks2.TRIM_MEMORY_URGENT:
// return "URGENT内存极度紧张";
// 数值 20用户正在离开应用如按Home键
// case ComponentCallbacks2.TRIM_MEMORY_USER_LEAVING:
// return "USER_LEAVING用户正在离开应用";
// 未知等级
default:
return "UNKNOWN(" + level + ")";
}
}
} }

View File

@@ -21,6 +21,7 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import cc.winboll.studio.powerbell.utils.ImageDownloader; import cc.winboll.studio.powerbell.utils.ImageDownloader;
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
import android.text.TextUtils;
/** /**
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com> * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
@@ -52,7 +53,7 @@ public class NetworkBackgroundDialog extends AlertDialog {
// 按钮点击回调接口Java7 接口实现) // 按钮点击回调接口Java7 接口实现)
public interface OnDialogClickListener { public interface OnDialogClickListener {
void onConfirm(String szConfirmFilePath, String previewFileUrl); // 确认按钮点击 void onConfirm(String szConfirmFilePath); // 确认按钮点击
void onCancel(); // 取消按钮点击 void onCancel(); // 取消按钮点击
} }
@@ -91,7 +92,7 @@ public class NetworkBackgroundDialog extends AlertDialog {
case MSG_IMAGE_LOAD_SUCCESS: case MSG_IMAGE_LOAD_SUCCESS:
// 图片加载成功,获取文件路径并设置背景 // 图片加载成功,获取文件路径并设置背景
mDownloadSavedPath = (String) msg.obj; mDownloadSavedPath = (String) msg.obj;
previewBackground(mDownloadSavedPath); mBackgroundView.loadImage(mDownloadSavedPath);
break; break;
case MSG_IMAGE_LOAD_FAILED: case MSG_IMAGE_LOAD_FAILED:
// 图片加载失败,设置默认背景 // 图片加载失败,设置默认背景
@@ -139,7 +140,7 @@ public class NetworkBackgroundDialog extends AlertDialog {
etURL = (EditText) dialogView.findViewById(R.id.et_url); etURL = (EditText) dialogView.findViewById(R.id.et_url);
mBackgroundView = (BackgroundView) dialogView.findViewById(R.id.bv_background_preview); mBackgroundView = (BackgroundView) dialogView.findViewById(R.id.bv_background_preview);
// 加载初始图片 // 加载初始图片
mBackgroundView.setBackgroundResource(R.drawable.ic_launcher); mBackgroundView.setBackgroundResource(R.drawable.blank100x100);
// 设置按钮点击事件 // 设置按钮点击事件
setButtonClickListeners(); setButtonClickListeners();
} }
@@ -168,13 +169,13 @@ public class NetworkBackgroundDialog extends AlertDialog {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
LogUtils.d("NetworkBackgroundDialog", "确认按钮点击"); LogUtils.d("NetworkBackgroundDialog", "确认按钮点击");
// 确定预览背景资源
BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(mContext);
utils.saveFileToPreviewBean(new File(mPreviewFilePath), mPreviewFileUrl);
dismiss(); // 关闭对话框 dismiss(); // 关闭对话框
if(TextUtils.isEmpty(mDownloadSavedPath)) {
ToastUtils.show("未下载图片。");
return;
}
if (listener != null) { if (listener != null) {
listener.onConfirm(mPreviewFilePath, mPreviewFileUrl); listener.onConfirm(mDownloadSavedPath);
} }
} }
}); });
@@ -258,6 +259,7 @@ public class NetworkBackgroundDialog extends AlertDialog {
// 发送消息到主线程,携带图片路径 // 发送消息到主线程,携带图片路径
Message successMsg = mUiHandler.obtainMessage(MSG_IMAGE_LOAD_SUCCESS, savePath); Message successMsg = mUiHandler.obtainMessage(MSG_IMAGE_LOAD_SUCCESS, savePath);
mUiHandler.sendMessage(successMsg); mUiHandler.sendMessage(successMsg);
} }
@Override @Override

View File

@@ -183,38 +183,42 @@ public class BackgroundSourceUtils {
/** /**
* 检查背景是否为空并创建空白背景Bean * 检查背景是否为空并创建空白背景Bean
*/ */
boolean checkEmptyBackgroundAndCreateBlankBackgroundBean(BackgroundBean checkBackgroundBean) { public boolean checkEmptyBackgroundAndCreateBlankBackgroundBean(BackgroundBean checkBackgroundBean) {
LogUtils.d(TAG, "【checkEmptyBackgroundAndCreateBlankBackgroundBean调用】开始检查背景Bean"); LogUtils.d(TAG, "【checkEmptyBackgroundAndCreateBlankBackgroundBean调用】开始检查背景Bean");
File fCheckBackgroundFile = new File(checkBackgroundBean.getBackgroundFilePath()); File fCheckBackgroundFile = new File(checkBackgroundBean.getBackgroundFilePath());
if (!fCheckBackgroundFile.exists()) { if (!fCheckBackgroundFile.exists()) {
String newCropFileName = genNewCropFileName(); return createBlankBackgroundBean(checkBackgroundBean.getPixelColor());
String fileSuffix = "png";
mCropSourceFile = new File(fCropCacheDir, newCropFileName + "." + fileSuffix);
mCropResultFile = new File(fCropCacheDir, "SelectCompress_" + newCropFileName + "." + fileSuffix);
AssetsCopyUtils.copyAssetsFileToDir(mContext, "images/blank100x100.png", mCropSourceFile.getAbsolutePath());
try {
mCropResultFile.createNewFile();
} catch (IOException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
loadSettings();
previewBackgroundBean.setPixelColor(0xFFFFFFFF);
previewBackgroundBean.setIsUseBackgroundFile(true);
previewBackgroundBean.setIsUseBackgroundScaledCompressFile(false);
previewBackgroundBean.setBackgroundFileName(mCropSourceFile.getName());
previewBackgroundBean.setBackgroundFilePath(mCropSourceFile.getAbsolutePath());
previewBackgroundBean.setBackgroundScaledCompressFileName(mCropResultFile.getName());
previewBackgroundBean.setBackgroundScaledCompressFilePath(mCropResultFile.getAbsolutePath());
saveSettings();
LogUtils.d(TAG, "背景Bean为空已创建空白背景并更新配置");
return true;
} }
LogUtils.d(TAG, "背景Bean文件存在无需创建空白背景"); LogUtils.d(TAG, "背景Bean文件存在无需创建空白背景");
return false; return false;
} }
public boolean createBlankBackgroundBean(int nBackgroundPixelColor) {
String newCropFileName = genNewCropFileName();
String fileSuffix = "png";
mCropSourceFile = new File(fCropCacheDir, newCropFileName + "." + fileSuffix);
mCropResultFile = new File(fCropCacheDir, "SelectCompress_" + newCropFileName + "." + fileSuffix);
AssetsCopyUtils.copyAssetsFileToDir(mContext, "images/blank100x100.png", mCropSourceFile.getAbsolutePath());
try {
mCropResultFile.createNewFile();
} catch (IOException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
loadSettings();
previewBackgroundBean.setPixelColor(nBackgroundPixelColor);
previewBackgroundBean.setIsUseBackgroundFile(true);
previewBackgroundBean.setIsUseBackgroundScaledCompressFile(false);
previewBackgroundBean.setBackgroundFileName(mCropSourceFile.getName());
previewBackgroundBean.setBackgroundFilePath(mCropSourceFile.getAbsolutePath());
previewBackgroundBean.setBackgroundScaledCompressFileName(mCropResultFile.getName());
previewBackgroundBean.setBackgroundScaledCompressFilePath(mCropResultFile.getAbsolutePath());
saveSettings();
LogUtils.d(TAG, "背景Bean为空已创建空白背景并更新配置");
return true;
}
String genNewCropFileName() { String genNewCropFileName() {
return UUID.randomUUID().toString() + System.currentTimeMillis(); return UUID.randomUUID().toString() + System.currentTimeMillis();
} }

View File

@@ -124,8 +124,8 @@ public class BackgroundView extends RelativeLayout {
// 调用带路径判断的loadImage方法 // 调用带路径判断的loadImage方法
if (isRefresh) { if (isRefresh) {
App._mBitmapCacheUtils.removeCachedBitmap(targetPath); App.sBitmapCacheUtils.removeCachedBitmap(targetPath);
App._mBitmapCacheUtils.cacheBitmap(targetPath); App.sBitmapCacheUtils.cacheBitmap(targetPath);
} }
loadImage(targetPath); loadImage(targetPath);
} }
@@ -154,7 +154,7 @@ public class BackgroundView extends RelativeLayout {
// ======================== 新增:路径判断逻辑 ======================== // ======================== 新增:路径判断逻辑 ========================
// 1. 路径未变化:直接使用缓存 // 1. 路径未变化:直接使用缓存
if (imagePath.equals(mCurrentCachedPath)) { if (imagePath.equals(mCurrentCachedPath)) {
Bitmap cachedBitmap = App._mBitmapCacheUtils.getCachedBitmap(imagePath); Bitmap cachedBitmap = App.sBitmapCacheUtils.getCachedBitmap(imagePath);
// 核心修改判断缓存Bitmap是否为null // 核心修改判断缓存Bitmap是否为null
if (cachedBitmap != null && !cachedBitmap.isRecycled()) { if (cachedBitmap != null && !cachedBitmap.isRecycled()) {
LogUtils.d(TAG, "loadImage: 路径未变,使用缓存 Bitmap"); LogUtils.d(TAG, "loadImage: 路径未变,使用缓存 Bitmap");
@@ -174,7 +174,7 @@ public class BackgroundView extends RelativeLayout {
// 2. 路径已更新:移除旧缓存,加载新图片并更新缓存 // 2. 路径已更新:移除旧缓存,加载新图片并更新缓存
if (!TextUtils.isEmpty(mCurrentCachedPath)) { if (!TextUtils.isEmpty(mCurrentCachedPath)) {
App._mBitmapCacheUtils.removeCachedBitmap(mCurrentCachedPath); App.sBitmapCacheUtils.removeCachedBitmap(mCurrentCachedPath);
LogUtils.d(TAG, "loadImage: 路径已更新,移除旧缓存 - " + mCurrentCachedPath); LogUtils.d(TAG, "loadImage: 路径已更新,移除旧缓存 - " + mCurrentCachedPath);
} }
// ======================== 路径判断逻辑结束 ======================== // ======================== 路径判断逻辑结束 ========================
@@ -194,7 +194,7 @@ public class BackgroundView extends RelativeLayout {
} }
// 缓存新图片,并更新当前缓存路径记录 // 缓存新图片,并更新当前缓存路径记录
App._mBitmapCacheUtils.cacheBitmap(imagePath); App.sBitmapCacheUtils.cacheBitmap(imagePath);
mCurrentCachedPath = imagePath; mCurrentCachedPath = imagePath;
LogUtils.d(TAG, "loadImage: 加载新图片并更新缓存 - " + imagePath); LogUtils.d(TAG, "loadImage: 加载新图片并更新缓存 - " + imagePath);

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

View File

@@ -40,17 +40,17 @@
android:layout_width="160dp" android:layout_width="160dp"
android:layout_height="36dp" android:layout_height="36dp"
android:text="Origin BG" android:text="Origin BG"
android:id="@+id/activitybackgroundpictureAButton5"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_margin="5dp"/> android:layout_margin="5dp"
android:id="@+id/activitybackgroundsettingsAButton1"/>
<cc.winboll.studio.libaes.views.AButton <cc.winboll.studio.libaes.views.AButton
android:layout_width="160dp" android:layout_width="160dp"
android:layout_height="36dp" android:layout_height="36dp"
android:text="Received BG" android:text="Received BG"
android:id="@+id/activitybackgroundpictureAButton4"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_margin="5dp"/> android:layout_margin="5dp"
android:id="@+id/activitybackgroundsettingsAButton2"/>
</RelativeLayout> </RelativeLayout>
@@ -66,7 +66,7 @@
android:text="◎" android:text="◎"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="5dp" android:layout_margin="5dp"
android:id="@+id/activitybackgroundpictureAButton1"/> android:id="@+id/activitybackgroundsettingsAButton3"/>
<cc.winboll.studio.libaes.views.AButton <cc.winboll.studio.libaes.views.AButton
android:layout_width="50dp" android:layout_width="50dp"
@@ -74,7 +74,7 @@
android:text="☑" android:text="☑"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="5dp" android:layout_margin="5dp"
android:id="@+id/activitybackgroundpictureAButton2"/> android:id="@+id/activitybackgroundsettingsAButton4"/>
<cc.winboll.studio.libaes.views.AButton <cc.winboll.studio.libaes.views.AButton
android:layout_width="50dp" android:layout_width="50dp"
@@ -82,8 +82,7 @@
android:text="♾" android:text="♾"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="5dp" android:layout_margin="5dp"
android:id="@+id/activitybackgroundpictureAButton9" android:id="@+id/activitybackgroundsettingsAButton5"/>
android:onClick="onNetworkBackgroundDialog"/>
</LinearLayout> </LinearLayout>
@@ -99,7 +98,7 @@
android:text="[+]" android:text="[+]"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="5dp" android:layout_margin="5dp"
android:id="@+id/activitybackgroundpictureAButton3"/> android:id="@+id/activitybackgroundsettingsAButton6"/>
<cc.winboll.studio.libaes.views.AButton <cc.winboll.studio.libaes.views.AButton
android:layout_width="50dp" android:layout_width="50dp"
@@ -107,7 +106,7 @@
android:text="[+~]" android:text="[+~]"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="5dp" android:layout_margin="5dp"
android:id="@+id/activitybackgroundpictureAButton6"/> android:id="@+id/activitybackgroundsettingsAButton7"/>
<cc.winboll.studio.libaes.views.AButton <cc.winboll.studio.libaes.views.AButton
android:layout_width="50dp" android:layout_width="50dp"
@@ -115,7 +114,7 @@
android:text="[◐]" android:text="[◐]"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="5dp" android:layout_margin="5dp"
android:id="@+id/activitybackgroundpictureAButton7"/> android:id="@+id/activitybackgroundsettingsAButton8"/>
<cc.winboll.studio.libaes.views.AButton <cc.winboll.studio.libaes.views.AButton
android:layout_width="50dp" android:layout_width="50dp"
@@ -123,8 +122,8 @@
android:text="[©]" android:text="[©]"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="5dp" android:layout_margin="5dp"
android:id="@+id/activitybackgroundsettingsAButton1" android:onClick="onColorPaletteDialog"
android:onClick="onColorPaletteDialog"/> android:id="@+id/activitybackgroundsettingsAButton9"/>
<cc.winboll.studio.libaes.views.AButton <cc.winboll.studio.libaes.views.AButton
android:layout_width="50dp" android:layout_width="50dp"
@@ -132,7 +131,7 @@
android:text="[○]" android:text="[○]"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="5dp" android:layout_margin="5dp"
android:id="@+id/activitybackgroundpictureAButton8"/> android:id="@+id/activitybackgroundsettingsAButton10"/>
</LinearLayout> </LinearLayout>

View File

@@ -13,11 +13,20 @@
android:id="@+id/tv_dialog_title" android:id="@+id/tv_dialog_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="网络后台提示" android:text="网络图片资源下载"
android:textSize="18sp" android:textSize="18sp"
android:textColor="@android:color/black" android:textColor="@android:color/black"
android:textStyle="bold"/> android:textStyle="bold"/>
<TextView
android:id="@+id/tv_dialog_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="请输入网络图片地址:"
android:textSize="15sp"
android:textColor="@android:color/darker_gray"/>
<LinearLayout <LinearLayout
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -54,15 +63,6 @@
</LinearLayout> </LinearLayout>
<TextView
android:id="@+id/tv_dialog_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="应用正在后台使用网络,是否继续允许?"
android:textSize="15sp"
android:textColor="@android:color/darker_gray"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -74,7 +74,7 @@
android:id="@+id/btn_cancel" android:id="@+id/btn_cancel"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="取消" android:text="关闭返回"
android:textSize="14sp" android:textSize="14sp"
android:background="@android:drawable/btn_default_small" android:background="@android:drawable/btn_default_small"
android:layout_marginRight="8dp"/> android:layout_marginRight="8dp"/>
@@ -83,7 +83,7 @@
android:id="@+id/btn_confirm" android:id="@+id/btn_confirm"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="允许" android:text="使用图片"
android:textSize="14sp" android:textSize="14sp"
android:background="@android:drawable/btn_default_small"/> android:background="@android:drawable/btn_default_small"/>