From 5e2d0cf8fb7a157876da9f1fa24bc5f32c3a1761 Mon Sep 17 00:00:00 2001 From: David Britch Date: Fri, 12 Feb 2021 16:20:45 +0000 Subject: [PATCH] Backgrounded app updates. (#701) --- .../AlarmHandler.cs | 3 ++- .../AndroidNotificationManager.cs | 17 +++++++++++-- .../BootReceiver.cs | 19 +++++++++++++++ .../LocalNotifications.Android.csproj | 1 + .../Properties/AndroidManifest.xml | 5 ++-- .../LocalNotifications.iOS/AppDelegate.cs | 2 +- .../iOSNotificationReceiver.cs | 24 +++++++++++++++---- 7 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 LocalNotifications/LocalNotifications/LocalNotifications.Android/BootReceiver.cs diff --git a/LocalNotifications/LocalNotifications/LocalNotifications.Android/AlarmHandler.cs b/LocalNotifications/LocalNotifications/LocalNotifications.Android/AlarmHandler.cs index 9f5b4fd67..bee012411 100644 --- a/LocalNotifications/LocalNotifications/LocalNotifications.Android/AlarmHandler.cs +++ b/LocalNotifications/LocalNotifications/LocalNotifications.Android/AlarmHandler.cs @@ -12,7 +12,8 @@ namespace LocalNotifications.Droid string title = intent.GetStringExtra(AndroidNotificationManager.TitleKey); string message = intent.GetStringExtra(AndroidNotificationManager.MessageKey); - AndroidNotificationManager.Instance.Show(title, message); + AndroidNotificationManager manager = AndroidNotificationManager.Instance ?? new AndroidNotificationManager(); + manager.Show(title, message); } } } diff --git a/LocalNotifications/LocalNotifications/LocalNotifications.Android/AndroidNotificationManager.cs b/LocalNotifications/LocalNotifications/LocalNotifications.Android/AndroidNotificationManager.cs index 0d7c7beed..cd85c9e46 100644 --- a/LocalNotifications/LocalNotifications/LocalNotifications.Android/AndroidNotificationManager.cs +++ b/LocalNotifications/LocalNotifications/LocalNotifications.Android/AndroidNotificationManager.cs @@ -29,10 +29,15 @@ namespace LocalNotifications.Droid public static AndroidNotificationManager Instance { get; private set; } + public AndroidNotificationManager() => Initialize(); + public void Initialize() { - CreateNotificationChannel(); - Instance = this; + if (Instance == null) + { + CreateNotificationChannel(); + Instance = this; + } } public void SendNotification(string title, string message, DateTime? notifyTime = null) @@ -89,6 +94,14 @@ namespace LocalNotifications.Droid manager.Notify(messageId++, notification); } + public void DeleteNotification(int id) + { + Intent intent = new Intent(AndroidApp.Context, typeof(AlarmHandler)); + PendingIntent pendingIntent = PendingIntent.GetBroadcast(AndroidApp.Context, id, intent, PendingIntentFlags.CancelCurrent); + AlarmManager alarmManager = AndroidApp.Context.GetSystemService(Context.AlarmService) as AlarmManager; + alarmManager.Cancel(pendingIntent); + } + void CreateNotificationChannel() { manager = (NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService); diff --git a/LocalNotifications/LocalNotifications/LocalNotifications.Android/BootReceiver.cs b/LocalNotifications/LocalNotifications/LocalNotifications.Android/BootReceiver.cs new file mode 100644 index 000000000..ee7f3664c --- /dev/null +++ b/LocalNotifications/LocalNotifications/LocalNotifications.Android/BootReceiver.cs @@ -0,0 +1,19 @@ +using Android.App; +using Android.Content; + +namespace LocalNotifications.Droid +{ + [BroadcastReceiver(Enabled = true, Label = "Reboot complete receiver")] + [IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })] + public class BootReceiver : BroadcastReceiver + { + public override void OnReceive(Context context, Intent intent) + { + if (intent.Action == "android.intent.action.BOOT_COMPLETED") + { + // Recreate alarms + } + } + } +} + diff --git a/LocalNotifications/LocalNotifications/LocalNotifications.Android/LocalNotifications.Android.csproj b/LocalNotifications/LocalNotifications/LocalNotifications.Android/LocalNotifications.Android.csproj index f0e38c210..5b824680d 100644 --- a/LocalNotifications/LocalNotifications/LocalNotifications.Android/LocalNotifications.Android.csproj +++ b/LocalNotifications/LocalNotifications/LocalNotifications.Android/LocalNotifications.Android.csproj @@ -60,6 +60,7 @@ + diff --git a/LocalNotifications/LocalNotifications/LocalNotifications.Android/Properties/AndroidManifest.xml b/LocalNotifications/LocalNotifications/LocalNotifications.Android/Properties/AndroidManifest.xml index 9cbaabc55..8896e050a 100644 --- a/LocalNotifications/LocalNotifications/LocalNotifications.Android/Properties/AndroidManifest.xml +++ b/LocalNotifications/LocalNotifications/LocalNotifications.Android/Properties/AndroidManifest.xml @@ -1,6 +1,7 @@  - + - + + \ No newline at end of file diff --git a/LocalNotifications/LocalNotifications/LocalNotifications.iOS/AppDelegate.cs b/LocalNotifications/LocalNotifications/LocalNotifications.iOS/AppDelegate.cs index a59031e92..b928f8189 100644 --- a/LocalNotifications/LocalNotifications/LocalNotifications.iOS/AppDelegate.cs +++ b/LocalNotifications/LocalNotifications/LocalNotifications.iOS/AppDelegate.cs @@ -11,7 +11,7 @@ namespace LocalNotifications.iOS { global::Xamarin.Forms.Forms.Init(); - // set a delegate to handle incoming notifications + // Set a delegate to handle incoming notifications. UNUserNotificationCenter.Current.Delegate = new iOSNotificationReceiver(); LoadApplication(new App()); diff --git a/LocalNotifications/LocalNotifications/LocalNotifications.iOS/iOSNotificationReceiver.cs b/LocalNotifications/LocalNotifications/LocalNotifications.iOS/iOSNotificationReceiver.cs index 25aef83ba..4f4689b54 100644 --- a/LocalNotifications/LocalNotifications/LocalNotifications.iOS/iOSNotificationReceiver.cs +++ b/LocalNotifications/LocalNotifications/LocalNotifications.iOS/iOSNotificationReceiver.cs @@ -6,13 +6,29 @@ namespace LocalNotifications.iOS { public class iOSNotificationReceiver : UNUserNotificationCenterDelegate { + // Called if app is in the foreground. public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action completionHandler) { - DependencyService.Get().ReceiveNotification(notification.Request.Content.Title, notification.Request.Content.Body); - - // alerts are always shown for demonstration but this can be set to "None" - // to avoid showing alerts if the app is in the foreground + ProcessNotification(notification); completionHandler(UNNotificationPresentationOptions.Alert); } + + // Called if app is in the background, or killed state. + public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler) + { + if (response.IsDefaultAction) + { + ProcessNotification(response.Notification); + } + completionHandler(); + } + + void ProcessNotification(UNNotification notification) + { + string title = notification.Request.Content.Title; + string message = notification.Request.Content.Body; + + DependencyService.Get().ReceiveNotification(title, message); + } } } \ No newline at end of file