Android-Apps senden und empfangen Broadcast-Nachrichten vom Android-System und von anderen Android-Apps. Das ähnelt dem Publish-Subscribe Designmuster. Das System und die Apps senden in der Regel Broadcasts, wenn bestimmte Ereignisse eintreten. Das Android-System sendet beispielsweise Broadcasts, wenn verschiedene Systemereignisse auftreten, z. B. beim Systemstart oder beim Aufladen des Geräts. Apps senden auch benutzerdefinierte Broadcasts, um andere Apps über etwas zu informieren, das für sie von Interesse sein könnte (z. B. ein neuer Datendownload).
Apps können sich registrieren, um bestimmte Broadcasts zu empfangen. Wenn ein Broadcast gesendet wird, leitet das System ihn automatisch an Apps weiter, die ihn abonniert haben.
Im Allgemeinen können Broadcasts als Messaging-System für Apps und außerhalb des normalen Nutzerablaufs verwendet werden. Sie müssen jedoch darauf achten, die Möglichkeit, auf Broadcasts zu reagieren und Jobs im Hintergrund auszuführen, nicht zu missbrauchen, da dies die Systemleistung beeinträchtigen kann.
System-Broadcasts
Das System sendet automatisch Broadcasts, wenn verschiedene Systemereignisse auftreten, z. B. wenn das System in den Flugmodus wechselt. Alle abonnierten Apps erhalten diese Broadcasts.
Das Intent-Objekt umschließt die Nachricht an alle. Der String action gibt
das aufgetretene Ereignis an, z. B. android.intent.action.AIRPLANE_MODE. Die Absicht kann auch zusätzliche Informationen enthalten, die im Feld „extra“ gebündelt sind.
Die Absicht für den Flugmodus enthält beispielsweise ein boolesches Extra, das angibt, ob der Flugmodus aktiviert ist.
Weitere Informationen zum Lesen von Absichten und zum Abrufen des Aktionsstrings aus einer Absicht finden Sie unter Absichten und Absichtsfilter.
System-Broadcast-Aktionen
Eine vollständige Liste der System-Broadcast-Aktionen finden Sie in der Datei BROADCAST_ACTIONS.TXT im Android SDK. Jeder Broadcast-Aktion ist ein Konstantenfeld zugeordnet. Der Wert der Konstanten
ACTION_AIRPLANE_MODE_CHANGED ist beispielsweise android.intent.action.AIRPLANE_MODE.
Die Dokumentation für jede Broadcast-Aktion ist im zugehörigen Konstantenfeld verfügbar.
Änderungen an System-Broadcasts
Im Laufe der Entwicklung der Android-Plattform ändert sich regelmäßig das Verhalten von System-Broadcasts. Beachten Sie die folgenden Änderungen, um alle Android-Versionen zu unterstützen.
Android 16
In Android 16 kann die Reihenfolge der Broadcast-Zustellung mit dem android:priority
Attribut oder IntentFilter.setPriority() über verschiedene Prozesse hinweg
nicht garantiert werden. Broadcast-Prioritäten werden nur innerhalb desselben Anwendungsprozesses berücksichtigt, nicht über alle Prozesse hinweg.
Außerdem sind die Broadcast-Prioritäten automatisch auf den Bereich
(SYSTEM_LOW_PRIORITY + 1, SYSTEM_HIGH_PRIORITY - 1) beschränkt.
Nur Systemkomponenten dürfen SYSTEM_LOW_PRIORITY und SYSTEM_HIGH_PRIORITY als Broadcast-Priorität festlegen.
Android 14
Wenn sich Apps im Cache befinden, optimiert das System die Broadcast-Zustellung
für die Systemleistung. Das System verschiebt beispielsweise weniger wichtige System
Broadcasts wie ACTION_SCREEN_ON, während sich die App im Cache befindet.
Sobald die App aus dem Cache in einen aktiven Prozesslebenszyklus,
liefert das System alle verschobenen Broadcasts.
Wichtige Broadcasts, die im Manifest deklariert sind, entfernen Apps vorübergehend aus dem Cache, damit sie zugestellt werden können.
Android 9
Ab Android 9 (API-Level 28) enthält der NETWORK_STATE_CHANGED_ACTION
Broadcast keine Informationen zum Standort des Nutzers oder zu personenbezogenen
Daten.
Wenn Ihre App auf einem Gerät mit Android 9.0 (API-Level 28) oder höher installiert ist, enthält das System keine SSIDs, BSSIDs, Verbindungsinformationen oder Scanergebnisse in WLAN-Broadcasts. Rufen Sie stattdessen
getConnectionInfo() auf, um diese Informationen zu erhalten.
Android 8.0
Ab Android 8.0 (API-Level 26) gelten für im Manifest deklarierte Empfänger zusätzliche Einschränkungen.
Wenn Ihre App auf Android 8.0 oder höher ausgerichtet ist, können Sie im Manifest keinen Empfänger für die meisten impliziten Broadcasts deklarieren (Broadcasts, die nicht speziell auf Ihre App ausgerichtet sind). Sie können weiterhin einen kontextregistrierten Empfänger verwenden, wenn der Nutzer Ihre App aktiv verwendet.
Android 7.0
Unter Android 7.0 (API-Level 24) und höher werden die folgenden System-Broadcasts nicht gesendet:
Außerdem müssen Apps, die auf Android 7.0 und höher ausgerichtet sind, den
CONNECTIVITY_ACTION Broadcast mit
registerReceiver(BroadcastReceiver, IntentFilter) registrieren. Die Deklaration eines Empfängers im Manifest funktioniert nicht.
Broadcasts empfangen
Apps können Broadcasts auf zwei Arten empfangen: über kontextregistrierte Empfänger und im Manifest deklarierte Empfänger.
Kontextregistrierte Empfänger
Kontextregistrierte Empfänger empfangen Broadcasts, solange ihr Registrierungskontext gültig ist. Das ist in der Regel zwischen den Aufrufen von registerReceiver und
unregisterReceiver. Der Registrierungskontext wird auch ungültig, wenn das System den entsprechenden Kontext zerstört. Wenn Sie sich beispielsweise in einem
Activity-Kontext registrieren, empfangen Sie Broadcasts, solange die Aktivität
aktiv ist. Wenn Sie sich mit dem Anwendungskontext registrieren, empfangen Sie Broadcasts, solange die App ausgeführt wird.
So registrieren Sie einen Empfänger mit einem Kontext:
Fügen Sie in der Build-Datei auf Modulebene Ihrer App Version 1.9.0 oder höher von der AndroidX Core-Bibliothek hinzu:
Groovy
dependencies { def core_version = "1.19.0" // Java language implementation implementation "androidx.core:core:$core_version" // Kotlin implementation "androidx.core:core-ktx:$core_version" // To use RoleManagerCompat implementation "androidx.core:core-role:1.1.0" // To use the Animator APIs implementation "androidx.core:core-animation:1.0.0" // To test the Animator APIs androidTestImplementation "androidx.core:core-animation-testing:1.0.0" // Optional - To enable APIs that query the performance characteristics of GMS devices. implementation "androidx.core:core-performance:1.0.0" // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google implementation "androidx.core:core-google-shortcuts:1.1.0" // Optional - to support backwards compatibility of RemoteViews implementation "androidx.core:core-remoteviews:1.1.0" // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12 implementation "androidx.core:core-splashscreen:1.2.0" }
Kotlin
dependencies { val core_version = "1.19.0" // Java language implementation implementation("androidx.core:core:$core_version") // Kotlin implementation("androidx.core:core-ktx:$core_version") // To use RoleManagerCompat implementation("androidx.core:core-role:1.1.0") // To use the Animator APIs implementation("androidx.core:core-animation:1.0.0") // To test the Animator APIs androidTestImplementation("androidx.core:core-animation-testing:1.0.0") // Optional - To enable APIs that query the performance characteristics of GMS devices. implementation("androidx.core:core-performance:1.0.0") // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google implementation("androidx.core:core-google-shortcuts:1.1.0") // Optional - to support backwards compatibility of RemoteViews implementation("androidx.core:core-remoteviews:1.1.0") // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12 implementation("androidx.core:core-splashscreen:1.2.0") }
Erstellen Sie eine Instanz von
BroadcastReceiver:Kotlin
val myBroadcastReceiver = MyBroadcastReceiver()Java
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();Erstellen Sie eine Instanz von
IntentFilter:Kotlin
val filter = IntentFilter("com.example.snippets.ACTION_UPDATE_DATA")Java
IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");Wählen Sie aus, ob der Übertragungsempfänger exportiert und für andere Apps auf dem Gerät sichtbar sein soll. Wenn dieser Empfänger auf Broadcasts vom System oder von anderen Apps wartet – auch von anderen Apps, die Sie besitzen –, verwenden Sie das Flag
RECEIVER_EXPORTED. Wenn dieser Empfänger stattdessen nur auf Broadcasts wartet, die von Ihrer App gesendet werden, verwenden Sie das FlagRECEIVER_NOT_EXPORTED.Kotlin
val listenToBroadcastsFromOtherApps = false val receiverFlags = if (listenToBroadcastsFromOtherApps) { ContextCompat.RECEIVER_EXPORTED } else { ContextCompat.RECEIVER_NOT_EXPORTED }Java
boolean listenToBroadcastsFromOtherApps = false; int receiverFlags = listenToBroadcastsFromOtherApps ? ContextCompat.RECEIVER_EXPORTED : ContextCompat.RECEIVER_NOT_EXPORTED;Registrieren Sie den Empfänger mit
registerReceiver():Kotlin
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)Java
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);Wenn Sie keine Broadcasts mehr empfangen möchten, rufen Sie
unregisterReceiver(android.content.BroadcastReceiver)auf. Heben Sie die Registrierung des Empfängers auf, wenn Sie ihn nicht mehr benötigen oder der Kontext nicht mehr gültig ist.
Registrierung des Übertragungsempfängers aufheben
Solange der Übertragungsempfänger registriert ist, enthält er einen Verweis auf den Kontext, mit dem Sie ihn registriert haben. Dies kann zu Speicherlecks führen, wenn der registrierte Bereich des Empfängers den Lebenszyklusbereich des Kontexts überschreitet. Das kann beispielsweise passieren, wenn Sie einen Empfänger im Bereich einer Aktivität registrieren, aber vergessen, die Registrierung aufzuheben, wenn das System die Aktivität zerstört. Heben Sie daher immer die Registrierung Ihres Übertragungsempfängers auf.
Kotlin
class MyActivity : ComponentActivity() {
private val myBroadcastReceiver = MyBroadcastReceiver()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags)
setContent { MyApp() }
}
override fun onDestroy() {
super.onDestroy()
// When you forget to unregister your receiver here, you're causing a leak!
this.unregisterReceiver(myBroadcastReceiver)
}
}
Java
class MyActivity extends ComponentActivity {
MyBroadcastReceiver myBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags);
// Set content
}
}
Empfänger im kleinstmöglichen Bereich registrieren
Ihr Übertragungsempfänger sollte nur registriert werden, wenn Sie tatsächlich an dem Ergebnis interessiert sind. Wählen Sie den kleinstmöglichen Empfängerbereich aus:
LifecycleResumeEffectoder AktivitätslebenszyklusmethodenonResume/onPause: Der Übertragungsempfänger erhält nur Updates, wenn sich die App im fortgesetzten Zustand befindet.LifecycleStartEffectoder AktivitätslebenszyklusmethodenonStart/onStop: Der Übertragungsempfänger erhält nur Updates, wenn sich die App im fortgesetzten Zustand befindet.DisposableEffect: Der Übertragungsempfänger erhält nur Updates, wenn sich die zusammensetzbare Funktion im Kompositionsbaum befindet. Dieser Bereich ist nicht an den Aktivitätslebenszyklusbereich angehängt. Registrieren Sie den Empfänger im Anwendungskontext. Das liegt daran, dass die zusammensetzbare Funktion theoretisch den Aktivitätslebenszyklus überdauern und die Aktivität lecken kann.onCreate/onDestroyder Activity: Der Übertragungsempfänger erhält Updates, wenn sich die Activity im erstellten Zustand befindet. Heben Sie die Registrierung inonDestroy()und nicht inonSaveInstanceState(Bundle)auf, da diese möglicherweise nicht aufgerufen wird.- Ein benutzerdefinierter Bereich: Sie können beispielsweise einen Empfänger im Bereich
ViewModelregistrieren, damit er die Neuerstellung der Aktivität überdauert. Verwenden Sie den Anwendungskontext, um den Empfänger zu registrieren, da der Empfänger den Lebenszyklusbereich der Aktivität überdauern und die Aktivität lecken kann.
Zustandsorientierte und zustandslose zusammensetzbare Funktionen erstellen
Compose hat zustandsorientierte und zustandslose zusammensetzbare Funktionen. Wenn Sie einen Übertragungsempfänger innerhalb einer zusammensetzbaren Funktion registrieren oder die Registrierung aufheben, wird er zustandsorientiert. Die zusammensetzbare Funktion ist keine deterministische Funktion, die bei Übergabe derselben Parameter denselben Inhalt rendert. Der interne Zustand kann sich je nach Aufrufen des registrierten Broadcast-Empfängers ändern.
Als Best Practice in Compose empfehlen wir, Ihre zusammensetzbaren Funktionen in zustandsorientierte und zustandslose Versionen aufzuteilen. Daher empfehlen wir, die Erstellung des Übertragungsempfängers aus einer komponierbaren Funktion herauszuheben, um ihn zustandslos zu machen:
@Composable
fun MyStatefulScreen() {
val myBroadcastReceiver = remember { MyBroadcastReceiver() }
val context = LocalContext.current
LifecycleStartEffect(true) {
// ...
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, flags)
onStopOrDispose { context.unregisterReceiver(myBroadcastReceiver) }
}
MyStatelessScreen()
}
@Composable
fun MyStatelessScreen() {
// Implement your screen
}
Im Manifest deklarierte Empfänger
Wenn Sie einen Übertragungsempfänger im Manifest deklarieren, startet das System Ihre App, wenn der Broadcast gesendet wird. Wenn die App noch nicht ausgeführt wird, startet das System sie.
So deklarieren Sie einen Übertragungsempfänger im Manifest:
Geben Sie das
<receiver>Element im Manifest Ihrer App an.<!-- If this receiver listens for broadcasts sent from the system or from other apps, even other apps that you own, set android:exported to "true". --> <receiver android:name=".MyBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.example.snippets.ACTION_UPDATE_DATA" /> </intent-filter> </receiver>Die Absichtsfilter geben die Broadcast-Aktionen an, die Ihr Empfänger abonniert.
Erstellen Sie eine Unterklasse von
BroadcastReceiverund implementieren SieonReceive(Context, Intent). Der Übertragungsempfänger im folgenden Beispiel protokolliert und zeigt den Inhalt des Broadcasts an:Kotlin
class MyBroadcastReceiver : BroadcastReceiver() { @Inject lateinit var dataRepository: DataRepository override fun onReceive(context: Context, intent: Intent) { if (intent.action == "com.example.snippets.ACTION_UPDATE_DATA") { val data = intent.getStringExtra("com.example.snippets.DATA") ?: "No data" // Do something with the data, for example send it to a data repository: dataRepository.updateData(data) } } }Java
public static class MyBroadcastReceiver extends BroadcastReceiver { @Inject DataRepository dataRepository; @Override public void onReceive(Context context, Intent intent) { if (Objects.equals(intent.getAction(), "com.example.snippets.ACTION_UPDATE_DATA")) { String data = intent.getStringExtra("com.example.snippets.DATA"); // Do something with the data, for example send it to a data repository: if (data != null) { dataRepository.updateData(data); } } } }
Der System-Paketmanager registriert den Empfänger, wenn die App installiert wird. Der Empfänger wird dann zu einem separaten Einstiegspunkt in Ihre App. Das bedeutet, dass das System die App starten und den Broadcast zustellen kann, wenn die App nicht ausgeführt wird.
Das System erstellt ein neues BroadcastReceiver-Komponentenobjekt, um
jeden empfangenen Broadcast zu verarbeiten. Dieses Objekt ist nur für die Dauer von
dem Aufruf von onReceive(Context, Intent) gültig. Sobald Ihr Code von dieser Methode zurückkehrt, betrachtet das System die Komponente als nicht mehr aktiv.
Auswirkungen auf den Prozessstatus
Ob Ihr BroadcastReceiver ausgeführt wird oder nicht, wirkt sich auf den enthaltenen
Prozess aus, was die Wahrscheinlichkeit beeinflussen kann, dass er vom System beendet wird. Ein Vordergrundprozess
führt die Methode onReceive() eines Empfängers aus. Das System führt den Prozess aus, es sei denn, der Arbeitsspeicher ist extrem ausgelastet.
Das System deaktiviert den BroadcastReceiver nach onReceive().
Die Bedeutung des Hostprozesses des Empfängers hängt von seinen App-Komponenten ab. Wenn dieser Prozess nur einen im Manifest deklarierten Empfänger hostet, beendet das System ihn möglicherweise nach onReceive(), um Ressourcen für andere, wichtigere Prozesse freizugeben. Das ist häufig bei Apps der Fall, mit denen der Nutzer noch nie oder seit Kurzem nicht mehr interagiert hat.
Daher sollten Broadcast-Empfänger keine Hintergrundthreads mit langer Ausführungszeit initiieren.
Das System kann den Prozess jederzeit nach onReceive() beenden, um Arbeitsspeicher freizugeben, und dabei den erstellten Thread beenden. Wenn Sie den Prozess aktiv halten möchten, planen Sie mit JobScheduler einen
JobService vom Empfänger aus, damit das
System weiß, dass der Prozess noch ausgeführt wird. Weitere Informationen
finden Sie unter Hintergrundaufgaben.
Broadcasts senden
Android bietet zwei Möglichkeiten für Apps, Broadcasts zu senden:
- Die
sendOrderedBroadcast(Intent, String)Methode sendet Broadcasts jeweils an einen Empfänger. Da jeder Empfänger nacheinander ausgeführt wird, kann er ein Ergebnis an den nächsten Empfänger weitergeben. Er kann den Broadcast auch vollständig abbrechen, sodass er andere Empfänger nicht erreicht. Sie können die Reihenfolge steuern, in der Empfänger innerhalb desselben App-Prozesses ausgeführt werden. Verwenden Sie dazu das Attributandroid:prioritydes entsprechenden Absichtsfilters. Empfänger mit derselben Priorität werden in einer beliebigen Reihenfolge ausgeführt. - Die
sendBroadcast(Intent)Methode sendet Broadcasts in einer nicht definierten Reihenfolge an alle Empfänger. Das wird als normaler Broadcast bezeichnet. Diese Methode ist effizienter, aber Empfänger können keine Ergebnisse von anderen Empfängern lesen, Daten aus dem Broadcast weitergeben oder den Broadcast abbrechen.
Das folgende Code-Snippet zeigt, wie Sie einen Broadcast senden, indem Sie eine
Absicht erstellen und sendBroadcast(Intent) aufrufen.
Kotlin
val intent = Intent("com.example.snippets.ACTION_UPDATE_DATA").apply {
putExtra("com.example.snippets.DATA", newData)
setPackage("com.example.snippets")
}
context.sendBroadcast(intent)
Java
Intent intent = new Intent("com.example.snippets.ACTION_UPDATE_DATA");
intent.putExtra("com.example.snippets.DATA", newData);
intent.setPackage("com.example.snippets");
context.sendBroadcast(intent);
Die Nachricht an alle ist in ein Intent-Objekt eingebunden. Der String action der Absicht muss die Java-Paketnamenssyntax der App enthalten und das Broadcast-Ereignis eindeutig identifizieren. Mit putExtra(String, Bundle) können Sie der
Absicht zusätzliche Informationen anhängen. Sie können einen Broadcast auch auf
eine Reihe von Apps in derselben Organisation beschränken, indem Sie setPackage(String) für
die Absicht aufrufen.
Broadcasts mit Berechtigungen einschränken
Mit Berechtigungen können Sie Broadcasts auf die Apps beschränken, die bestimmte Berechtigungen haben. Sie können Einschränkungen für den Absender oder den Empfänger eines Broadcasts erzwingen.
Broadcasts mit Berechtigungen senden
Wenn Sie sendBroadcast(Intent, String) oder
sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String,
Bundle)
aufrufen, können Sie einen Berechtigungsparameter angeben. Nur Empfänger, die diese
Berechtigung mit dem <uses-permission> Tag in ihrem Manifest angefordert haben, können den
Broadcast empfangen. Wenn die Berechtigung gefährlich ist, müssen Sie sie erteilen, bevor der Empfänger den Broadcast empfangen kann. Der folgende Code sendet beispielsweise einen Broadcast mit einer Berechtigung:
Kotlin
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION)
Java
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION);
Damit die empfangende App den Broadcast empfangen kann, muss sie die Berechtigung so anfordern:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Sie können entweder eine vorhandene Systemberechtigung wie
BLUETOOTH_CONNECT angeben oder mit dem
<permission> Element eine benutzerdefinierte Berechtigung definieren. Informationen zu Berechtigungen und Sicherheit im
Allgemeinen finden Sie unter den Systemberechtigungen.
Broadcasts mit Berechtigungen empfangen
Wenn Sie einen Berechtigungsparameter angeben, wenn Sie einen Übertragungsempfänger registrieren
(entweder mit
registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) oder im
<receiver> Tag in Ihrem Manifest), können nur Absender, die die Berechtigung mit dem <uses-permission> Tag in ihrem
Manifest angefordert haben, eine Absicht an den Empfänger senden. Wenn die Berechtigung gefährlich ist, muss sie dem Absender auch erteilt werden.
Angenommen, Ihre empfangende App hat einen im Manifest deklarierten Empfänger wie folgt:
<!-- If this receiver listens for broadcasts sent from the system or from
other apps, even other apps that you own, set android:exported to "true". -->
<receiver
android:name=".MyBroadcastReceiverWithPermission"
android:permission="android.permission.ACCESS_COARSE_LOCATION"
android:exported="true">
<intent-filter>
<action android:name="com.example.snippets.ACTION_UPDATE_DATA" />
</intent-filter>
</receiver>
Oder Ihre empfangende App hat einen kontextregistrierten Empfänger wie folgt:
Kotlin
ContextCompat.registerReceiver(
context, myBroadcastReceiver, filter,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
null, // scheduler that defines thread, null means run on main thread
receiverFlags
)
Java
ContextCompat.registerReceiver(
context, myBroadcastReceiver, filter,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
null, // scheduler that defines thread, null means run on main thread
receiverFlags
);
Damit die sendende App Broadcasts an diese Empfänger senden kann, muss sie die Berechtigung so anfordern:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Sicherheitsaspekte
Hier sind einige Sicherheitsaspekte für das Senden und Empfangen von Broadcasts:
Wenn viele Apps in ihrem Manifest registriert sind, um denselben Broadcast zu empfangen, kann das System viele Apps starten, was sich erheblich auf die Geräteleistung und die Nutzerfreundlichkeit auswirkt. Um das zu vermeiden, sollten Sie die Kontextregistrierung der Manifestdeklaration vorziehen. Manchmal erzwingt das Android-System selbst die Verwendung von kontextregistrierten Empfängern. Der
CONNECTIVITY_ACTIONBroadcast wird beispielsweise nur an kontextregistrierte Empfänger zugestellt.Senden Sie keine vertraulichen Informationen mit einem impliziten Intent. Jede App kann die Informationen lesen, wenn sie sich für den Empfang des Broadcasts registriert. Es gibt drei Möglichkeiten, zu steuern, wer Ihre Broadcasts empfangen kann:
- Sie können beim Senden eines Broadcasts eine Berechtigung angeben.
- Unter Android 4.0 (API-Level 14) und höher können Sie mit
setPackage(String)ein Paket angeben, wenn Sie einen Broadcast senden. Das System beschränkt den Broadcast auf die Apps, die dem Paket entsprechen.
Wenn Sie einen Empfänger registrieren, kann jede App potenziell schädliche Broadcasts an den Empfänger Ihrer App senden. Es gibt mehrere Möglichkeiten, die Broadcasts zu beschränken, die Ihre App empfängt:
- Sie können beim Registrieren eines Übertragungsempfängers eine Berechtigung angeben.
- Für im Manifest deklarierte Empfänger können Sie das android:exported Attribut auf „false“ im Manifest setzen. Der Empfänger empfängt keine Broadcasts von Quellen außerhalb der App.
Der Namespace für Broadcast-Aktionen ist global. Achten Sie darauf, dass Aktionsnamen und andere Strings in einem Namespace geschrieben sind, den Sie besitzen. Andernfalls kann es zu unbeabsichtigten Konflikten mit anderen Apps kommen.
Da die Methode
onReceive(Context, Intent)eines Empfängers im Hauptthread ausgeführt wird, sollte sie schnell ausgeführt werden und zurückkehren. Wenn Sie Aufgaben mit langer Ausführungszeit ausführen müssen, sollten Sie Threads oder Hintergrunddienste nur mit Bedacht starten, da das System den gesamten Prozess beenden kann, nachdemonReceive()zurückgekehrt ist. Weitere Informationen finden Sie unter Auswirkungen auf den Prozessstatus. So führen Sie Aufgaben mit langer Ausführungszeit aus:- Rufen Sie in der Methode
onReceive()Ihres EmpfängersgoAsync()auf und übergeben SieBroadcastReceiver.PendingResultan einen Hintergrund thread. Dadurch bleibt der Broadcast aktiv, nachdemonReceive()zurückgekehrt ist. Auch bei dieser Methode erwartet das System jedoch, dass Sie den Broadcast sehr schnell (in weniger als 10 Sekunden) beenden. Sie können Aufgaben in einen anderen Thread verschieben, um den Hauptthread nicht zu überlasten. - Planen Sie einen Job mit dem
JobScheduler. Weitere Informationen finden Sie unter Intelligente Jobplanung.
- Rufen Sie in der Methode
Starten Sie keine Aktivitäten von Broadcast-Empfängern aus, da das die Nutzerfreundlichkeit beeinträchtigt, insbesondere wenn es mehr als einen Empfänger gibt. Erwägen Sie stattdessen, eine Benachrichtigung anzuzeigen.