Xamarin Forms应用关闭后无法显示通知问题求助
修复方案
1. 现有代码核心错误点
- AlarmManager配置完全缺失:你目前MainActivity里的AlarmManager相关代码是注释状态,相当于只启动了普通后台服务,Android 11之后普通后台服务在app被杀死后会被系统直接回收,根本无法持续运行
- BroadcastReceiver注册冲突:你同时在代码里动态注册了BackgroundReceiver,又在Manifest里静态注册了这个Receiver,还指定了
android:process=":remote"跑在独立进程,Xamarin.Forms的Device类API跨进程调用会失效,你的Timer和通知逻辑自然无法正常触发 - 通知通道ID不匹配:你前台服务创建的通知通道ID是
10121,但是用LocalNotification插件发通知时指定的ChannelId是General,两个ID不一致,发送的通知找不到对应通道,当然不会展示 - WakeLock使用错误:你在BroadcastReceiver的OnReceive里启动了循环Timer,然后直接释放了WakeLock,Timer还没开始运行WakeLock就已经失效,系统很快会进入休眠,逻辑直接中断
- 前台服务启动方式错误:Android 8.0及以上启动前台服务必须用
StartForegroundService,你现在用的是普通的StartService,调用后5秒内不调用StartForeground的话系统会直接杀死服务并报错
2. 分步修复步骤
第一步:修正BroadcastReceiver配置
删掉Manifest里Receiver的android:process=":remote"属性,同时删掉MainActivity里动态注册Receiver的代码,只用静态注册即可,避免跨进程调用问题:
<receiver android:name=".BackgroundReceiver" android:enabled="true" android:exported="true" android:label="myproject" />
第二步:统一通知通道ID
要么把LocalNotification插件的ChannelId改成10121,要么把前台服务创建的通道ID改成General,保证两边ID一致:
// 通知插件调用时修改 .WithAndroidOptions((android) => android .WithAutoCancel(true) .WithChannelId("10121") // 和前台服务的通道ID保持统一 .WithPriority(Plugin.LocalNotification.NotificationPriority.High) .Build())
第三步:正确启动前台服务
MainActivity里的服务启动逻辑替换为:
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O) { StartForegroundService(new Intent(this, typeof(PeriodicService))); } else { StartService(new Intent(this, typeof(PeriodicService))); }
第四步:补全AlarmManager循环触发逻辑
把MainActivity里注释的AlarmManager代码放开,调整为循环触发配置:
Intent alarmIntent = new Intent(Application.Context, typeof(BackgroundReceiver)); // Android 12+必须加Immutable flag PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable); AlarmManager alarmManager = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService); // Android 6.0+低电模式下最小触发间隔是15分钟,设置更小间隔会被系统自动拉长 long interval = 15 * 60 * 1000; long triggerTime = SystemClock.ElapsedRealtime() + interval; alarmManager.SetInexactRepeating(AlarmType.ElapsedRealtimeWakeup, triggerTime, interval, pendingIntent);
第五步:修正WakeLock逻辑
如果要保留Timer,把WakeLock的释放逻辑放到Timer停止的分支中,或者直接去掉Timer,每次Alarm触发时执行一次通知逻辑即可,避免后台长时间运行被系统查杀。
3. 小米设备专属配置
除了你已经开启的自启动、无电池限制,还需要完成两个设置:
- 进入应用通知设置,打开总通知开关,同时打开对应通道的悬浮通知、锁屏通知权限
- 关闭小米神隐模式对该应用的限制,神隐模式会强制查杀第三方后台服务
内容的提问来源于stack exchange,提问作者Judson Abraham
相关产品推荐
相关产品推荐

