Android-Apps senden und empfangen Broadcast-Nachrichten vom Android-System und von anderen Android-Apps, ähnlich wie beim Publish/Subscribe-Entwurfsmuster. Das System und Apps senden in der Regel Broadcasts, wenn bestimmte Ereignisse eintreten. Das Android-System sendet beispielsweise Broadcasts, wenn verschiedene Systemereignisse eintreten, 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. einen neuen Datendownload.
Apps können sich registrieren, um bestimmte Broadcasts zu empfangen. Wenn eine Broadcast-Nachricht gesendet wird, leitet das System sie automatisch an Apps weiter, die den Empfang dieser bestimmten Art von Broadcast-Nachricht abonniert haben.
Im Allgemeinen können Broadcasts als Messaging-System für Apps und außerhalb des normalen Nutzerablaufs verwendet werden. Sie dürfen die Möglichkeit, auf Broadcasts zu reagieren und Jobs im Hintergrund auszuführen, jedoch nicht missbrauchen, da dies zu einer langsamen Systemleistung führen kann.
Systemnachrichten
Das System sendet automatisch Broadcasts, wenn verschiedene Systemereignisse eintreten, z. B. wenn das System in den Flugmodus wechselt oder den Flugmodus verlässt. Alle abonnierten Apps empfangen 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 in ihrem zusätzlichen Feld gebündelt sind.
Der Intent „Flugmodus“ enthält beispielsweise ein boolesches Extra, das angibt, ob der Flugmodus aktiviert ist.
Weitere Informationen zum Lesen von Intents und zum Abrufen des Aktionsstrings aus einem Intent finden Sie unter Intents und Intent-Filter.
Systemnachrichtenaktionen
Eine vollständige Liste der System-Broadcast-Aktionen finden Sie in der Datei BROADCAST_ACTIONS.TXT im Android SDK. Jeder Broadcast-Aktion ist ein konstantes Feld 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 Konstantfeld 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 ist die Reihenfolge der Broadcast-Zustellung mit dem Attribut android:priority oder IntentFilter.setPriority() über verschiedene Prozesse hinweg nicht garantiert. Broadcast-Prioritäten werden nur innerhalb desselben Anwendungsprozesses berücksichtigt, nicht über alle Prozesse hinweg.
Außerdem werden Broadcast-Prioritäten automatisch auf den Bereich (SYSTEM_LOW_PRIORITY + 1, SYSTEM_HIGH_PRIORITY – 1) beschränkt.
Nur Systemkomponenten dürfen SYSTEM_LOW_PRIORITY,
SYSTEM_HIGH_PRIORITY als Broadcast-Priorität festlegen.
Android 14
Wenn sich Apps im Cache-Zustand befinden, optimiert das System die Übertragung von Broadcasts im Hinblick auf die Systemintegrität. 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 wechselt, liefert das System alle verzögerten Broadcasts aus.
Wichtige Broadcasts, die im Manifest deklariert sind, entfernen Apps vorübergehend aus dem Cache-Status für die Auslieferung.
Android 9
Ab Android 9 (API-Level 28) werden bei der NETWORK_STATE_CHANGED_ACTION-Broadcast keine Informationen zum Standort des Nutzers oder personenbezogene Daten empfangen.
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-Ebene 26) gelten für im Manifest deklarierte Receiver zusätzliche Einschränkungen.
Wenn Ihre App auf Android 8.0 oder höher ausgerichtet ist, können Sie das Manifest nicht verwenden, um einen Empfänger für die meisten impliziten Broadcasts (Broadcasts, die nicht speziell auf Ihre App ausgerichtet sind) zu deklarieren. Sie können weiterhin einen kontextregistrierten Receiver 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 Receivers im Manifest funktioniert nicht.
Übertragungen empfangen
Apps können Broadcasts auf zwei Arten empfangen: über kontextregistrierte Empfänger und über im Manifest deklarierte Empfänger.
Kontextregistrierte Empfänger
Kontextregistrierte Empfänger empfangen Broadcasts, solange ihr Registrierungskontext gültig ist. Dies geschieht 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 im Kontext Activity registrieren, erhalten Sie Broadcasts, solange die Aktivität aktiv bleibt. Wenn Sie sich mit dem Anwendungskontext registrieren, erhalten Sie Broadcasts, solange die App ausgeführt wird.
So registrieren Sie einen Receiver mit einem Kontext:
Fügen Sie in die Build-Datei auf Modulebene Ihrer App Version 1.9.0 oder höher der AndroidX Core-Bibliothek ein:
Groovy
dependencies { def core_version = "1.18.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.18.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 Receiver auf Broadcasts wartet, die vom System oder von anderen Apps gesendet werden – auch von anderen Apps, die Ihnen gehören –, verwenden Sie das Flag
RECEIVER_EXPORTED. Wenn dieser Receiver stattdessen nur auf Broadcasts reagiert, 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, indem Sie
registerReceiver()aufrufen:Kotlin
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)Java
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);Wenn Sie keine Broadcasts mehr erhalten möchten, rufen Sie
unregisterReceiver(android.content.BroadcastReceiver)an. Registrieren Sie den Receiver ab, wenn Sie ihn nicht mehr benötigen oder der Kontext nicht mehr gültig ist.
Übertragungsempfänger abmelden
Solange der Übertragungsempfänger registriert ist, enthält er einen Verweis auf den Kontext, mit dem Sie ihn registriert haben. Dies kann zu Lecks führen, wenn der registrierte Bereich des Empfängers den Bereich des Context-Lebenszyklus überschreitet. Das kann beispielsweise passieren, wenn Sie einen Receiver in einem Activity-Bereich registrieren, aber vergessen, die Registrierung aufzuheben, wenn das System die Activity zerstört. Melden Sie Ihren Übertragungsempfänger daher immer ab.
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 am Ergebnis interessiert sind. Wählen Sie den kleinstmöglichen Empfängerbereich aus:
LifecycleResumeEffect- oder Aktivitäts-Lifecycle-MethodenonResume/onPause: Der Übertragungsempfänger empfängt nur Updates, wenn sich die App im fortgesetzten Zustand befindet.LifecycleStartEffect- oder Aktivitäts-Lifecycle-MethodenonStart/onStop: Der Übertragungsempfänger empfängt nur Updates, wenn sich die App im fortgesetzten Zustand befindet.DisposableEffect: Der Übertragungsempfänger empfängt nur Updates, wenn sich das Composable im Kompositionsbaum befindet. Dieser Bereich ist nicht an den Bereich des Aktivitätslebenszyklus angehängt. Registrieren Sie den Receiver im Anwendungskontext. Das liegt daran, dass das Composable theoretisch den Aktivitätslebenszyklus überdauern und die Aktivität leaken könnte.- Aktivität
onCreate/onDestroy: Der Übertragungsempfänger empfängt Updates, während sich die Aktivität im Status „Erstellt“ befindet. Melden Sie sich inonDestroy()und nicht inonSaveInstanceState(Bundle)ab, da diese möglicherweise nicht aufgerufen wird. - Benutzerdefinierter Bereich: Sie können beispielsweise einen Receiver in Ihrem
ViewModel-Bereich registrieren, damit er die Neuerstellung von Aktivitäten übersteht. Verwenden Sie den Anwendungskontext, um den Receiver zu registrieren, da der Receiver den Lebenszyklusbereich der Aktivität überdauern und die Aktivität leaken kann.
Zustandsorientierte und zustandslose Composables erstellen
Compose hat zustandsorientierte und zustandslose Composables. Durch das Registrieren oder Aufheben der Registrierung eines Übertragungsempfängers in einem Composable wird es zustandsbehaftet. Das Composable ist keine deterministische Funktion, die bei Übergabe derselben Parameter denselben Inhalt rendert. Der interne Status kann sich basierend auf Aufrufen des registrierten Broadcast-Empfängers ändern.
Als Best Practice in Compose empfehlen wir, Ihre komponierbaren Funktionen in zustandsorientierte und zustandslose Versionen aufzuteilen. Daher empfehlen wir, die Erstellung des Übertragungsempfängers aus einer komponierbaren Funktion herauszuziehen, damit sie zustandslos wird:
@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 in Ihrem Manifest einen Übertragungsempfänger deklarieren, startet das System Ihre App, wenn der Broadcast gesendet wird. Wenn die App noch nicht ausgeführt wird, wird sie vom System gestartet.
So deklarieren Sie einen Übertragungsempfänger im Manifest:
Geben Sie das Element
<receiver>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 Intent-Filter geben die Broadcast-Aktionen an, für die Ihr Empfänger registriert ist.
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 Systempaketmanager registriert den Empfänger, wenn die App installiert wird. Der Receiver wird dann zu einem separaten Einstiegspunkt in Ihre App. Das bedeutet, dass das System die App starten und den Broadcast übermitteln kann, wenn die App nicht ausgeführt wird.
Das System erstellt ein neues BroadcastReceiver-Komponentenobjekt, um jede empfangene Broadcast zu verarbeiten. Dieses Objekt ist nur für die Dauer des Aufrufs 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 in Betrieb ist oder nicht, wirkt sich auf den darin enthaltenen Prozess aus, was die Wahrscheinlichkeit, dass das System beendet wird, verändern kann. Ein Vordergrundprozess führt die Methode onReceive() eines Receivers aus. Das System führt den Prozess aus, es sei denn, es besteht eine extreme Arbeitsspeicherauslastung.
Das System deaktiviert BroadcastReceiver nach onReceive().
Die Bedeutung des Hostprozesses des Empfängers hängt von seinen App-Komponenten ab. Wenn in diesem Prozess nur ein im Manifest deklarierter Empfänger gehostet wird, kann das System ihn nach onReceive() beenden, um Ressourcen für andere, wichtigere Prozesse freizugeben. Das ist häufig bei Apps der Fall, mit denen der Nutzer noch nie oder in letzter Zeit nicht interagiert hat.
Daher sollten Broadcast-Empfänger keine Hintergrundthreads mit langer Ausführungszeit initiieren.
Das System kann den Prozess jederzeit nach onReceive() beenden, um Speicherplatz freizugeben, und den erstellten Thread beenden. Damit der Prozess aktiv bleibt, plane mit JobScheduler eine JobService vom Empfänger aus, damit das System weiß, dass der Prozess noch aktiv ist. Weitere Informationen finden Sie unter Hintergrundarbeit – Übersicht.
Nachrichten an alle senden
Android bietet zwei Möglichkeiten für Apps, Broadcasts zu senden:
- Die Methode
sendOrderedBroadcast(Intent, String)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. Außerdem kann die Übertragung vollständig abgebrochen werden, sodass sie nicht auf anderen Empfängern ankommt. Sie können die Reihenfolge festlegen, in der Empfänger im selben App-Prozess ausgeführt werden. Verwenden Sie dazu das Attributandroid:prioritydes entsprechenden Intent-Filters. Empfänger mit derselben Priorität werden in beliebiger Reihenfolge ausgeführt. - Mit der Methode
sendBroadcast(Intent)werden Broadcasts in einer nicht definierten Reihenfolge an alle Empfänger gesendet. Dies wird als normale Übertragung bezeichnet. Das ist effizienter, bedeutet aber, dass Empfänger keine Ergebnisse von anderen Empfängern lesen, vom Broadcast empfangene Daten weiterleiten oder den Broadcast abbrechen können.
Das folgende Code-Snippet zeigt, wie Sie einen Broadcast senden, indem Sie einen Intent 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 wird in ein Intent-Objekt eingeschlossen. Der action-String des Intents muss die Syntax des Java-Paketnamens der App enthalten und das Broadcast-Ereignis eindeutig identifizieren. Mit putExtra(String, Bundle) können Sie dem Intent zusätzliche Informationen anhängen. Sie können eine Broadcast-Nachricht auch auf eine Reihe von Apps in derselben Organisation beschränken, indem Sie setPackage(String) für den Intent aufrufen.
Übertragungen 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 einer Broadcast-Nachricht erzwingen.
Nachrichten 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. Mit dem folgenden Code wird beispielsweise ein Broadcast mit einer Berechtigung gesendet:
Kotlin
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION)
Java
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION);
Damit die empfangende App die Broadcast-Nachricht 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 eine benutzerdefinierte Berechtigung mit dem Element <permission> definieren. Informationen zu Berechtigungen und Sicherheit im Allgemeinen finden Sie unter Systemberechtigungen.
Broadcasts mit Berechtigungen empfangen
Wenn Sie beim Registrieren eines Übertragungsempfängers einen Berechtigungsparameter angeben (entweder mit registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) oder im Tag <receiver> in Ihrem Manifest), können nur Broadcaster, die die Berechtigung mit dem Tag <uses-permission> in ihrem Manifest angefordert haben, einen Intent an den Empfänger senden. Wenn die Berechtigung gefährlich ist, muss sie auch dem Broadcaster gewährt werden.
Angenommen, Ihre Empfänger-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 beim Senden und Empfangen von Broadcasts:
Wenn viele Apps im Manifest für den Empfang desselben Broadcasts registriert sind, kann das System viele Apps starten, was sich erheblich auf die Geräteleistung und die Nutzerfreundlichkeit auswirkt. Um dies zu vermeiden, sollten Sie die Kontextregistrierung der Manifestdeklaration vorziehen. Manchmal erzwingt das Android-System selbst die Verwendung von kontextregistrierten Empfängern. Die Übertragung
CONNECTIVITY_ACTIONwird beispielsweise nur an kontextregistrierte Empfänger gesendet.Senden Sie keine vertraulichen Informationen über eine implizite Intention. Jede App kann die Informationen lesen, wenn sie sich für den Empfang des Broadcasts registriert. Es gibt drei Möglichkeiten, festzulegen, wer deine Übertragungen sehen kann:
- Sie können beim Senden einer Broadcast-Nachricht eine Berechtigung angeben.
- Unter Android 4.0 (API-Level 14) und höher können Sie beim Senden eines Broadcasts mit
setPackage(String)ein package angeben. Das System beschränkt den Broadcast auf die Apps, die mit dem Paket übereinstimmen.
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 von Ihrer App empfangenen Broadcasts einzuschränken:
- Sie können eine Berechtigung angeben, wenn Sie einen Übertragungsempfänger registrieren.
- Bei im Manifest deklarierten Broadcast-Empfängern können Sie das Attribut android:exported im Manifest auf „false“ 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 werden, der Ihnen gehört. Andernfalls kann es zu unbeabsichtigten Konflikten mit anderen Apps kommen.
Da die
onReceive(Context, Intent)-Methode eines Empfängers im Hauptthread ausgeführt wird, sollte sie schnell ausgeführt und zurückgegeben werden. Wenn Sie langwierige Aufgaben ausführen müssen, sollten Sie keine Threads erstellen oder Hintergrunddienste starten, da das System den gesamten Prozess nach der Rückgabe vononReceive()beenden kann. Weitere Informationen finden Sie unter Auswirkungen auf den Prozessstatus. Für Vorgänge mit langer Ausführungszeit empfehlen wir Folgendes:- Rufen Sie
goAsync()in der MethodeonReceive()Ihres Receivers auf und übergeben SieBroadcastReceiver.PendingResultan einen Hintergrundthread. Dadurch bleibt die Übertragung aktiv, wenn du vononReceive()zurückkehrst. Auch bei diesem Ansatz erwartet das System jedoch, dass du die Übertragung sehr schnell (in weniger als 10 Sekunden) beendest. So können Sie Aufgaben in einen anderen Thread verschieben, um den Hauptthread nicht zu überlasten. - Planen eines Jobs mit
JobSchedulerWeitere Informationen finden Sie unter Intelligent Job Scheduling.
- Rufen Sie
Starten Sie keine Aktivitäten über Broadcast-Empfänger, da dies die Nutzerfreundlichkeit beeinträchtigt, insbesondere wenn es mehrere Empfänger gibt. Stattdessen sollten Sie eine Benachrichtigung anzeigen.