如何在设备充电且电量达100%(或95%以上)时启动Activity?
嘿,你已经迈出了关键的第一步——搞定充电插入的广播接收!不过要实现持续监控电量直到达标(95%+),还得结合后台任务调度和电量状态监听,同时适配Android的后台限制(毕竟现在系统对后台操作管得越来越严了)。下面给你一套靠谱的实现方案:
核心思路:用WorkManager实现后台持续监控(推荐)
WorkManager是Google官方推荐的后台任务管理工具,能完美适配不同Android版本的后台规则,就算应用被关闭甚至设备重启(加个开机广播就行),也能正常调度任务,完全符合你的需求。
1. 写一个Worker类负责检查电量
这个Worker会定期检查充电状态和电量,达标就启动目标Activity,没达标就继续重试:
class BatteryCheckWorker( context: Context, params: WorkerParameters ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { val batteryManager = applicationContext.getSystemService(Context.BATTERY_SERVICE) as BatteryManager // 获取当前电量百分比 val currentLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) // 判断是否在充电 val isCharging = batteryManager.isCharging if (isCharging && currentLevel >= 95) { // 后台启动Activity必须加FLAG_ACTIVITY_NEW_TASK val launchIntent = Intent(applicationContext, TargetActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } applicationContext.startActivity(launchIntent) return Result.success() // 任务完成,停止重试 } else { // 15分钟后再检查一次(间隔可以根据需求调整) return Result.retry() } } }
2. 在充电广播接收器中触发Worker
当检测到充电器插入时,就调度Worker开始监控;拔掉充电器就取消任务,避免无效运行:
class ChargingReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { context ?: return when (intent?.action) { Intent.ACTION_POWER_CONNECTED -> { // 设置任务约束:只在充电时运行 val constraints = Constraints.Builder() .setRequiresCharging(true) .build() // 调度周期性检查任务 val checkRequest = PeriodicWorkRequestBuilder<BatteryCheckWorker>(15, TimeUnit.MINUTES) .setConstraints(constraints) .build() // 用唯一任务名,避免重复调度 WorkManager.getInstance(context).enqueueUniquePeriodicWork( "BatteryMonitorWork", ExistingPeriodicWorkPolicy.REPLACE, checkRequest ) } Intent.ACTION_POWER_DISCONNECTED -> { // 拔掉充电器,取消监控任务 WorkManager.getInstance(context).cancelUniqueWork("BatteryMonitorWork") } } } }
3. 注册组件和权限
在AndroidManifest.xml里注册广播接收器和添加必要权限:
<!-- 注册充电广播接收器 --> <receiver android:name=".ChargingReceiver"> <intent-filter> <action android:name="android.intent.action.ACTION_POWER_CONNECTED" /> <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" /> </intent-filter> </receiver> <!-- 必要权限 --> <uses-permission android:name="android.permission.BATTERY_STATS" /> <!-- 可选:开机后自动恢复监控 --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
4. 额外优化:实时监听电量变化(替代轮询)
如果不想定期轮询,也可以在Worker里动态注册电量变化广播,实时监听电量达标情况(注意Android 8.0+静态注册电量广播无效,只能动态注册):
override suspend fun doWork(): Result { var isCompleted = false val batteryReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val level = intent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1 val scale = intent?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1 val currentLevel = (level * 100) / scale val isCharging = intent?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) == BatteryManager.BATTERY_STATUS_CHARGING if (isCharging && currentLevel >= 95) { val launchIntent = Intent(context, TargetActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } context?.startActivity(launchIntent) context?.unregisterReceiver(this) isCompleted = true cancelWorkById(id) } } } // 动态注册电量广播 applicationContext.registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) // 设置超时:2小时后还没达标就停止监控 delay(2 * 60 * 60 * 1000) if (!isCompleted) { applicationContext.unregisterReceiver(batteryReceiver) } return if (isCompleted) Result.success() else Result.failure() }
关键注意事项
- 后台启动Activity限制:Android 10+(API 29)之后,后台直接启动Activity有严格限制,除非用户最近和应用有交互,或者应用有前台服务。如果需要在完全后台场景下启动,建议引导用户关闭应用的电量优化,或者申请
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限。 - 测试技巧:可以用adb命令模拟充电和电量变化,快速验证功能:
# 模拟连接充电器 adb shell dumpsys battery set ac 1 # 设置电量为96% adb shell dumpsys battery set level 96 # 恢复正常状态 adb shell dumpsys battery reset
这样就能实现你想要的效果:充电器插入后自动后台监控电量,达标就启动目标Activity,不管应用是打开还是关闭状态。
内容的提问来源于stack exchange,提问作者Dpedrinha
相关产品推荐
相关产品推荐

