Broadcasts – Übersicht

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:

  1. 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")
    }
  2. Erstellen Sie eine Instanz von BroadcastReceiver:

    Kotlin

    val myBroadcastReceiver = MyBroadcastReceiver()
    

    Java

    MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
    
  3. 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");
    
  4. 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 Flag RECEIVER_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;
    
  5. Registrieren Sie den Empfänger mit registerReceiver():

    Kotlin

    ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)
    

    Java

    ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);
    
  6. 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:

  • LifecycleResumeEffect oder Aktivitätslebenszyklusmethoden onResume/onPause: Der Übertragungsempfänger erhält nur Updates, wenn sich die App im fortgesetzten Zustand befindet.
  • LifecycleStartEffect oder Aktivitätslebenszyklusmethoden onStart/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/onDestroy der Activity: Der Übertragungsempfänger erhält Updates, wenn sich die Activity im erstellten Zustand befindet. Heben Sie die Registrierung in onDestroy() und nicht in onSaveInstanceState(Bundle) auf, da diese möglicherweise nicht aufgerufen wird.
  • Ein benutzerdefinierter Bereich: Sie können beispielsweise einen Empfänger im Bereich ViewModel registrieren, 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:

  1. 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.

  2. Erstellen Sie eine Unterklasse von BroadcastReceiver und implementieren Sie onReceive(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 Attribut android:priority des 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_ACTION Broadcast 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, nachdem onReceive() 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ängers goAsync() auf und übergeben Sie BroadcastReceiver.PendingResult an einen Hintergrund thread. Dadurch bleibt der Broadcast aktiv, nachdem onReceive() 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.
  • 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.