#if FIREBASE using Android.App; using Android.Content; using AndroidX.Core.App; using Firebase.Messaging; namespace MijnBesluit.App; /// /// Vangt meldingen op die binnenkomen terwijl de app openstaat. /// /// Android zet een melding alleen zelf in de balk als de app op de achtergrond staat. Staat hij /// open, dan geeft Android hem door aan deze dienst en gebeurt er verder niets - tenzij we hem /// hier zelf tonen. Dat was precies het geval waarin de proefmelding "verstuurd" heette en er /// op de telefoon niets te zien was. /// /// De tekst komt uit het data-deel van het bericht en niet uit het notification-deel. Beide /// staan erin (zie FirebasePush), maar het data-deel is het stuk waar de naamgeving in de /// Android-binding niet per versie verschilt. /// [Service(Exported = false)] [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] public class Meldingsdienst : FirebaseMessagingService { /// /// Het kanaal waarop deze meldingen binnenkomen. Vanaf Android 8 hoort elke melding bij een /// kanaal, en kan de gebruiker per kanaal zeggen hoe opdringerig het mag zijn. De naam staat /// ook in AndroidManifest.xml, zodat meldingen die binnenkomen terwijl de app dicht is op /// hetzelfde kanaal terechtkomen en niet onder "Overig". /// public const string Kanaal = "mijnbesluit-berichten"; /// /// Maakt het kanaal aan als het er nog niet is. Mag zo vaak aangeroepen worden als je wilt; /// Android werkt een bestaand kanaal dan alleen bij. Gebeurt bij het starten van de app, want /// een melding die binnenkomt terwijl de app dicht is heeft het kanaal al nodig. /// public static void MaakKanaal(Context context) { if (!OperatingSystem.IsAndroidVersionAtLeast(26)) return; var kanaal = new NotificationChannel(Kanaal, "Berichten", NotificationImportance.High) { Description = "Laat weten dat er iets voor je klaarstaat. Wat erin staat komt er nooit bij te staan." }; var beheer = (NotificationManager?)context.GetSystemService(Context.NotificationService); beheer?.CreateNotificationChannel(kanaal); } public override void OnMessageReceived(RemoteMessage bericht) { var gegevens = bericht.Data; gegevens.TryGetValue("titel", out var titel); gegevens.TryGetValue("tekst", out var tekst); if (string.IsNullOrWhiteSpace(titel)) titel = "MijnBesluit"; if (string.IsNullOrWhiteSpace(tekst)) tekst = "Er staat iets voor je klaar."; Toon(this, titel, tekst); } /// /// Firebase geeft een toestel af en toe een nieuw kenmerk. Het oude werkt dan niet meer. /// De app meldt zich bij elke aanmelding opnieuw aan met het kenmerk van dat moment, dus dat /// herstelt zichzelf zodra je weer inlogt. Zolang je ingelogd blijft kan er een melding /// tussendoor vallen; dat is bewust niet hier opgelost, want hier is geen verbinding met de /// server en geen sleutel om mee te praten. /// public override void OnNewToken(string kenmerk) => base.OnNewToken(kenmerk); private static void Toon(Context context, string titel, string tekst) { MaakKanaal(context); // Aantikken opent de app. SingleTop, zodat je niet een tweede keer hetzelfde scherm // opent bovenop het scherm waar je al was. var openen = new Intent(context, typeof(MainActivity)); openen.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop); var tik = PendingIntent.GetActivity(context, 0, openen, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable); // ApplicationInfo.Icon en niet een eigen tekening: dat is een nummer dat Android zelf // bijhoudt, dus hier hoeft geen tweede plaatje bijgehouden te worden dat kan ontbreken. var melding = new NotificationCompat.Builder(context, Kanaal) .SetContentTitle(titel) .SetContentText(tekst) .SetStyle(new NotificationCompat.BigTextStyle().BigText(tekst)) .SetSmallIcon(context.ApplicationInfo!.Icon) .SetAutoCancel(true) .SetPriority((int)NotificationPriority.High) .SetContentIntent(tik) .Build(); // Elk bericht een eigen nummer, anders vervangt de tweede melding de eerste. NotificationManagerCompat.From(context).Notify(Volgnummer(), melding); } private static int _laatste; private static int Volgnummer() => Interlocked.Increment(ref _laatste); } #endif