如何在Android 14 Pixel设备应用中程序化控制Bedtime Mode?
在Google Pixel Android 14上程序化控制Bedtime Mode(非DnD)
需求明确:要在应用中程序化启用/禁用Bedtime Mode,支持设备待机状态运行,最终通过Home Assistant触发应用通知完成操作,设备为Google Pixel Android 14,可接受访问安全设置的方案。
已尝试的失败方案及原因
Settings.Secure.getInt(applicationContext.contentResolver, "accessibility_display_daltonizer_enabled"):该参数控制的是色彩校正功能,和Bedtime Mode完全无关import androidx.digitalwellbeing.DigitalWellbeingManager+getSystemService(Context.DIGITAL_WELLBEING_SERVICE) as DigitalWellbeingManager:这套API仅能读取Bedtime Mode的状态,没有修改权限;且依赖特定版本的Google Play Services,存在无法解决的兼容性问题
可行方案分析
方案一:直接操作安全设置(推荐)
Bedtime Mode在Pixel Android 14中属于数字健康模块,对应系统安全设置参数为digital_wellbeing_bedtime_mode_enabled,需要获取系统级的WRITE_SECURE_SETTINGS权限。
实现步骤:
- 申请权限:在
AndroidManifest.xml中添加权限声明<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> - 授予权限:该权限无法通过应用内弹窗请求,需通过ADB命令一次性授予
adb shell pm grant <你的应用包名> android.permission.WRITE_SECURE_SETTINGS - 代码控制状态:
// 启用Bedtime Mode Settings.Secure.putInt(applicationContext.contentResolver, "digital_wellbeing_bedtime_mode_enabled", 1) // 禁用Bedtime Mode Settings.Secure.putInt(applicationContext.contentResolver, "digital_wellbeing_bedtime_mode_enabled", 0) - 确保待机状态运行:
- 添加唤醒锁权限避免系统休眠:
<uses-permission android:name="android.permission.WAKE_LOCK" /> - 使用WorkManager调度任务,保证操作在后台/待机时也能执行:
实现Worker类:// 构建任务请求 val request = OneTimeWorkRequestBuilder<BedtimeModeWorker>().setInputData( workDataOf("enable" to true) // 传入启用/禁用标识 ).build() WorkManager.getInstance(context).enqueue(request)class BedtimeModeWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork(): Result { val enable = inputData.getBoolean("enable", false) Settings.Secure.putInt( applicationContext.contentResolver, "digital_wellbeing_bedtime_mode_enabled", if (enable) 1 else 0 ) return Result.success() } }
- 添加唤醒锁权限避免系统休眠:
方案二:模拟快速设置开关交互(备选)
通过AccessibilityService模拟点击快速设置中的Bedtime Mode开关,无需系统级权限,但需要用户手动开启辅助功能权限。
实现步骤:
- 创建AccessibilityService:
class BedtimeModeAccessibilityService : AccessibilityService() { override fun onAccessibilityEvent(event: AccessibilityEvent) { val root = rootInActiveWindow ?: return // 根据界面实际文本定位Bedtime Mode开关,英文系统是"Bedtime mode",中文是"就寝模式" val switchNode = root.findAccessibilityNodeInfoByText("Bedtime mode") switchNode?.performAction(AccessibilityNodeInfo.ACTION_CLICK) } override fun onInterrupt() {} } - 注册服务:在
AndroidManifest.xml中添加服务声明<service android:name=".BedtimeModeAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" /> </service> - 配置辅助服务参数:创建
res/xml/accessibility_service_config.xml<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canPerformGestures="true" android:description="@string/accessibility_desc" /> - 触发流程:接收Home Assistant通知后,打开快速设置界面,由辅助服务自动点击开关
val intent = Intent(Intent.ACTION_QUICK_SETTINGS) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intent)
方案三:调用系统设置Activity(不推荐)
系统Bedtime Mode的设置界面Activity为com.google.android.apps.wellbeing.settings.bedtime.BedtimeSettingsActivity,但无法直接传递参数控制状态,需模拟界面点击操作,效率远低于方案一,仅作为极端情况下的备选。
注意事项
- 方案一中的安全设置参数
digital_wellbeing_bedtime_mode_enabled是Pixel Android 14的特定参数,需在目标设备上测试确认有效性 - 要保证待机状态运行,需在设备电池设置中关闭应用的电池优化,避免被系统杀死
- Home Assistant可通过FCM发送通知,应用接收通知后触发对应的Bedtime Mode控制逻辑
内容的提问来源于stack exchange,提问作者Wip
相关产品推荐
相关产品推荐

