Broadcast Receivers in Xamarin.Android

In diesem Abschnitt wird die Verwendung eines Übertragungsempfängers erläutert.

Übersicht über Übertragungsempfänger

Ein Broadcastempfänger ist eine Android-Komponente, die es einer Anwendung ermöglicht, auf Nachrichten (android Intent) zu reagieren, die vom Android-Betriebssystem oder von einer Anwendung übertragen werden. Übertragungen folgen einem Veröffentlichungs-/Abonnementmodell : Ein Ereignis bewirkt, dass eine Übertragung veröffentlicht und von den komponenten empfangen wird, die an dem Ereignis interessiert sind.

Android identifiziert zwei Arten von Übertragungen:

  • Explizite Übertragung : Diese Arten von Broadcasts zielen auf eine bestimmte Anwendung ab. Die häufigste Verwendung einer expliziten Übertragung ist das Starten einer Aktivität. Ein Beispiel für eine explizite Übertragung, wenn eine App eine Telefonnummer wählen muss; Es sendet eine Absicht, die auf die Telefon-App unter Android ausgerichtet ist, und gibt die zu wählende Telefonnummer weiter. Android leitet dann die Absicht an die Smartphone-App weiter.
  • Implizite Übertragung : Diese Broadcasts werden an alle Apps auf dem Gerät gesendet. Ein Beispiel für eine implizite Übertragung ist die ACTION_POWER_CONNECTED Absicht. Diese Absicht wird jedes Mal veröffentlicht, wenn Android erkennt, dass der Akku des Geräts aufgeladen wird. Android leitet diese Absicht an alle Apps weiter, die sich für dieses Ereignis registriert haben.

Der Broadcastempfänger ist eine Unterklasse des BroadcastReceiver Typs und muss die OnReceive -Methode überschreiben. Android wird im Standard-Thread ausgeführtOnReceive, sodass diese Methode für die schnelle Ausführung konzipiert werden sollte. Beim Einfügen von Threads in OnReceive sollte Vorsicht beachtet werden, da Android den Prozess nach Abschluss der Methode beenden kann. Wenn ein Broadcastempfänger lang andauernde Arbeiten ausführen muss, empfiehlt es sich, einen Auftrag mit dem JobScheduleroder dem Firebase-Auftragsverteiler zu planen. Die Planung der Arbeit mit einem Auftrag wird in einem separaten Leitfaden erläutert.

Ein Absichtsfilter wird verwendet, um einen Broadcastempfänger zu registrieren, damit Android Nachrichten ordnungsgemäß weiterleiten kann. Der Absichtsfilter kann zur Laufzeit angegeben werden (dies wird manchmal als kontextregistrierter Empfänger oder als dynamische Registrierung bezeichnet) oder er kann statisch im Android-Manifest (ein manifest registrierter Empfänger) definiert werden. Xamarin.Android stellt das C#-Attribut bereit, IntentFilterAttributedas den Absichtsfilter statisch registriert (dies wird später in diesem Handbuch ausführlicher erläutert). Ab Android 8.0 ist es für eine Anwendung nicht möglich, sich statisch für eine implizite Übertragung zu registrieren.

Der Hauptunterschied zwischen dem manifest-registrierten Empfänger und dem kontext registrierten Empfänger besteht darin, dass ein kontext registrierter Empfänger nur auf Broadcasts reagiert, während eine Anwendung ausgeführt wird, während ein manifest registrierter Empfänger auf Übertragungen reagieren kann, obwohl die App möglicherweise nicht ausgeführt wird.

Es gibt zwei Sätze von APIs zum Verwalten eines Broadcastempfängers und Senden von Übertragungen:

  1. Context – Die Android.Content.Context -Klasse kann verwendet werden, um einen Broadcastempfänger zu registrieren, der auf systemweite Ereignisse reagiert. Wird Context auch verwendet, um systemweite Broadcasts zu veröffentlichen.
  2. LocalBroadcastManager – Dies ist eine API, die über das NuGet-Paket der Xamarin Support Library v4 verfügbar ist. Diese Klasse wird verwendet, um Broadcast- und Broadcastempfänger im Kontext der Anwendung, die sie verwendet, isoliert zu halten. Diese Klasse kann nützlich sein, um zu verhindern, dass andere Anwendungen auf reine Anwendungsübertragungen reagieren oder Nachrichten an private Empfänger senden.

Ein Broadcastempfänger zeigt möglicherweise keine Dialoge an, und es wird dringend davon abgeraten, eine Aktivität innerhalb eines Broadcastempfängers zu starten. Wenn ein Broadcastempfänger den Benutzer benachrichtigen muss, sollte er eine Benachrichtigung veröffentlichen.

Es ist nicht möglich, einen Dienst innerhalb eines Broadcastempfängers zu binden oder ihn zu starten.

In diesem Leitfaden erfahren Sie, wie Sie einen Broadcastempfänger erstellen und registrieren, damit er Broadcasts empfangen kann.

Erstellen eines Übertragungsempfängers

Um einen Broadcastempfänger in Xamarin.Android zu erstellen, muss eine Anwendung die BroadcastReceiver -Klasse unterklassen, sie mit BroadcastReceiverAttributeversehen und die OnReceive -Methode überschreiben:

[BroadcastReceiver(Enabled = true, Exported = false)]
public class SampleReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Do stuff here.

        String value = intent.GetStringExtra("key");
    }
}

Wenn Xamarin.Android die -Klasse kompiliert, wird auch das AndroidManifest mit den erforderlichen Metadaten aktualisiert, um den Empfänger zu registrieren. Für einen statisch registrierten Broadcastempfänger muss ordnungsgemäß Enabled auf truefestgelegt werden, andernfalls kann Android keine instance des Empfängers erstellen.

Die Exported -Eigenschaft steuert, ob der Broadcastempfänger Nachrichten von außerhalb der Anwendung empfangen kann. Wenn die Eigenschaft nicht explizit festgelegt ist, wird der Standardwert der Eigenschaft von Android basierend darauf bestimmt, ob dem Broadcastempfänger Absichtsfilter zugeordnet sind. Wenn mindestens ein Absichtsfilter für den Broadcastempfänger vorhanden ist, geht Android davon aus, dass die Exported -Eigenschaft ist true. Wenn dem Broadcastempfänger keine Absichtsfilter zugeordnet sind, geht Android davon aus, dass der Wert ist false.

Die OnReceive -Methode empfängt einen Verweis auf den , der Intent an den Broadcastempfänger gesendet wurde. Dies ermöglicht es dem Absender der Absicht, Werte an den Broadcastempfänger zu übergeben.

Statisch registrieren eines Übertragungsempfängers mit einem Absichtsfilter

Wenn ein BroadcastReceiver mit IntentFilterAttributeergänzt wird, fügt Xamarin.Android das erforderliche <intent-filter> Element zum Android-Manifest zur Kompilierzeit hinzu. Der folgende Codeausschnitt ist ein Beispiel für einen Broadcastempfänger, der ausgeführt wird, wenn der Start eines Geräts abgeschlossen ist (wenn der Benutzer die entsprechenden Android-Berechtigungen erteilt hat):

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class MyBootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Work that should be done when the device boots.     
    }
}

Hinweis

In Android 8.0 (API 26 und höher) hat Google Einschränkungen hinsichtlich der Möglichkeiten von Apps gesetzt, während Benutzer nicht direkt mit ihnen interagieren. Diese Einschränkungen wirken sich auf Hintergrunddienste und implizite Broadcastempfänger wie Android.Content.Intent.ActionBootCompletedaus. Aufgrund dieser Einschränkungen haben Sie möglicherweise Probleme beim Registrieren eines Boot Completed Broadcastempfängers unter neueren Versionen von Android. Beachten Sie in diesem Fall, dass diese Einschränkungen nicht für Vordergrunddienste gelten, die von Ihrem Broadcastempfänger aufgerufen werden können.

Es ist auch möglich, einen Absichtsfilter zu erstellen, der auf benutzerdefinierte Absichten reagiert. Betrachten Sie das folgenden Beispiel:

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "com.xamarin.example.TEST" })]
public class MySampleBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Do stuff here
    }
}

Apps, die auf Android 8.0 (API-Ebene 26) oder höher ausgerichtet sind, registrieren sich möglicherweise nicht statisch für eine implizite Übertragung. Apps können sich weiterhin statisch für eine explizite Übertragung registrieren. Es gibt eine kleine Liste impliziter Übertragungen, die von dieser Einschränkung ausgenommen sind. Diese Ausnahmen werden im Leitfaden zu impliziten Broadcastausnahmen in der Android-Dokumentation beschrieben. Apps, die an impliziten Übertragungen interessiert sind, müssen dies dynamisch mit der RegisterReceiver -Methode tun. Dies wird als Nächstes beschrieben.

Context-Registering eines Übertragungsempfängers

Die Kontextregistrierung (auch als dynamische Registrierung bezeichnet) eines Empfängers erfolgt durch Aufrufen der RegisterReceiver -Methode, und der Broadcastempfänger muss die Registrierung mit einem Aufruf der UnregisterReceiver -Methode aufheben. Um Ressourcenverluste zu verhindern, ist es wichtig, die Registrierung des Empfängers aufzuheben, wenn er für den Kontext (Aktivität oder Dienst) nicht mehr relevant ist. Beispielsweise kann ein Dienst eine Absicht übertragen, um eine Aktivität darüber zu informieren, dass Updates verfügbar sind, um dem Benutzer angezeigt zu werden. Wenn die Aktivität beginnt, wird sie für diese Absichten registriert. Wenn die Aktivität in den Hintergrund verschoben und für den Benutzer nicht mehr sichtbar ist, sollte die Registrierung des Empfängers aufgehoben werden, da die Benutzeroberfläche zum Anzeigen der Updates nicht mehr sichtbar ist. Der folgende Codeausschnitt ist ein Beispiel für das Registrieren und Aufheben der Registrierung eines Broadcastempfängers im Kontext einer Aktivität:

[Activity(Label = "MainActivity", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity: Activity
{
    MySampleBroadcastReceiver receiver;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        receiver = new MySampleBroadcastReceiver();

        // Code omitted for clarity
    }

    protected override void OnResume()
    {
        base.OnResume();
        RegisterReceiver(receiver, new IntentFilter("com.xamarin.example.TEST"));
        // Code omitted for clarity
    }

    protected override void OnPause()
    {
        UnregisterReceiver(receiver);
        // Code omitted for clarity
        base.OnPause();
    }
}

Im vorherigen Beispiel registriert die Aktivität, wenn sie in den Vordergrund kommt, einen Broadcastempfänger, der mithilfe der OnResume Lifecycle-Methode auf eine benutzerdefinierte Absicht lauscht. Wenn die Aktivität in den Hintergrund verschoben wird, hebt die -Methode die OnPause() Registrierung des Empfängers auf.

Veröffentlichen einer Übertragung

Eine Übertragung kann für alle auf dem Gerät installierten Apps veröffentlicht werden, die ein Intent-Objekt erstellen und mit der SendBroadcast - oder - SendOrderedBroadcast Methode senden.

  1. Context.SendBroadcast-Methoden : Es gibt mehrere Implementierungen dieser Methode. Diese Methoden übertragen die Absicht an das gesamte System. Broadcast-Empfänger, die die Absicht in einer unbestimmten Reihenfolge empfangen. Dies bietet ein hohes Maß an Flexibilität, bedeutet aber, dass es für andere Anwendungen möglich ist, sich zu registrieren und die Absicht zu erhalten. Dies kann ein potenzielles Sicherheitsrisiko darstellen. Anwendungen müssen möglicherweise zusätzliche Sicherheit implementieren, um nicht autorisierten Zugriff zu verhindern. Eine mögliche Lösung besteht darin, die zu verwenden, die LocalBroadcastManager Nachrichten nur innerhalb des privaten Bereichs der App sendet. Dieser Codeausschnitt ist ein Beispiel für das Senden einer Absicht mit einer der SendBroadcast Methoden:

    Intent message = new Intent("com.xamarin.example.TEST");
    // If desired, pass some values to the broadcast receiver.
    message.PutExtra("key", "value");
    SendBroadcast(message);
    

    Dieser Codeausschnitt ist ein weiteres Beispiel für das Senden einer Übertragung mithilfe der Intent.SetAction -Methode, um die Aktion zu identifizieren:

    Intent intent = new Intent();
    intent.SetAction("com.xamarin.example.TEST");
    intent.PutExtra("key", "value");
    SendBroadcast(intent);
    
  2. Context.SendOrderedBroadcast – Diese Methode ist sehr ähnlich mit Context.SendBroadcast, mit dem Unterschied, dass die Absicht einmal für Empfänger veröffentlicht wird, in der Reihenfolge, in der die Empfänger registriert wurden.

LocalBroadcastManager

Die Xamarin-Supportbibliothek v4 stellt eine Hilfsklasse namens bereit LocalBroadcastManager. Ist LocalBroadcastManager für Apps vorgesehen, die keine Übertragungen von anderen Apps auf dem Gerät senden oder empfangen möchten. Die LocalBroadcastManager veröffentlicht nur Nachrichten im Kontext der Anwendung und nur für die Broadcastempfänger, die LocalBroadcastManagerbei registriert sind. Dieser Codeausschnitt ist ein Beispiel für die Registrierung eines Broadcastempfängers mit LocalBroadcastManager:

Android.Support.V4.Content.LocalBroadcastManager.GetInstance(this). RegisterReceiver(receiver, new IntentFilter("com.xamarin.example.TEST"));

Andere Apps auf dem Gerät können die Nachrichten, die mit LocalBroadcastManagerveröffentlicht werden, nicht empfangen. Dieser Codeausschnitt zeigt, wie eine Absicht mithilfe von verteilt wird LocalBroadcastManager:

Intent message = new Intent("com.xamarin.example.TEST");
// If desired, pass some values to the broadcast receiver.
message.PutExtra("key", "value");
Android.Support.V4.Content.LocalBroadcastManager.GetInstance(this).SendBroadcast(message);