更新应用设置窗口的TTS服务选项卡的处理逻辑。

This commit is contained in:
2026-01-19 20:38:46 +08:00
parent 45400314af
commit 8229ab099a
3 changed files with 203 additions and 94 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Mon Jan 19 20:04:16 HKT 2026 #Mon Jan 19 12:37:49 GMT 2026
stageCount=2 stageCount=2
libraryProject= libraryProject=
baseVersion=15.15 baseVersion=15.15
publishVersion=15.15.1 publishVersion=15.15.1
buildCount=0 buildCount=1
baseBetaVersion=15.15.2 baseBetaVersion=15.15.2

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,122 +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();
initTtsCheckBoxStatus();
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); LogUtils.d(TAG, "onCreate: 应用设置页面初始化完成");
if (thoughtfulServiceBean == null) {
thoughtfulServiceBean = new ThoughtfulServiceBean();
}
// 原有2个复选框赋值
((CheckBox)findViewById(R.id.activitysettingsCheckBox1)).setChecked(thoughtfulServiceBean.isEnableUsePowerTts());
((CheckBox)findViewById(R.id.activitysettingsCheckBox2)).setChecked(thoughtfulServiceBean.isEnableChargeTts());
// 新增2个复选框赋值
((CheckBox)findViewById(R.id.activitysettingsCheckBox3)).setChecked(thoughtfulServiceBean.isEnableUseageTtsWithBattary());
((CheckBox)findViewById(R.id.activitysettingsCheckBox4)).setChecked(thoughtfulServiceBean.isEnableChargeTtsWithBattary());
LogUtils.d(TAG, "【onCreate】SettingsActivity 初始化完成");
} }
// ======================== 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) { * 初始化TTS复选框初始状态
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); */
if (thoughtfulServiceBean == null) { private void initTtsCheckBoxStatus() {
thoughtfulServiceBean = new ThoughtfulServiceBean(); LogUtils.d(TAG, "initTtsCheckBoxStatus: TTS复选框状态初始化开始");
} ThoughtfulServiceBean bean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class);
thoughtfulServiceBean.setIsEnableChargeTts(((CheckBox)view).isChecked()); if (bean == null) {
ThoughtfulServiceBean.saveBean(this, thoughtfulServiceBean); LogUtils.d(TAG, "initTtsCheckBoxStatus: 未读取到配置Bean创建新实例");
} bean = new ThoughtfulServiceBean();
}
// 原有方法 boolean useMainOpen = bean.isEnableUsePowerTts();
public void onEnableUsePowerTts(View view) { boolean chargeMainOpen = bean.isEnableChargeTts();
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); cbUsePowerTts.setChecked(useMainOpen);
if (thoughtfulServiceBean == null) { cbChargeTts.setChecked(chargeMainOpen);
thoughtfulServiceBean = new ThoughtfulServiceBean(); cbUseageTtsBattary.setChecked(bean.isEnableUseageTtsWithBattary());
} cbChargeTtsBattary.setChecked(bean.isEnableChargeTtsWithBattary());
thoughtfulServiceBean.setIsEnableUsePowerTts(((CheckBox)view).isChecked()); cbUseageTtsBattary.setEnabled(useMainOpen);
ThoughtfulServiceBean.saveBean(this, thoughtfulServiceBean); cbChargeTtsBattary.setEnabled(chargeMainOpen);
}
// 新增用电TTS加入电量提醒 LogUtils.d(TAG, "initTtsCheckBoxStatus: 主开关状态-用电TTS" + useMainOpen + " 充电TTS" + chargeMainOpen);
public void onEnableUseageTtsWithBattary(View view) { LogUtils.d(TAG, "initTtsCheckBoxStatus: TTS复选框状态初始化完成");
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); }
if (thoughtfulServiceBean == null) {
thoughtfulServiceBean = new ThoughtfulServiceBean();
}
thoughtfulServiceBean.setIsEnableUseageTtsWithBattary(((CheckBox)view).isChecked());
ThoughtfulServiceBean.saveBean(this, thoughtfulServiceBean);
}
// 新增充电TTS加入电量提醒 // ======================== 事件响应区 =========================
public void onEnableChargeTtsWithBattary(View view) { /**
ThoughtfulServiceBean thoughtfulServiceBean = ThoughtfulServiceBean.loadBean(this, ThoughtfulServiceBean.class); * 悬浮窗权限检查入口
if (thoughtfulServiceBean == null) { */
thoughtfulServiceBean = new ThoughtfulServiceBean(); public void onCheckTTSDrawOverlaysPermission(View view) {
} LogUtils.d(TAG, "onCheckTTSDrawOverlaysPermission: 触发悬浮窗权限检查");
thoughtfulServiceBean.setIsEnableChargeTtsWithBattary(((CheckBox)view).isChecked()); canDrawOverlays();
ThoughtfulServiceBean.saveBean(this, thoughtfulServiceBean); }
}
/** /**
* 用电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();
} }
@@ -170,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,
@@ -188,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

@@ -61,14 +61,33 @@
android:text="用电提醒启用时的TTS贴心服务" android:text="用电提醒启用时的TTS贴心服务"
android:onClick="onEnableUsePowerTts" android:onClick="onEnableUsePowerTts"
android:id="@+id/activitysettingsCheckBox1"/> android:id="@+id/activitysettingsCheckBox1"/>
<CheckBox <LinearLayout
android:layout_width="wrap_content" android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="用电TTS加入电量提醒" android:gravity="center_vertical">
android:onClick="onEnableUseageTtsWithBattary"
android:id="@+id/activitysettingsCheckBox3"/> <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"
@@ -76,14 +95,33 @@
android:text="充电提醒启用时的TTS贴心服务" android:text="充电提醒启用时的TTS贴心服务"
android:onClick="onEnableChargeTts" android:onClick="onEnableChargeTts"
android:id="@+id/activitysettingsCheckBox2"/> android:id="@+id/activitysettingsCheckBox2"/>
<CheckBox <LinearLayout
android:layout_width="wrap_content" android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="充电TTS加入电量提醒" android:gravity="center_vertical">
android:onClick="onEnableChargeTtsWithBattary"
android:id="@+id/activitysettingsCheckBox4"/> <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>