Compare commits

...

16 Commits

Author SHA1 Message Date
81b758ddc5 <powerbell>APK 15.15.7 release Publish. 2026-01-24 20:41:05 +08:00
64a53058cc 增加对签名证书修改后的证书识别能力。 2026-01-24 20:38:52 +08:00
aae17b6cd2 <powerbell>APK 15.15.6 release Publish. 2026-01-24 12:44:08 +08:00
d6637e1c17 更新基础类库,新类库应用验证模块有改进。 2026-01-24 12:41:51 +08:00
6d425cab5c <powerbell>APK 15.15.5 release Publish. 2026-01-23 03:18:09 +08:00
ab566f76ff 添加应用签名联网校验模块。 2026-01-23 03:15:06 +08:00
cd04458c62 <powerbell>APK 15.15.4 release Publish. 2026-01-20 21:21:19 +08:00
6b46180da7 应用指纹校验对话框显示优化。 2026-01-20 21:19:53 +08:00
af8b57b735 <powerbell>APK 15.15.3 release Publish. 2026-01-20 21:00:50 +08:00
21c02db577 更新基础类库,添加应用签名校验。 2026-01-20 20:59:01 +08:00
49a35829d2 <powerbell>APK 15.15.2 release Publish. 2026-01-19 20:40:18 +08:00
8229ab099a 更新应用设置窗口的TTS服务选项卡的处理逻辑。 2026-01-19 20:38:46 +08:00
45400314af <powerbell>APK 15.15.1 release Publish. 2026-01-19 20:04:16 +08:00
f53113d0df TTS贴心服务加入当前电量语音提醒功能。 2026-01-19 20:01:28 +08:00
53fb1ac835 <powerbell>APK 15.15.0 release Publish. 2026-01-13 11:47:03 +08:00
be9855b29d 更新基础类库与应用介绍页。 2026-01-13 11:44:12 +08:00
10 changed files with 401 additions and 84 deletions

View File

@@ -18,22 +18,19 @@ def genVersionName(def versionName){
} }
android { android {
// 适配MIUI12
// 关键:改为你已安装的 SDK 32≥ targetSdkVersion 30兼容已安装环境 compileSdkVersion 30
compileSdkVersion 32 buildToolsVersion "30.0.3"
// 直接使用已安装的构建工具 33.0.3(无需修改)
buildToolsVersion "33.0.3"
defaultConfig { defaultConfig {
applicationId "cc.winboll.studio.powerbell" applicationId "cc.winboll.studio.powerbell"
minSdkVersion 23 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 30
versionCode 7 versionCode 7
// versionName 更新后需要手动设置 // versionName 更新后需要手动设置
// .winboll/winbollBuildProps.properties 文件的 stageCount=0 // .winboll/winbollBuildProps.properties 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.14" versionName "15.15"
if(true) { if(true) {
versionName = genVersionName("${versionName}") versionName = genVersionName("${versionName}")
} }
@@ -83,12 +80,12 @@ dependencies {
//api 'androidx.fragment:fragment:1.1.0' //api 'androidx.fragment:fragment:1.1.0'
// WinBoLL库 nexus.winboll.cc 地址 // WinBoLL库 nexus.winboll.cc 地址
api 'cc.winboll.studio:libaes:15.12.13' api 'cc.winboll.studio:libaes:15.15.2'
api 'cc.winboll.studio:libappbase:15.14.2' api 'cc.winboll.studio:libappbase:15.15.11'
// WinBoLL备用库 jitpack.io 地址 // WinBoLL备用库 jitpack.io 地址
//api 'com.github.ZhanGSKen:AES:aes-v15.12.9' //api 'com.github.ZhanGSKen:AES:aes-v15.15.2'
//api 'com.github.ZhanGSKen:APPBase:appbase-v15.14.1' //api 'com.github.ZhanGSKen:APPBase:appbase-v15.15.4'
//api fileTree(dir: 'libs', include: ['*.aar']) //api fileTree(dir: 'libs', include: ['*.aar'])
api fileTree(dir: 'libs', include: ['*.jar']) api fileTree(dir: 'libs', include: ['*.jar'])

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Wed Jan 07 18:09:34 HKT 2026 #Sat Jan 24 20:41:05 HKT 2026
stageCount=50 stageCount=8
libraryProject= libraryProject=
baseVersion=15.14 baseVersion=15.15
publishVersion=15.14.49 publishVersion=15.15.7
buildCount=0 buildCount=0
baseBetaVersion=15.14.50 baseBetaVersion=15.15.8

View File

@@ -301,7 +301,8 @@
android:process=":main" android:process=":main"
android:stopWithTask="false"/> android:stopWithTask="false"/>
<service android:name=".services.ThoughtfulService" <service
android:name=".services.ThoughtfulService"
android:enabled="true" android:enabled="true"
android:exported="false" android:exported="false"
android:process=":main" android:process=":main"
@@ -324,6 +325,8 @@
android:name="android.max_aspect" android:name="android.max_aspect"
android:value="4.0"/> android:value="4.0"/>
<activity android:name="cc.winboll.studio.powerbell.activities.AboutActivity"/>
</application> </application>
</manifest> </manifest>

View File

@@ -13,13 +13,13 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewStub; import android.view.ViewStub;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libaes.activitys.AboutActivity;
import cc.winboll.studio.libaes.models.APPInfo; import cc.winboll.studio.libaes.models.APPInfo;
import cc.winboll.studio.libaes.utils.AESThemeUtil; import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.libaes.utils.DevelopUtils; import cc.winboll.studio.libaes.utils.DevelopUtils;
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
import cc.winboll.studio.libaes.views.ADsBannerView; import cc.winboll.studio.libaes.views.ADsBannerView;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.powerbell.activities.AboutActivity;
import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity; import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity;
import cc.winboll.studio.powerbell.activities.BatteryReportActivity; import cc.winboll.studio.powerbell.activities.BatteryReportActivity;
import cc.winboll.studio.powerbell.activities.ClearRecordActivity; import cc.winboll.studio.powerbell.activities.ClearRecordActivity;
@@ -550,7 +550,6 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
LogUtils.d(TAG, "startAboutActivity() 调用"); LogUtils.d(TAG, "startAboutActivity() 调用");
Intent aboutIntent = new Intent(getApplicationContext(), AboutActivity.class); Intent aboutIntent = new Intent(getApplicationContext(), AboutActivity.class);
APPInfo appInfo = genDefaultAppInfo(); APPInfo appInfo = genDefaultAppInfo();
aboutIntent.putExtra(AboutActivity.EXTRA_APPINFO, appInfo);
WinBoLLActivityManager.getInstance().startWinBoLLActivity(getApplicationContext(), aboutIntent, AboutActivity.class); WinBoLLActivityManager.getInstance().startWinBoLLActivity(getApplicationContext(), aboutIntent, AboutActivity.class);
LogUtils.d(TAG, "startAboutActivity: 关于页面已启动"); LogUtils.d(TAG, "startAboutActivity: 关于页面已启动");
} }

View File

@@ -0,0 +1,81 @@
package cc.winboll.studio.powerbell.activities;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.models.APPInfo;
import cc.winboll.studio.libappbase.views.AboutView;
import cc.winboll.studio.powerbell.R;
/**
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
* @Date 2026/01/13 11:25
* @Describe 应用介绍窗口
*/
public class AboutActivity extends WinBoLLActivity {
public static final String TAG = "AboutActivity";
private Toolbar mToolbar;
@Override
public Activity getActivity() {
return this;
}
@Override
public String getTag() {
return TAG;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
// 设置工具栏
initToolbar();
AboutView aboutView = findViewById(R.id.aboutview);
aboutView.setAPPInfo(genDefaultAppInfo());
}
private void initToolbar() {
LogUtils.d(TAG, "initToolbar() 开始初始化");
mToolbar = findViewById(R.id.toolbar);
if (mToolbar == null) {
LogUtils.e(TAG, "initToolbar() | Toolbar未找到");
return;
}
setSupportActionBar(mToolbar);
mToolbar.setSubtitle(getTag());
mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LogUtils.d(TAG, "导航栏 点击返回按钮");
finish();
}
});
LogUtils.d(TAG, "initToolbar() 配置完成");
}
private APPInfo genDefaultAppInfo() {
LogUtils.d(TAG, "genDefaultAppInfo() 调用");
String branchName = "powerbell";
APPInfo appInfo = new APPInfo();
appInfo.setAppName(getString(R.string.app_name));
appInfo.setAppIcon(R.drawable.ic_winboll);
appInfo.setAppDescription(getString(R.string.app_description));
appInfo.setAppGitName("PowerBell");
appInfo.setAppGitOwner("Studio");
appInfo.setAppGitAPPBranch(branchName);
appInfo.setAppGitAPPSubProjectFolder(branchName);
appInfo.setAppHomePage("https://www.winboll.cc/apks/index.php?project=PowerBell");
appInfo.setAppAPKName("PowerBell");
appInfo.setAppAPKFolderName("PowerBell");
LogUtils.d(TAG, "genDefaultAppInfo: 应用信息已生成");
return appInfo;
}
}

View File

@@ -23,20 +23,24 @@ import java.lang.reflect.Field;
/** /**
* 应用设置窗口,提供应用配置项的统一入口 * 应用设置窗口,提供应用配置项的统一入口
* 适配 API30基于 Java7 开发 * 适配 API30基于 Java7 开发
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com> * @Author 豆包&ZhanGSKen<zhangsken@qq.com>
* @Date 2025/11/27 14:26 * @Date 202511271426分00秒
* @Describe 应用设置窗口 * @LastEditTime 2026年01月19日22时18分00秒
* @Describe 应用设置窗口(主开关联动子开关启用/禁用,主开关关闭则子开关禁用并取消勾选)
*/ */
public class SettingsActivity extends WinBoLLActivity implements IWinBoLLActivity { public class SettingsActivity extends WinBoLLActivity implements IWinBoLLActivity {
// ======================== 静态常量 ========================= // ======================== 静态常量 =========================
public static final String TAG = "SettingsActivity"; public static final String TAG = "SettingsActivity";
// 权限请求常量(为后续读取媒体图片权限预留)
private static final int REQUEST_READ_MEDIA_IMAGES = 1001; private static final int REQUEST_READ_MEDIA_IMAGES = 1001;
// ======================== 成员变量 ========================= // ======================== 成员属性区 =========================
private Toolbar mToolbar; // 顶部工具栏 private Toolbar mToolbar;
private CheckBox cbUsePowerTts; // 用电TTS主开关
private CheckBox cbChargeTts; // 充电TTS主开关
private CheckBox cbUseageTtsBattary; // 用电TTS带电量提醒子开关
private CheckBox cbChargeTtsBattary; // 充电TTS带电量提醒子开关
// ======================== 接口实现方法 ========================= // ======================== 接口实现 =========================
@Override @Override
public Activity getActivity() { public Activity getActivity() {
return this; return this;
@@ -47,96 +51,191 @@ public class SettingsActivity extends WinBoLLActivity implements IWinBoLLActivit
return TAG; return TAG;
} }
// ======================== 生命周期方法 ========================= // ======================== 生命周期 =========================
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings); setContentView(R.layout.activity_settings);
LogUtils.d(TAG, "onCreate】SettingsActivity 初始化开始"); LogUtils.d(TAG, "onCreate: 应用设置页面初始化开始");
// 初始化工具栏
initToolbar(); initToolbar();
initTtsCheckBoxes();
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); initTtsCheckBoxStatus();
if (thoughtfulServiceBean == null) {
thoughtfulServiceBean = new ThoughtfulServiceBean();
}
((CheckBox)findViewById(R.id.activitysettingsCheckBox1)).setChecked(thoughtfulServiceBean.isEnableUsePowerTts());
((CheckBox)findViewById(R.id.activitysettingsCheckBox2)).setChecked(thoughtfulServiceBean.isEnableChargeTts());
LogUtils.d(TAG, "onCreate】SettingsActivity 初始化完成"); LogUtils.d(TAG, "onCreate: 应用设置页面初始化完成");
} }
// ======================== UI初始化方法 ========================= // ======================== UI初始化 =========================
/** /**
* 初始化顶部工具栏,设置导航返回与样式 * 初始化顶部工具栏
*/ */
private void initToolbar() { private void initToolbar() {
LogUtils.d(TAG, "initToolbar: 工具栏初始化开始");
mToolbar = findViewById(R.id.toolbar); mToolbar = findViewById(R.id.toolbar);
setSupportActionBar(mToolbar); setSupportActionBar(mToolbar);
// 设置工具栏副标题与标题样式
mToolbar.setSubtitle(getTag()); mToolbar.setSubtitle(getTag());
mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText); mToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText);
// 显示返回按钮
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// 绑定导航点击事件
mToolbar.setNavigationOnClickListener(new View.OnClickListener() { mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
LogUtils.d(TAG, "【导航栏】点击返回"); LogUtils.d(TAG, "initToolbar-navigationOnClick: 点击导航返回按钮");
finish(); finish();
} }
}); });
LogUtils.d(TAG, "initToolbar工具栏初始化完成"); LogUtils.d(TAG, "initToolbar: 工具栏初始化完成");
} }
public void onCheckTTSDrawOverlaysPermission(View view) { /**
canDrawOverlays(); * 绑定TTS相关复选框控件
} */
private void initTtsCheckBoxes() {
LogUtils.d(TAG, "initTtsCheckBoxes: TTS复选框绑定开始");
cbUsePowerTts = findViewById(R.id.activitysettingsCheckBox1);
cbChargeTts = findViewById(R.id.activitysettingsCheckBox2);
cbUseageTtsBattary = findViewById(R.id.activitysettingsCheckBox3);
cbChargeTtsBattary = findViewById(R.id.activitysettingsCheckBox4);
LogUtils.d(TAG, "initTtsCheckBoxes: TTS复选框绑定完成");
}
public void onEnableChargeTts(View view) { /**
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); * 初始化TTS复选框初始状态
if (thoughtfulServiceBean == null) { */
thoughtfulServiceBean = new ThoughtfulServiceBean(); private void initTtsCheckBoxStatus() {
} LogUtils.d(TAG, "initTtsCheckBoxStatus: TTS复选框状态初始化开始");
thoughtfulServiceBean.setIsEnableChargeTts(((CheckBox)view).isChecked()); ThoughtfulServiceBean bean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class);
ThoughtfulServiceBean.saveBean(this, thoughtfulServiceBean); if (bean == null) {
} LogUtils.d(TAG, "initTtsCheckBoxStatus: 未读取到配置Bean创建新实例");
bean = new ThoughtfulServiceBean();
}
public void onEnableUsePowerTts(View view) { boolean useMainOpen = bean.isEnableUsePowerTts();
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); boolean chargeMainOpen = bean.isEnableChargeTts();
if (thoughtfulServiceBean == null) { cbUsePowerTts.setChecked(useMainOpen);
thoughtfulServiceBean = new ThoughtfulServiceBean(); cbChargeTts.setChecked(chargeMainOpen);
} cbUseageTtsBattary.setChecked(bean.isEnableUseageTtsWithBattary());
thoughtfulServiceBean.setIsEnableUsePowerTts(((CheckBox)view).isChecked()); cbChargeTtsBattary.setChecked(bean.isEnableChargeTtsWithBattary());
ThoughtfulServiceBean.saveBean(this, thoughtfulServiceBean); cbUseageTtsBattary.setEnabled(useMainOpen);
} cbChargeTtsBattary.setEnabled(chargeMainOpen);
/** LogUtils.d(TAG, "initTtsCheckBoxStatus: 主开关状态-用电TTS" + useMainOpen + " 充电TTS" + chargeMainOpen);
LogUtils.d(TAG, "initTtsCheckBoxStatus: TTS复选框状态初始化完成");
}
// ======================== 事件响应区 =========================
/**
* 悬浮窗权限检查入口
*/
public void onCheckTTSDrawOverlaysPermission(View view) {
LogUtils.d(TAG, "onCheckTTSDrawOverlaysPermission: 触发悬浮窗权限检查");
canDrawOverlays();
}
/**
* 用电TTS主开关点击事件
*/
public void onEnableUsePowerTts(View view) {
boolean isChecked = cbUsePowerTts.isChecked();
LogUtils.d(TAG, "onEnableUsePowerTts: 用电TTS主开关点击切换后状态=" + isChecked);
cbUsePowerTts.setChecked(isChecked);
// 主开关联动子开关
cbUseageTtsBattary.setEnabled(isChecked);
// if (!isChecked) {
// cbUseageTtsBattary.setChecked(false);
// }
// 保存配置
ThoughtfulServiceBean bean = getThoughtfulServiceBean();
bean.setIsEnableUsePowerTts(isChecked);
ThoughtfulServiceBean.saveBean(this, bean);
LogUtils.d(TAG, "onEnableUsePowerTts: 用电TTS状态保存完成");
}
/**
* 充电TTS主开关点击事件
*/
public void onEnableChargeTts(View view) {
boolean isChecked = cbChargeTts.isChecked();
LogUtils.d(TAG, "onEnableChargeTts: 充电TTS主开关点击切换后状态=" + isChecked);
cbChargeTts.setChecked(isChecked);
// 主开关联动子开关
cbChargeTtsBattary.setEnabled(isChecked);
// if (!isChecked) {
// cbChargeTtsBattary.setChecked(false);
// }
// 保存配置
ThoughtfulServiceBean bean = getThoughtfulServiceBean();
bean.setIsEnableChargeTts(isChecked);
ThoughtfulServiceBean.saveBean(this, bean);
LogUtils.d(TAG, "onEnableChargeTts: 充电TTS状态保存完成");
}
/**
* 用电TTS带电量提醒子开关点击事件
*/
public void onEnableUseageTtsWithBattary(View view) {
boolean isChecked = cbUseageTtsBattary.isChecked();
LogUtils.d(TAG, "onEnableUseageTtsWithBattary: 用电TTS电量提醒开关点击切换后状态=" + isChecked);
cbUseageTtsBattary.setChecked(isChecked);
ThoughtfulServiceBean bean = getThoughtfulServiceBean();
bean.setIsEnableUseageTtsWithBattary(isChecked);
ThoughtfulServiceBean.saveBean(this, bean);
LogUtils.d(TAG, "onEnableUseageTtsWithBattary: 用电TTS电量提醒状态保存完成");
}
/**
* 充电TTS带电量提醒子开关点击事件
*/
public void onEnableChargeTtsWithBattary(View view) {
boolean isChecked = cbChargeTtsBattary.isChecked();
LogUtils.d(TAG, "onEnableChargeTtsWithBattary: 充电TTS电量提醒开关点击切换后状态=" + isChecked);
cbChargeTtsBattary.setChecked(isChecked);
ThoughtfulServiceBean bean = getThoughtfulServiceBean();
bean.setIsEnableChargeTtsWithBattary(isChecked);
ThoughtfulServiceBean.saveBean(this, bean);
LogUtils.d(TAG, "onEnableChargeTtsWithBattary: 充电TTS电量提醒状态保存完成");
}
// ======================== 工具方法区 =========================
/**
* 获取配置Bean实例避免重复代码
*/
private ThoughtfulServiceBean getThoughtfulServiceBean() {
LogUtils.d(TAG, "getThoughtfulServiceBean: 获取配置Bean");
ThoughtfulServiceBean bean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class);
if (bean == null) {
LogUtils.d(TAG, "getThoughtfulServiceBean: 配置Bean为空创建新实例");
bean = new ThoughtfulServiceBean();
}
return bean;
}
/**
* 悬浮窗权限检查与请求 * 悬浮窗权限检查与请求
*/ */
void canDrawOverlays() { void canDrawOverlays() {
LogUtils.d(TAG, "onCanDrawOverlays: 检查悬浮窗权限"); LogUtils.d(TAG, "canDrawOverlays: 悬浮窗权限检查开始");
// API6.0+校验权限
if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) { if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) {
LogUtils.d(TAG, "onCanDrawOverlays: 未开启悬浮窗权限,发起请求"); LogUtils.d(TAG, "canDrawOverlays: 未开启悬浮窗权限,发起请求");
showDrawOverlayRequestDialog(); showDrawOverlayRequestDialog();
} else { } else {
LogUtils.d(TAG, "canDrawOverlays: 悬浮窗权限已开启");
ToastUtils.show("悬浮窗权限已开启"); ToastUtils.show("悬浮窗权限已开启");
} }
} }
/** /**
* 显示悬浮窗权限请求对话框 * 显示悬浮窗权限请求对话框
*/ */
private void showDrawOverlayRequestDialog() { private void showDrawOverlayRequestDialog() {
LogUtils.d(TAG, "showDrawOverlayRequestDialog: 显示悬浮窗权限请求弹窗");
AlertDialog dialog = new AlertDialog.Builder(this) AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("权限请求") .setTitle("权限请求")
.setMessage("为保证通话监听功能正常,需开启悬浮窗权限") .setMessage("为保证通话监听功能正常,需开启悬浮窗权限")
.setPositiveButton("去设置", new DialogInterface.OnClickListener() { .setPositiveButton("去设置", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
LogUtils.d(TAG, "showDrawOverlayRequestDialog-去设置: 点击跳转权限页面");
dialog.dismiss(); dialog.dismiss();
jumpToDrawOverlaySettings(); jumpToDrawOverlaySettings();
} }
@@ -144,12 +243,12 @@ public class SettingsActivity extends WinBoLLActivity implements IWinBoLLActivit
.setNegativeButton("稍后", new DialogInterface.OnClickListener() { .setNegativeButton("稍后", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
LogUtils.d(TAG, "showDrawOverlayRequestDialog-稍后: 点击取消请求");
dialog.dismiss(); dialog.dismiss();
} }
}) })
.create(); .create();
// 解决对话框焦点问题
if (dialog.getWindow() != null) { if (dialog.getWindow() != null) {
dialog.getWindow().setFlags( dialog.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
@@ -162,23 +261,21 @@ public class SettingsActivity extends WinBoLLActivity implements IWinBoLLActivit
* 跳转悬浮窗权限设置页面(反射适配低版本) * 跳转悬浮窗权限设置页面(反射适配低版本)
*/ */
private void jumpToDrawOverlaySettings() { private void jumpToDrawOverlaySettings() {
LogUtils.d(TAG, "jumpToDrawOverlaySettings: 跳转悬浮窗权限设置"); LogUtils.d(TAG, "jumpToDrawOverlaySettings: 跳转悬浮窗权限设置页面");
try { try {
// 反射获取设置页面Action避免高版本API依赖
Class<?> settingsClazz = Settings.class; Class<?> settingsClazz = Settings.class;
Field actionField = settingsClazz.getDeclaredField("ACTION_MANAGE_OVERLAY_PERMISSION"); Field actionField = settingsClazz.getDeclaredField("ACTION_MANAGE_OVERLAY_PERMISSION");
String action = (String) actionField.get(null); String action = (String) actionField.get(null);
// 跳转当前应用权限设置页
Intent intent = new Intent(action); Intent intent = new Intent(action);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("package:" + getPackageName())); intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent); startActivity(intent);
LogUtils.d(TAG, "jumpToDrawOverlaySettings: 跳转权限页面意图已发送");
} catch (Exception e) { } catch (Exception e) {
LogUtils.e(TAG, "jumpToDrawOverlaySettings: 跳转权限设置失败", e); LogUtils.e(TAG, "jumpToDrawOverlaySettings: 跳转权限设置失败", e);
Toast.makeText(this, "请手动在设置中开启悬浮窗权限", Toast.LENGTH_LONG).show(); Toast.makeText(this, "请手动在设置中开启悬浮窗权限", Toast.LENGTH_LONG).show();
} }
} }
} }

View File

@@ -24,10 +24,15 @@ public class ThoughtfulServiceBean extends BaseBean implements Parcelable, Seria
// JSON序列化字段常量 杜绝硬编码 // JSON序列化字段常量 杜绝硬编码
public static final String JSON_FIELD_IS_ENABLE_CHARGE_TTS = "isEnableChargeTts"; public static final String JSON_FIELD_IS_ENABLE_CHARGE_TTS = "isEnableChargeTts";
public static final String JSON_FIELD_IS_ENABLE_USE_POWER_TTS = "isEnableUsePowerTts"; public static final String JSON_FIELD_IS_ENABLE_USE_POWER_TTS = "isEnableUsePowerTts";
// 新增字段JSON常量
public static final String JSON_FIELD_IS_ENABLE_USAGE_TTS_WITH_BATTERY = "isEnableUseageTtsWithBattary";
public static final String JSON_FIELD_IS_ENABLE_CHARGE_TTS_WITH_BATTERY = "isEnableChargeTtsWithBattary";
// ====================== 核心成员变量 - 私有封装 ====================== // ====================== 核心成员变量 - 私有封装 ======================
private boolean isEnableChargeTts = false; // 是否启用 充电TTS贴心语音服务 private boolean isEnableChargeTts = false; // 是否启用 充电TTS贴心语音服务
private boolean isEnableUsePowerTts = false; // 是否启用 用电TTS贴心语音服务 private boolean isEnableUsePowerTts = false; // 是否启用 用电TTS贴心语音服务
private boolean isEnableUseageTtsWithBattary = false; // 用电TTS加入电量提醒
private boolean isEnableChargeTtsWithBattary = false;// 充电TTS加入电量提醒
// ====================== Parcelable 静态创建器 (API30标准写法 必须public static final) ====================== // ====================== Parcelable 静态创建器 (API30标准写法 必须public static final) ======================
public static final Creator<ThoughtfulServiceBean> CREATOR = new Creator<ThoughtfulServiceBean>() { public static final Creator<ThoughtfulServiceBean> CREATOR = new Creator<ThoughtfulServiceBean>() {
@@ -55,11 +60,17 @@ public class ThoughtfulServiceBean extends BaseBean implements Parcelable, Seria
* 全参构造 - 手动配置所有服务状态 * 全参构造 - 手动配置所有服务状态
* @param isEnableChargeTts 充电TTS服务开关 * @param isEnableChargeTts 充电TTS服务开关
* @param isEnableUsePowerTts 用电TTS服务开关 * @param isEnableUsePowerTts 用电TTS服务开关
* @param isEnableUseageTtsWithBattary 用电TTS加电量提醒开关
* @param isEnableChargeTtsWithBattary 充电TTS加电量提醒开关
*/ */
public ThoughtfulServiceBean(boolean isEnableChargeTts, boolean isEnableUsePowerTts) { public ThoughtfulServiceBean(boolean isEnableChargeTts, boolean isEnableUsePowerTts,
boolean isEnableUseageTtsWithBattary, boolean isEnableChargeTtsWithBattary) {
this.isEnableChargeTts = isEnableChargeTts; this.isEnableChargeTts = isEnableChargeTts;
this.isEnableUsePowerTts = isEnableUsePowerTts; this.isEnableUsePowerTts = isEnableUsePowerTts;
LogUtils.d(TAG, "ThoughtfulServiceBean: 全参构造 | isEnableChargeTts=" + isEnableChargeTts + " | isEnableUsePowerTts=" + isEnableUsePowerTts); this.isEnableUseageTtsWithBattary = isEnableUseageTtsWithBattary;
this.isEnableChargeTtsWithBattary = isEnableChargeTtsWithBattary;
LogUtils.d(TAG, "ThoughtfulServiceBean: 全参构造 | 充电TTS=" + isEnableChargeTts + " | 用电TTS=" + isEnableUsePowerTts
+ " | 用电TTS加电量=" + isEnableUseageTtsWithBattary + " | 充电TTS加电量=" + isEnableChargeTtsWithBattary);
} }
/** /**
@@ -68,7 +79,11 @@ public class ThoughtfulServiceBean extends BaseBean implements Parcelable, Seria
private ThoughtfulServiceBean(Parcel in) { private ThoughtfulServiceBean(Parcel in) {
this.isEnableChargeTts = in.readByte() != 0; this.isEnableChargeTts = in.readByte() != 0;
this.isEnableUsePowerTts = in.readByte() != 0; this.isEnableUsePowerTts = in.readByte() != 0;
LogUtils.d(TAG, "ThoughtfulServiceBean: Parcel构造解析完成 | isEnableChargeTts=" + isEnableChargeTts + " | isEnableUsePowerTts=" + isEnableUsePowerTts); // 新增字段反序列化
this.isEnableUseageTtsWithBattary = in.readByte() != 0;
this.isEnableChargeTtsWithBattary = in.readByte() != 0;
LogUtils.d(TAG, "ThoughtfulServiceBean: Parcel构造解析完成 | 充电TTS=" + isEnableChargeTts + " | 用电TTS=" + isEnableUsePowerTts
+ " | 用电TTS加电量=" + isEnableUseageTtsWithBattary + " | 充电TTS加电量=" + isEnableChargeTtsWithBattary);
} }
// ====================== Getter/Setter 方法区 (封装成员变量 统一访问) ====================== // ====================== Getter/Setter 方法区 (封装成员变量 统一访问) ======================
@@ -90,6 +105,26 @@ public class ThoughtfulServiceBean extends BaseBean implements Parcelable, Seria
this.isEnableUsePowerTts = isEnableUsePowerTts; this.isEnableUsePowerTts = isEnableUsePowerTts;
} }
// 新增 用电TTS加入电量提醒 Getter/Setter
public boolean isEnableUseageTtsWithBattary() {
return isEnableUseageTtsWithBattary;
}
public void setIsEnableUseageTtsWithBattary(boolean isEnableUseageTtsWithBattary) {
LogUtils.d(TAG, "setIsEnableUseageTtsWithBattary: 旧值=" + this.isEnableUseageTtsWithBattary + " 新值=" + isEnableUseageTtsWithBattary);
this.isEnableUseageTtsWithBattary = isEnableUseageTtsWithBattary;
}
// 新增 充电TTS加入电量提醒 Getter/Setter
public boolean isEnableChargeTtsWithBattary() {
return isEnableChargeTtsWithBattary;
}
public void setIsEnableChargeTtsWithBattary(boolean isEnableChargeTtsWithBattary) {
LogUtils.d(TAG, "setIsEnableChargeTtsWithBattary: 旧值=" + this.isEnableChargeTtsWithBattary + " 新值=" + isEnableChargeTtsWithBattary);
this.isEnableChargeTtsWithBattary = isEnableChargeTtsWithBattary;
}
// ====================== 重写父类 BaseBean 核心方法 (JSON序列化/反序列化 业务核心) ====================== // ====================== 重写父类 BaseBean 核心方法 (JSON序列化/反序列化 业务核心) ======================
@Override @Override
public String getName() { public String getName() {
@@ -106,6 +141,9 @@ public class ThoughtfulServiceBean extends BaseBean implements Parcelable, Seria
super.writeThisToJsonWriter(jsonWriter); super.writeThisToJsonWriter(jsonWriter);
jsonWriter.name(JSON_FIELD_IS_ENABLE_CHARGE_TTS).value(this.isEnableChargeTts); jsonWriter.name(JSON_FIELD_IS_ENABLE_CHARGE_TTS).value(this.isEnableChargeTts);
jsonWriter.name(JSON_FIELD_IS_ENABLE_USE_POWER_TTS).value(this.isEnableUsePowerTts); jsonWriter.name(JSON_FIELD_IS_ENABLE_USE_POWER_TTS).value(this.isEnableUsePowerTts);
// 新增字段JSON序列化
jsonWriter.name(JSON_FIELD_IS_ENABLE_USAGE_TTS_WITH_BATTERY).value(this.isEnableUseageTtsWithBattary);
jsonWriter.name(JSON_FIELD_IS_ENABLE_CHARGE_TTS_WITH_BATTERY).value(this.isEnableChargeTtsWithBattary);
LogUtils.d(TAG, "writeThisToJsonWriter: JSON序列化完成所有TTS服务状态已写入"); LogUtils.d(TAG, "writeThisToJsonWriter: JSON序列化完成所有TTS服务状态已写入");
} }
@@ -124,6 +162,13 @@ public class ThoughtfulServiceBean extends BaseBean implements Parcelable, Seria
break; break;
case JSON_FIELD_IS_ENABLE_USE_POWER_TTS: case JSON_FIELD_IS_ENABLE_USE_POWER_TTS:
bean.setIsEnableUsePowerTts(jsonReader.nextBoolean()); bean.setIsEnableUsePowerTts(jsonReader.nextBoolean());
break;
// 新增字段反序列化
case JSON_FIELD_IS_ENABLE_USAGE_TTS_WITH_BATTERY:
bean.setIsEnableUseageTtsWithBattary(jsonReader.nextBoolean());
break;
case JSON_FIELD_IS_ENABLE_CHARGE_TTS_WITH_BATTERY:
bean.setIsEnableChargeTtsWithBattary(jsonReader.nextBoolean());
break; break;
default: default:
jsonReader.skipValue(); jsonReader.skipValue();
@@ -149,6 +194,9 @@ public class ThoughtfulServiceBean extends BaseBean implements Parcelable, Seria
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (isEnableChargeTts ? 1 : 0)); dest.writeByte((byte) (isEnableChargeTts ? 1 : 0));
dest.writeByte((byte) (isEnableUsePowerTts ? 1 : 0)); dest.writeByte((byte) (isEnableUsePowerTts ? 1 : 0));
// 新增字段Parcel序列化
dest.writeByte((byte) (isEnableUseageTtsWithBattary ? 1 : 0));
dest.writeByte((byte) (isEnableChargeTtsWithBattary ? 1 : 0));
LogUtils.d(TAG, "writeToParcel: Parcel序列化完成所有TTS服务状态已写入"); LogUtils.d(TAG, "writeToParcel: Parcel序列化完成所有TTS服务状态已写入");
} }

View File

@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.powerbell.App;
import cc.winboll.studio.powerbell.models.AppConfigBean; import cc.winboll.studio.powerbell.models.AppConfigBean;
import cc.winboll.studio.powerbell.models.ThoughtfulServiceBean; import cc.winboll.studio.powerbell.models.ThoughtfulServiceBean;
import cc.winboll.studio.powerbell.utils.AppConfigUtils; import cc.winboll.studio.powerbell.utils.AppConfigUtils;
@@ -31,7 +32,7 @@ public class ThoughtfulService extends Service {
*/ */
public enum ServiceType { public enum ServiceType {
CHARGE_STATE, //充电状态服务 CHARGE_STATE, //充电状态服务
DISCHARGE_STATE //放电状态服务 DISCHARGE_STATE, //放电状态服务
} }
// ====================================== 对外公开静态启动函数【新增核心】入参Context + 枚举 ====================================== // ====================================== 对外公开静态启动函数【新增核心】入参Context + 枚举 ======================================
@@ -95,7 +96,7 @@ public class ThoughtfulService extends Service {
case DISCHARGE_STATE: case DISCHARGE_STATE:
// 执行【放电状态】对应的业务任务 // 执行【放电状态】对应的业务任务
executeDischargeStateTask(); executeDischargeStateTask();
break; break;
default: default:
LogUtils.d(TAG, "【onStartCommand】未知的服务类型不执行任何任务"); LogUtils.d(TAG, "【onStartCommand】未知的服务类型不执行任何任务");
break; break;
@@ -129,10 +130,16 @@ public class ThoughtfulService extends Service {
return; return;
} }
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class);
if (thoughtfulServiceBean == null) {
thoughtfulServiceBean = new ThoughtfulServiceBean();
}
if (latestConfig.isEnableChargeReminder()) { if (latestConfig.isEnableChargeReminder()) {
int nChargeReminderValue = latestConfig.getChargeReminderValue(); int nChargeReminderValue = latestConfig.getChargeReminderValue();
String szCurrentBattery = thoughtfulServiceBean.isEnableChargeTtsWithBattary()? String.format("现在电量为百分之%d。", App.sQuantityOfElectricity) : "";
String szRemind = String.format("限量充电提醒已启用,限量值为百分之%d。", nChargeReminderValue); String szRemind = String.format("限量充电提醒已启用,限量值为百分之%d。", nChargeReminderValue);
szRemind = szRemind + szRemind + szRemind; szRemind = szCurrentBattery + szRemind + szRemind + szRemind;
TTSPlayService.startPlayTTS(this, szRemind); TTSPlayService.startPlayTTS(this, szRemind);
} }
} }
@@ -151,14 +158,22 @@ public class ThoughtfulService extends Service {
LogUtils.e(TAG, "handleNotifyAppConfigUpdate() 终止 | 最新配置为空"); LogUtils.e(TAG, "handleNotifyAppConfigUpdate() 终止 | 最新配置为空");
return; return;
} }
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class);
if (thoughtfulServiceBean == null) {
thoughtfulServiceBean = new ThoughtfulServiceBean();
}
if (latestConfig.isEnableUsageReminder()) { if (latestConfig.isEnableUsageReminder()) {
int nUsageReminderValue = latestConfig.getUsageReminderValue(); int nUsageReminderValue = latestConfig.getUsageReminderValue();
String szRemind = String.format("电量不足提醒已启用,低电值为百分之%d。", nUsageReminderValue); String szCurrentBattery = thoughtfulServiceBean.isEnableUseageTtsWithBattary()? String.format("现在电量为百分之%d。", App.sQuantityOfElectricity) : "";
String szRemind = szCurrentBattery + String.format("电量不足提醒已启用,低电值为百分之%d。", nUsageReminderValue);
//szRemind = szRemind + szRemind + szRemind; //szRemind = szRemind + szRemind + szRemind;
TTSPlayService.startPlayTTS(this, szRemind); TTSPlayService.startPlayTTS(this, szRemind);
} }
} }
} }

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<cc.winboll.studio.libaes.views.ASupportToolbar
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:id="@+id/toolbar"
android:gravity="center_vertical"
style="@style/DefaultAToolbar"/>
<cc.winboll.studio.libappbase.views.AboutView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:id="@+id/aboutview"/>
</LinearLayout>

View File

@@ -62,6 +62,33 @@
android:onClick="onEnableUsePowerTts" android:onClick="onEnableUsePowerTts"
android:id="@+id/activitysettingsCheckBox1"/> android:id="@+id/activitysettingsCheckBox1"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="("
android:layout_marginLeft="10dp"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用电TTS加入电量提醒"
android:onClick="onEnableUseageTtsWithBattary"
android:id="@+id/activitysettingsCheckBox3"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=")"
android:layout_marginLeft="20dp"/>
</LinearLayout>
<CheckBox <CheckBox
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -69,6 +96,33 @@
android:onClick="onEnableChargeTts" android:onClick="onEnableChargeTts"
android:id="@+id/activitysettingsCheckBox2"/> android:id="@+id/activitysettingsCheckBox2"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="("
android:layout_marginLeft="10dp"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="充电TTS加入电量提醒"
android:onClick="onEnableChargeTtsWithBattary"
android:id="@+id/activitysettingsCheckBox4"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=")"
android:layout_marginLeft="20dp"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout