本地通知未在Android 10中触发 [英] Local notification not triggering in Android 10
问题描述
我正在使用xamarin.forms应用程序,并且正在使用警报管理器设置本地通知.在Android 版本8和9 上可以正常触发,但在 Android 10 上却不能触发.
I am working on xamarin.forms app and I am setting local notification using alarm manager. It is triggering fine on android version 8 and 9 but somehow it's not triggering in Android 10.
在 Android 10 的android设备日志中,我知道了
In android device logs for Android 10, I got
07-22 15:00:06.612 Samsung SM-M205F Verbose 4185 SamsungAlarmManager Sending to uid : 10244 action=null alarm=Alarm{a757a70 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 )
我已经设法在应用程序运行时收到通知,但是现在在关闭应用程序时不会触发通知.
I have managed to get notification when app is running, but now notifications are not firing when app is closed.
注意::我制作了一个可以在Android 10上正常运行的示例,该示例在运行或关闭应用程序时都会触发通知.我不必使用前台服务.(我在工作项目中使用了相同的方法).所以我的工作项目出了点问题,我无法弄清.
Note : I have made a sample which is working just fine with Android 10, Notifications are triggering when app is running or closed in the sample. I don't have to use foreground service. (I have used same approach in my work project). So There is something wrong in my work project which I am not able to figure out.
这是 Android设备日志,当应用关闭且通知即将触发时,
Here is the Android device logs when app is closed and notifications are about to trigger,
如果有人可以帮助您!
If someone can help !
推荐答案
关闭应用程序(包括警报管理器)时,所有代码将被冻结.如果您希望它仍然存在,我们可以使用前台服务: https://docs.microsoft.com/zh-cn/xamarin/android/app-fundamentals/services/foreground-services 这可能有点过时了,这是我创建通知的方法:
All of the code will be frozen when your application is closed including the alarm manager. If you want it still alive, we could use foreground service: https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/services/foreground-services This may be a little out of date, here is my approach to create the notification:
[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.
Update
Now you don't need to use alarmmanager any more .
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());
}
}
这篇关于本地通知未在Android 10中触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!