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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:15:05