本地通知未在 Android 10 中触发
Posted
技术标签:
【中文标题】本地通知未在 Android 10 中触发【英文标题】:Local notification not triggering in Android 10 【发布时间】:2020-07-15 07:07:05 【问题描述】:我正在开发 xamarin.forms 应用程序,并且正在使用警报管理器设置本地通知。它在 android version 8 和 9 上触发良好,但不知何故在 Android 10 中没有触发。
在 Android 10 的 android 设备日志中,我得到了
07-22 15:00:06.612 Samsung SM-M205F Verbose 4185 SamsungAlarmManager Sending to uid : 10244 action=null alarm=Alarma757a70 type 0 when 1595410200000 com.MyApp.andr.connect
07-22 15:00:06.613 Samsung SM-M205F Warning 4185 BroadcastQueue Unable to launch app com.MyApp.andr.connect/10244 for broadcast Intent flg=0x14 cmp=com.MyApp.andr.connect/crc640e87e93c5dbd1629.AlarmReceiver (has extras) : process is bad
更新(Android 10仍然存在问题)
我已经设法在应用程序运行时收到通知,但现在当应用程序关闭时通知不会触发。
注意:我制作了一个在 Android 10 上运行良好的示例,当应用在示例中运行或关闭时会触发通知。我不必使用前台服务。 (我在我的工作项目中使用了相同的方法)。所以我的工作项目有问题,我无法弄清楚。
这是当应用关闭且通知即将触发时的Android设备日志,
如果有人可以帮忙!
【问题讨论】:
【参考方案1】:当您的应用程序关闭时,包括警报管理器在内的所有代码都将被冻结。 如果您希望它还活着,我们可以使用前台服务: https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/services/foreground-services 这可能有点过时了,这是我创建通知的方法:
[Service]
public class SampleService : Service
public static string CHANNEL_ID = "com.channelid";
public static string CHANNEL_NAME = "com.channelname";
public override void OnCreate()
base.OnCreate();
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
registerNotificationChannel();
int notifyId = (int)JavaSystem.CurrentTimeMillis();
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
mBuilder.SetSmallIcon(Resource.Mipmap.ic_launcher);
if (Build.VERSION.SdkInt < BuildVersionCodes.N)
mBuilder.SetContentTitle("app name");
StartForeground(notifyId, mBuilder.Build());
return StartCommandResult.Sticky;
private void registerNotificationChannel()
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
NotificationManager mNotificationManager = (NotificationManager)GetSystemService(Context.NotificationService);
NotificationChannel notificationChannel = mNotificationManager.GetNotificationChannel(CHANNEL_ID);
if (notificationChannel == null)
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
CHANNEL_NAME, NotificationImportance.High);
channel.EnableLights(true);
channel.LightColor = Color.Red;
channel.LockscreenVisibility = NotificationVisibility.Public;
mNotificationManager.CreateNotificationChannel(channel);
public override IBinder OnBind(Intent intent)
throw new NotImplementedException();
更新
现在你不需要再使用alarmmanager了。
在 MainActivity 中
public static MainActivity Instance get; set;
protected override void OnCreate(Bundle savedInstanceState)
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Instance = this;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
在 AlarmAndNotificationService 中
void IAlarmAndNotificationService.ScheduleLocalNotification(string notificationTitle, string notificationMessage, DateTime specificDateTime, TimeSpan timeSpan, int notificationId, NotificationInterval interval)
// start service here
Intent s = new Intent(MainActivity.Instance, typeof(SampleService));
MainActivity.Instance.StartService(s);
在 SampleService 中
public class SampleService : Service
private Handler handler;
private Action runnable;
private bool isStarted;
private int DELAY_BETWEEN_LOG_MESSAGES = 5000; // set time span
private int NOTIFICATION_SERVICE_ID = 1001;
private int NOTIFICATION_AlARM_ID = 1002;
private string NOTIFICATION_CHANNEL_ID = "1003";
private string NOTIFICATION_CHANNEL_NAME = "MyChannel";
public override void OnCreate()
base.OnCreate();
handler = new Handler();
//here is what you want to do always, i just want to push a notification every 5 seconds here
runnable = new Action(() =>
if (isStarted)
DispatchNotificationThatAlarmIsGenerated("I'm running");
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
);
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
if (isStarted)
// service is already started
else
CreateNotificationChannel();
DispatchNotificationThatServiceIsRunning();
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
isStarted = true;
return StartCommandResult.Sticky;
public override void OnTaskRemoved(Intent rootIntent)
//base.OnTaskRemoved(rootIntent);
public override IBinder OnBind(Intent intent)
// Return null because this is a pure started service. A hybrid service would return a binder that would
// allow access to the GetFormattedStamp() method.
return null;
public override void OnDestroy()
// Stop the handler.
handler.RemoveCallbacks(runnable);
// Remove the notification from the status bar.
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Cancel(NOTIFICATION_SERVICE_ID);
isStarted = false;
base.OnDestroy();
private void CreateNotificationChannel()
//Notification Channel
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationImportance.Max);
notificationChannel.EnableLights(true);
notificationChannel.EnableVibration(true);
notificationChannel.SetVibrationPattern(new long[] 100, 200, 300, 400, 500, 400, 300, 200, 400 );
NotificationManager notificationManager = (NotificationManager)this.GetSystemService(Context.NotificationService);
notificationManager.CreateNotificationChannel(notificationChannel);
//start a foreground notification to keep alive
private void DispatchNotificationThatServiceIsRunning()
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetDefaults((int)NotificationDefaults.All)
.SetSmallIcon(Resource.Drawable.icon)
.SetVibrate(new long[] 100, 200, 300, 400, 500, 400, 300, 200, 400 )
.SetSound(null)
.SetChannelId(NOTIFICATION_CHANNEL_ID)
.SetPriority(NotificationCompat.PriorityDefault)
.SetAutoCancel(false)
.SetContentTitle("Mobile")
.SetContentText("My service started")
.SetOngoing(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.From(this);
StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
//every 5 seconds push a notificaition
private void DispatchNotificationThatAlarmIsGenerated(string message)
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
Notification.Builder notificationBuilder = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.icon)
.SetContentTitle("Alarm")
.SetContentText(message)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(NOTIFICATION_AlARM_ID, notificationBuilder.Build());
【讨论】:
即使应用程序在前台运行,我也没有收到通知。 您可以在另一台设备(或模拟器)上测试该应用程序。在某些特定设备上可能会出现一些未知问题。 我已经设法在应用程序使用 BroadcastReceiver 运行时收到通知。但是当应用程序关闭时它不会触发。所以我认为上述解决方案可以提供帮助。如果我使用 ForegroundService 触发通知,是否需要 BroadcastReceiver 以及如何设置通知以在特定日期和时间触发? 当然BroadcastReceiver
还是需要的。具体时间如何启动服务,可以查看***.com/questions/39092274/…
我做了一个使用alarmmanager触发本地通知的示例项目,它在应用程序运行和关闭时工作得很好。我什至不必在示例项目中使用前台服务。所以这可能是我工作项目的其他问题。当我解决我的工作项目中的问题时,我会在这里提供更新。以上是关于本地通知未在 Android 10 中触发的主要内容,如果未能解决你的问题,请参考以下文章