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 JobScheduler
oder 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, IntentFilterAttribute
das 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:
Context
– DieAndroid.Content.Context
-Klasse kann verwendet werden, um einen Broadcastempfänger zu registrieren, der auf systemweite Ereignisse reagiert. WirdContext
auch verwendet, um systemweite Broadcasts zu veröffentlichen.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 BroadcastReceiverAttribute
versehen 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 true
festgelegt 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 IntentFilterAttribute
ergä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.ActionBootCompleted
aus. 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.
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 derSendBroadcast
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);
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 LocalBroadcastManager
bei 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 LocalBroadcastManager
verö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);