Eerste commit
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
#if FIREBASE
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using AndroidX.Core.App;
|
||||
using Firebase.Messaging;
|
||||
|
||||
namespace MijnBesluit.App;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[Service(Exported = false)]
|
||||
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
|
||||
public class Meldingsdienst : FirebaseMessagingService
|
||||
{
|
||||
/// <summary>
|
||||
/// 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".
|
||||
/// </summary>
|
||||
public const string Kanaal = "mijnbesluit-berichten";
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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
|
||||
Reference in New Issue
Block a user