You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在设备充电且电量达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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:14:51