应用退出最近列表后,ACTION_BATTERY_CHANGED广播接收器失效问题
解决Android应用完全退出后无法监听电池电量变化的问题
你的问题根源在于动态注册的BroadcastReceiver和Activity生命周期绑定——当应用完全退出,MainActivity被销毁时,这个接收器也会被系统自动注销(如果没手动注销还会引发内存泄漏),自然就收不到ACTION_BATTERY_CHANGED广播了。而且要注意,ACTION_BATTERY_CHANGED是系统特殊广播,不支持静态注册(在AndroidManifest.xml中声明接收器无效),所以得换个方案:用**前台服务(Foreground Service)**来托管广播接收器,让它在后台持续运行监听电量变化。
下面是具体的实现步骤和代码:
1. 创建前台服务托管广播接收器
前台服务的优先级更高,不容易被系统回收,而且从Android 8.0开始,后台服务会被限制,前台服务必须显示一个状态栏通知(这是系统强制要求)。
public class BatteryMonitorService extends Service { private BroadcastReceiver mBatInfoReceiver; @Override public void onCreate() { super.onCreate(); // 注册电池电量变化广播接收器 IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); mBatInfoReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int batteryLevel = intent.getIntExtra("level", 0); Toast.makeText(context, "当前电量:" + batteryLevel + "%", Toast.LENGTH_SHORT).show(); } }; registerReceiver(mBatInfoReceiver, batteryFilter); // 初始化前台服务通知(Android 8.0+必填) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 创建通知渠道 NotificationChannel channel = new NotificationChannel( "battery_monitor_channel", "电池监控", NotificationManager.IMPORTANCE_LOW ); NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); // 构建通知 Notification notification = new NotificationCompat.Builder(this, "battery_monitor_channel") .setSmallIcon(R.drawable.ic_battery) // 替换成你的应用图标 .setContentTitle("电池监控中") .setContentText("正在监听电量变化") .setPriority(NotificationCompat.PRIORITY_LOW) .build(); // 启动前台服务 startForeground(1, notification); } } @Override public void onDestroy() { super.onDestroy(); // 注销接收器,避免内存泄漏 if (mBatInfoReceiver != null) { unregisterReceiver(mBatInfoReceiver); } } @Nullable @Override public IBinder onBind(Intent intent) { return null; // 不需要绑定服务,返回null即可 } @Override public int onStartCommand(Intent intent, int flags, int startId) { // 服务被系统杀死后尝试自动重启 return START_STICKY; } }
2. 配置Manifest权限和服务声明
在AndroidManifest.xml中添加必要的权限和服务声明:
<!-- 前台服务权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- Android 13及以上需要通知权限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <application ...> <!-- 声明电池监控服务 --> <service android:name=".BatteryMonitorService" android:foregroundServiceType="dataSync" /> <!-- 指定服务类型,优化系统调度 --> ... </application>
3. 在Activity中启动前台服务
在你的MainActivity中启动服务,同时处理Android 13+的通知权限请求:
public class MainActivity extends AppCompatActivity { private static final int NOTIFICATION_PERMISSION_REQUEST_CODE = 1001; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 处理Android 13+的通知权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { requestPermissions( new String[]{Manifest.permission.POST_NOTIFICATIONS}, NOTIFICATION_PERMISSION_REQUEST_CODE ); } else { startBatteryMonitorService(); } } else { startBatteryMonitorService(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == NOTIFICATION_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startBatteryMonitorService(); } else { // 用户拒绝权限,提示无法正常监控电池 Toast.makeText(this, "需要通知权限才能启动电池监控", Toast.LENGTH_SHORT).show(); } } } private void startBatteryMonitorService() { Intent serviceIntent = new Intent(this, BatteryMonitorService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(serviceIntent); } else { startService(serviceIntent); } } }
注意事项
- 前台服务会在状态栏显示一个持续通知,这是系统强制要求,无法隐藏(除非你的应用拥有特殊系统权限)。
- 当不需要监控电量时,记得调用
stopService()或在Service中调用stopSelf()来停止服务,避免浪费资源。 START_STICKY返回值可以让服务在被系统回收后尝试重启,但不能保证100%重启,系统资源极度紧张时还是会被彻底杀死。
内容的提问来源于stack exchange,提问作者Prem Bharwani
相关产品推荐
相关产品推荐

