运行 BroadcastReceiver 即使应用程序从最近的列表中被刷出

Run BroadcastReceiver even when app is swiped out from recent list

我正在使用 C# 在 Xamarin Android 上制作一个提醒应用程序。目前推送通知时,如果应用被刷出,我将收不到通知。

我见过很多这样的问题,但是 none 对我有帮助。

这是我的 BroadCastReceiver:

using Android.App;
using Android.Content;
using Newtonsoft.Json;
using ReminderApp.HelperRepository;
using System;
using ReminderApp.Models;
using Android.Graphics;
using Android.Support.V4.Content;
using Android.Media;

namespace ReminderApp.Notifications
{
    [BroadcastReceiver(Enabled = true)]
    public class ReminderNotifications : BroadcastReceiver
    {
        Reminder reminder;
        public ReminderNotifications()
        {
        }

        public override void OnReceive(Context context, Intent intent)
        {
            string CHANNEL_ID = "dan51";

            var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Max)
            {
                Description = "Firebase Cloud Messages appear in this channel"
            };

            long[] urgentVibrationPattern = { 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100, 100 };

            var alarmAttributes = new AudioAttributes.Builder()
                .SetContentType(AudioContentType.Sonification)
                .SetUsage(AudioUsageKind.Notification).Build();

            Android.Net.Uri infoAlarmUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);

            channel.EnableLights(true);
            channel.LightColor = Color.Red;
            channel.SetSound(infoAlarmUri, alarmAttributes);
            channel.EnableVibration(true);
            channel.SetVibrationPattern(urgentVibrationPattern);
            channel.SetBypassDnd(true);
            channel.LockscreenVisibility = NotificationVisibility.Public;

            string date = intent.GetStringExtra("date");
            string time = intent.GetStringExtra("time");


            reminder = ReminderHelper.SelectReminderByDateAndTime(context, date, time);
            if (reminder != null)
            {
                int NOTIFY_ID = 0 + new Random().Next();
                Intent newIntent = new Intent(context, typeof(ReminderContent));
                newIntent.PutExtra("reminder", JsonConvert.SerializeObject(reminder));

                Android.Support.V4.App.TaskStackBuilder stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(context);
                stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(ReminderContent)));
                stackBuilder.AddNextIntent(newIntent);

                PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);
                Bitmap icon = BitmapFactory.DecodeResource(context.Resources, Resource.Drawable.new_noti_celeb);

                Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID)
                .SetAutoCancel(true)
                .SetContentIntent(resultPendingIntent)
                .SetContentTitle("Reminder!!")
                .SetSmallIcon(Resource.Drawable.new_noti_celeb)
                .SetLargeIcon(icon)
                .SetColor(ContextCompat.GetColor(context, Resource.Color.material_deep_teal_500))
                .SetContentText("Click for details..")
                .SetVisibility(NotificationVisibility.Public)
                .SetDeleteIntent(resultPendingIntent);
                NotificationManager notificationManager = (NotificationManager)context.GetSystemService(Context.NotificationService);
                notificationManager.CreateNotificationChannel(channel);
                notificationManager.Notify(NOTIFY_ID, builder.Build());
            }
            if (reminder != null)
            {
                MediaPlayer player = MediaPlayer.Create(context, Resource.Drawable.notification_sound);
                player.Start();
            }
        }
    }
}

这是我的代码,用于在添加提醒时启动计时器直到收到通知:

public void ScheduleReminder(Reminder reminder)
        {
            AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
            Intent myIntent;
            PendingIntent pendingIntent;
            myIntent = new Intent(this, typeof(ReminderNotifications));
            myIntent.PutExtra("date", reminder.Date);
            myIntent.PutExtra("time", reminder.Time);

            var t = reminder.Time.Split(':');
            var ampm = t[1].Split(' ')[1];
            var hrr = Convert.ToDouble(t[0]);
            var min = Convert.ToDouble(t[1].Split(' ')[0]);

            string dateString = Convert.ToString(reminder.Date + " " + hrr + ":" + min + ":00 " + ampm);

            DateTimeOffset dateOffsetValue = DateTimeOffset.Parse(dateString);
            var millisec = dateOffsetValue.ToUnixTimeMilliseconds();

            pendingIntent = PendingIntent.GetBroadcast(this, new Random().Next(), myIntent, 0);
            manager.Set(AlarmType.RtcWakeup, millisec, pendingIntent);
        }

感谢任何帮助!

这对我有用:

using Android.App;
using Android.Content;
using Newtonsoft.Json;
using ReminderApp.HelperRepository;
using System;
using ReminderApp.Models;
using Android.Graphics;
using Android.Support.V4.Content;
using Android.Media;
using Android.OS;

namespace ReminderApp.Notifications
{
    [Service]
    public class ReminderNotifications : Service
    {
        Reminder reminder;
        public ReminderNotifications()
        {
        }

        public override IBinder OnBind(Intent intent)
        {
            throw new NotImplementedException();
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            string CHANNEL_ID = "dan51";

            var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Max)
            {
                Description = "Firebase Cloud Messages appear in this channel"
            };

            long[] urgentVibrationPattern = { 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100, 100 };

            var alarmAttributes = new AudioAttributes.Builder()
                .SetContentType(AudioContentType.Sonification)
                .SetUsage(AudioUsageKind.Notification).Build();

            Android.Net.Uri infoAlarmUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);

            channel.EnableLights(true);
            channel.LightColor = Color.Red;
            channel.SetSound(infoAlarmUri, alarmAttributes);
            channel.EnableVibration(true);
            channel.SetVibrationPattern(urgentVibrationPattern);
            channel.SetBypassDnd(true);
            channel.LockscreenVisibility = NotificationVisibility.Public;

            string date = intent.GetStringExtra("date");
            string time = intent.GetStringExtra("time");


            reminder = ReminderHelper.SelectReminderByDateAndTime(this, date, time);
            if (reminder != null)
            {
                int NOTIFY_ID = 0 + new Random().Next();
                Intent newIntent = new Intent(this, typeof(ReminderContent));
                newIntent.PutExtra("reminder", JsonConvert.SerializeObject(reminder));

                Android.Support.V4.App.TaskStackBuilder stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(this);
                stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(ReminderContent)));
                stackBuilder.AddNextIntent(newIntent);

                PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);
                Bitmap icon = BitmapFactory.DecodeResource(this.Resources, Resource.Drawable.new_noti_celeb);

                Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
                .SetAutoCancel(true)
                .SetContentIntent(resultPendingIntent)
                .SetContentTitle("Reminder!!")
                .SetSmallIcon(Resource.Drawable.new_noti_celeb)
                .SetLargeIcon(icon)
                .SetColor(ContextCompat.GetColor(this, Resource.Color.material_deep_teal_500))
                .SetContentText("Click for details..")
                .SetVisibility(NotificationVisibility.Public)
                .SetDeleteIntent(resultPendingIntent);
                NotificationManager notificationManager = (NotificationManager)this.GetSystemService(Context.NotificationService);
                notificationManager.CreateNotificationChannel(channel);
                notificationManager.Notify(NOTIFY_ID, builder.Build());

                PowerManager pm = (PowerManager)this.GetSystemService(Context.PowerService);
                bool isScreenOn = pm.IsInteractive;
                if (!isScreenOn)
                {
                    PowerManager.WakeLock wl = pm.NewWakeLock(WakeLockFlags.ScreenDim | WakeLockFlags.AcquireCausesWakeup, "myApp:notificationLock");
                    wl.Acquire(1);
                }
                MediaPlayer player = MediaPlayer.Create(this, Resource.Drawable.notification_sound);
                player.Start();
            }
            return StartCommandResult.NotSticky;
        }
    }
}

在我的 ScheduleReminder 函数中,我将 GetBroadcast 更改为 GetService!

唯一的问题是它在推送通知之前有 30 秒的延迟。如果谁有更好的解决办法,请post吧!