.NET Maui Android BroadcastReceiver无接收问题求助(适配Android 10)
Android 10 静态注册充电广播失效的问题分析与解决方案
问题根源
Android 8.0(API 26)起,系统为优化后台功耗,对隐式广播的静态注册做了严格限制。Intent.ACTION_POWER_CONNECTED、Intent.ACTION_POWER_DISCONNECTED、Intent.ACTION_DOCK_EVENT这类常用隐式广播均不在系统白名单内,因此静态注册的BroadcastReceiver在应用未运行时无法被触发,Android 10完全遵循此规则。
另外,Intent.ACTION_BATTERY_CHANGED属于粘性广播,本身就不支持静态注册,只能通过动态注册接收。
修正方案
要实现应用未运行时也能监听充电状态,可采用以下两种方案:
方案1:前台服务 + 动态注册广播
该方案能保证实时监听,步骤如下:
- 在
AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- 可选,用于开机自启服务 -->
- 创建前台服务,在服务内部动态注册广播接收器:
public class ChargeMonitorService : Service { private PowerConnectedBroadcastReceiver _receiver; public override void OnCreate() { base.OnCreate(); // 动态注册充电相关广播 _receiver = new PowerConnectedBroadcastReceiver(); var filter = new IntentFilter(); filter.AddAction(Intent.ActionPowerConnected); filter.AddAction(Intent.ActionPowerDisconnected); filter.AddAction(Intent.ActionDockEvent); filter.AddAction(Intent.ActionBatteryChanged); RegisterReceiver(_receiver, filter); // 启动前台服务,避免被系统后台回收 var notification = new Notification.Builder(this, "charge_monitor_channel") .SetContentTitle("充电状态监听中") .SetContentText("正在监控设备充电状态") .SetSmallIcon(Resource.Drawable.ic_notification) .Build(); StartForeground(1001, notification); } public override void OnDestroy() { base.OnDestroy(); // 服务销毁时注销广播 UnregisterReceiver(_receiver); } public override IBinder OnBind(Intent intent) => null; }
- 在
AndroidManifest.xml中注册服务:
<service android:name=".ChargeMonitorService" android:foregroundServiceType="dataSync" />
- 触发服务启动:可在应用首次启动时调用
StartService启动服务,或实现一个监听RECEIVE_BOOT_COMPLETED的广播接收器,实现开机自启服务。
方案2:使用WorkManager定期检查电池状态
如果对实时性要求不高,可通过WorkManager周期性检查电池状态:
- 创建Worker类处理检查逻辑:
public class ChargeCheckWorker : Worker { public ChargeCheckWorker(Context context, WorkerParameters params) : base(context, params) { } public override Result DoWork() { // 获取电池管理服务 var batteryManager = (BatteryManager)ApplicationContext.GetSystemService(Context.BatteryService); int chargeState = batteryManager.GetIntProperty(BatteryManager.PropertyStatus); bool isCharging = chargeState == BatteryManager.BatteryStatusCharging || chargeState == BatteryManager.BatteryStatusFull; // 处理充电状态逻辑 if (isCharging) { Console.WriteLine("设备正在充电"); } else { Console.WriteLine("设备未在充电"); } return Result.Success(); } }
- 调度周期性任务:
// 每15分钟执行一次(WorkManager最短周期限制为15分钟) var request = new PeriodicWorkRequest.Builder(typeof(ChargeCheckWorker), 15, TimeUnit.Minutes) .Build(); WorkManager.Instance.Enqueue(request);
额外注意事项
- 无需
BATTERY_STATS权限:监听充电状态相关广播或获取电池状态,不需要申请该权限,可从清单中移除。 - Android 12+适配:前台服务需指定正确的
foregroundServiceType,比如dataSync或health,避免权限报错。
内容的提问来源于stack exchange,提问作者Manfred Zimmer
相关产品推荐
相关产品推荐

