Xamarin.Android本地通知BootReceiver设备重启后不工作问题求助
问题排查及修复方案
- 首先修复组件路径不匹配的问题
你Manifest里注册的Receiver和Service路径和代码里声明的不一致:
- Manifest里Receiver路径是
com.mivs.notificationtest.app.RebootReceiver,但代码[BroadcastReceiver]属性里的Name是com.mivs.notificationtest.RebootReceiver,少了.app后缀 - Manifest里Service路径是
com.mivs.notificationtest.app.RebootService,代码[Service]属性里的Name是com.mivs.notificationtest.RebootService,同样少了.app后缀
系统找不到对应组件,自然无法触发重启广播接收逻辑,两边路径改成完全一致即可。
- 首先修复组件路径不匹配的问题
- 适配Android 8.0+的后台服务启动规则
你的测试设备是Android 9,已经禁止后台直接调用StartService启动普通服务,需要做两处修改: - Receiver里启动服务的代码改成:
if (Build.VERSION.SdkInt >= BuildVersionCodes.O) { context.StartForegroundService(serviceIntent); } else { context.StartService(serviceIntent); }- 在
RebootService的OnStartCommand方法里,5秒内调用StartForeground展示前台服务通知,否则系统会直接销毁服务并抛异常:
// 先创建通知渠道(Android 8.0+要求) const string channelId = "reboot_service_channel"; if (Build.VERSION.SdkInt >= BuildVersionCodes.O) { var channel = new NotificationChannel(channelId, "重启服务通知", NotificationImportance.Low); var notificationManager = GetSystemService(NotificationService).JavaCast<NotificationManager>(); notificationManager.CreateNotificationChannel(channel); } // 构建前台通知 var notification = new NotificationCompat.Builder(this, channelId) .SetContentTitle("后台服务运行中") .SetContentText("用于定时通知触发") .SetSmallIcon(Resource.Mipmap.ic_launcher) .Build(); // 启动前台服务,id不能为0 StartForeground(1001, notification);- 适配Android 8.0+的后台服务启动规则
- 修复AlarmManager的定时精度问题
Android 6.0及以上系统引入低电耗模式,普通Set方法的闹钟会被系统延迟触发,你要把闹钟设置逻辑改成:
注意要把if (Build.VERSION.SdkInt >= BuildVersionCodes.M) { alarmManager.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, millisec, pendingIntent); } else if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat) { alarmManager.SetExact(AlarmType.RtcWakeup, millisec, pendingIntent); } else { alarmManager.Set(AlarmType.RtcWakeup, millisec, pendingIntent); }AlarmType.Rtc改成AlarmType.RtcWakeup,才能保证设备休眠时也能唤醒触发闹钟。- 修复AlarmManager的定时精度问题
- 增加日期合法性判断
你当前写死了月日为9月29日,如果重启时当前时间已经过了当天15:35,设置的就是过去时间的闹钟,不会按预期触发,建议加判断:
if(dt < DateTime.Now) { dt = dt.AddDays(1); // 或者按你的业务逻辑调整到下一个触发时间 }- 增加日期合法性判断
- 额外适配排查点
- 先手动打开一次应用再重启测试:Android 3.1之后,从未被用户手动启动过的应用会被标记为停止状态,无法接收BOOT_COMPLETED广播
- 引导用户把应用加入系统电池优化白名单:LG系统自带电池管理策略,会禁止非白名单应用的后台广播和服务运行,你可以调用以下代码跳转设置页:
if (Build.VERSION.SdkInt >= BuildVersionCodes.M) { var intent = new Intent(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations); intent.SetData(Android.Net.Uri.Parse($"package:{PackageName}")); StartActivity(intent); }
内容的提问来源于stack exchange,提问作者Michał Schmude
相关产品推荐
相关产品推荐

