Android开发:Broadcast Receiver未触发电池80%/25%通知问题排查
电池电量提醒广播接收器无响应问题排查
我想要开发一款简单应用,在电池电量降至25%,或充电时电量达到80%及以上时提醒用户避免过充。尝试通过Manifest文件注册Broadcast Receiver实现,但电池达到对应电量时没有任何反应,以下是我的Receiver代码:
package com.example.batterymanager import android.app.NotificationManager import android.content.BroadcastReceiver import android.content.Context import android.content.Context.BATTERY_SERVICE import android.content.Context.NOTIFICATION_SERVICE import android.content.Intent import androidx.core.app.NotificationCompat class BatteryReceiver: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { fun show80Notification() { val notificationManager = context?.getSystemService(NOTIFICATION_SERVICE) as NotificationManager val notification = NotificationCompat.Builder(context, "channelID") .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("Battery at 80!") .setContentText("Your phone is at 80%! Stop charging it!") .setPriority(NotificationManager.IMPORTANCE_HIGH) .setAutoCancel(true) .build() notificationManager.notify(1, notification) } fun showLowNotification() { val notificationManager = context?.getSystemService(NOTIFICATION_SERVICE) as NotificationManager val notification = NotificationCompat.Builder(context, "channelID") .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("Battery low!") .setContentText("Your phone is at 25%! Charge it now!") .setPriority(NotificationManager.IMPORTANCE_HIGH) .setAutoCancel(true) .build() notificationManager.notify(1, notification) } when (context?.getSystemService(BATTERY_SERVICE)) { 80 -> { show80Notification() } 25 -> { showLowNotification() } } } }
核心错误点及修复方案
1. 错误的电量获取逻辑
context?.getSystemService(BATTERY_SERVICE) 返回的是BatteryManager对象,不是电池百分比数值,你的when语句永远不会匹配80或25,这是最根本的问题。
正确获取电量的方式是从广播Intent中提取数据:
val level = intent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1 val scale = intent?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1 val batteryPercent = if (scale > 0) (level * 100) / scale else 0
2. 静态广播接收器在Android 8.0+失效
从Android 8.0(API 26)开始,系统禁止静态注册ACTION_BATTERY_CHANGED这类隐式广播,你在Manifest中注册的接收器根本不会被触发。
修复:动态注册广播接收器
在Activity中注册/注销接收器,示例代码:
private lateinit var batteryReceiver: BatteryReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) batteryReceiver = BatteryReceiver() val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED) registerReceiver(batteryReceiver, filter) } override fun onDestroy() { super.onDestroy() unregisterReceiver(batteryReceiver) }
3. 未创建Android 8.0+通知渠道
Android 8.0及以上版本必须先创建通知渠道才能显示通知,你的代码直接使用channelID但未初始化渠道,即使触发逻辑也不会弹出通知。
添加渠道创建代码:
private fun createNotificationChannel(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val name = "Battery Alerts" val descriptionText = "Notifications for battery level warnings" val importance = NotificationManager.IMPORTANCE_HIGH val channel = NotificationChannel("channelID", name, importance).apply { description = descriptionText } val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } }
记得在显示通知前调用此方法。
4. 判断逻辑不完整
- 80%提醒需要判断设备是否处于充电状态,否则非充电场景下电量到80%也会触发提醒,不符合需求
- 25%提醒需明确电量阈值,且建议排除充电状态(避免充电时重复提醒)
- 通知ID重复会导致新通知覆盖旧通知,建议使用不同ID
完善后的onReceive逻辑:
override fun onReceive(context: Context?, intent: Intent?) { context?.let { ctx -> createNotificationChannel(ctx) val level = intent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1 val scale = intent?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1 val batteryPercent = if (scale > 0) (level * 100) / scale else 0 val isCharging = intent?.getIntExtra(BatteryManager.EXTRA_STATUS, -1)?.let { it == BatteryManager.BATTERY_STATUS_CHARGING || it == BatteryManager.BATTERY_STATUS_FULL } ?: false if (isCharging && batteryPercent >= 80) { show80Notification(ctx) } else if (!isCharging && batteryPercent <= 25) { showLowNotification(ctx) } } } private fun show80Notification(context: Context) { val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager val notification = NotificationCompat.Builder(context, "channelID") .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("Battery at 80%!") .setContentText("Stop charging to avoid overcharging.") .setPriority(NotificationManager.IMPORTANCE_HIGH) .setAutoCancel(true) .build() notificationManager.notify(1, notification) } private fun showLowNotification(context: Context) { val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager val notification = NotificationCompat.Builder(context, "channelID") .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("Battery Low!") .setContentText("Your battery is at 25%, please charge now.") .setPriority(NotificationManager.IMPORTANCE_HIGH) .setAutoCancel(true) .build() notificationManager.notify(2, notification) }
内容的提问来源于stack exchange,提问作者vukica
相关产品推荐
相关产品推荐

