Broadcasts – Übersicht

Android-Apps senden und empfangen Broadcast-Nachrichten vom Android-System und anderen Android-Apps, ähnlich wie beim Publish-Subscribe-Designpattern. Das System und die Apps senden in der Regel Broadcasts, wenn bestimmte Ereignisse auftreten. So sendet das Android-System beispielsweise Broadcasts, wenn verschiedene Systemereignisse auftreten, z. B. das Starten des Systems oder das Laden des Geräts. Apps senden auch benutzerdefinierte Broadcasts, um andere Apps beispielsweise über etwas zu informieren, das sie interessieren könnte (z. B. einen neuen Datendownload).

Apps können sich registrieren, um bestimmte Mitteilungen zu erhalten. Wenn eine Übertragung gesendet wird, leitet das System sie automatisch an Apps weiter, die den Empfang dieser Art von Übertragung abonniert haben.

Im Allgemeinen können Broadcasts als Messaging-System für mehrere Apps und außerhalb des normalen Nutzerflusses verwendet werden. Sie sollten jedoch darauf achten, die Möglichkeit, auf Übertragungen zu reagieren und Jobs im Hintergrund auszuführen, nicht zu missbrauchen, da dies zu einer Verlangsamung der Systemleistung führen kann.

Systemnachrichten

Das System sendet automatisch Broadcasts, wenn verschiedene Systemereignisse auftreten, z. B. wenn der Flugmodus aktiviert oder deaktiviert wird. Alle abonnierten Apps erhalten diese Übertragungen.

Das Intent-Objekt umschließt die Broadcast-Nachricht. Der String action identifiziert das aufgetretene Ereignis, z. B. android.intent.action.AIRPLANE_MODE. Die Absicht kann auch zusätzliche Informationen im Extra-Feld enthalten. Der Intent „Flugmodus“ enthält beispielsweise ein boolesche Extra, das angibt, ob der Flugmodus aktiviert ist oder nicht.

Weitere Informationen zum Lesen von Intents und zum Abrufen des Aktionsstrings aus einem Intent finden Sie unter Intents und Intent-Filter.

Aktionen für Systemnachrichten

Eine vollständige Liste der System-Broadcast-Aktionen finden Sie in der Datei BROADCAST_ACTIONS.TXT im Android SDK. Jede Übertragungsaktion ist mit einem Konstantenfeld verknüpft. Der Wert der Konstante ACTION_AIRPLANE_MODE_CHANGED ist beispielsweise android.intent.action.AIRPLANE_MODE. Die Dokumentation für jede Broadcastaktion ist im zugehörigen Konstantenfeld verfügbar.

Änderungen an Systemmeldungen

Im Zuge der Weiterentwicklung der Android-Plattform ändern sich regelmäßig die Verhaltensweisen von Systemweitergaben. Beachten Sie die folgenden Änderungen, damit alle Android-Versionen unterstützt werden.

Android 14

Wenn sich Apps im Cache-Status befinden, optimiert das System die Übertragung für die Systemzuverlässigkeit. Beispielsweise werden weniger wichtige System-Broadcasts wie ACTION_SCREEN_ON verzögert, wenn sich die App im Cache-Status befindet. Sobald die App den Cache-Status verlässt und sich in einem aktiven Prozesszyklus befindet, sendet das System alle verzögerten Übertragungen.

Bei wichtigen Übertragungen, die im Manifest deklariert sind, werden Apps vorübergehend aus dem Cache-Status für die Auslieferung entfernt.

Android 9

Ab Android 9 (API-Ebene 28) werden über die Übertragung von NETWORK_STATE_CHANGED_ACTION keine Informationen zum Standort des Nutzers oder personenidentifizierbare 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 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 Übertragungen deklarieren (Übertragungen, die nicht speziell auf Ihre App ausgerichtet sind). Sie können einen kontextregistrierten Empfänger auch dann verwenden, wenn der Nutzer Ihre App aktiv nutzt.

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, die CONNECTIVITY_ACTION-Ausstrahlung mit registerReceiver(BroadcastReceiver, IntentFilter) registrieren. Die Deklarierung eines Empfängers im Manifest funktioniert nicht.

Übertragungen empfangen

Apps können Streams auf zwei Arten empfangen: über im Kontext registrierte Empfänger und im Manifest deklarierte Empfänger.

Kontextregistrierte Empfänger

Kontextregistrierte Empfänger erhalten Übertragungen, solange der Registrierungskontext gültig ist. Dies 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, erhalten Sie Mitteilungen, solange die Aktivität aktiv bleibt. Wenn Sie sich mit dem Anwendungskontext registrieren, erhalten Sie Streams, 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 der AndroidX Core Library hinzu:

    Groovy

    dependencies {
        def core_version = "1.15.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.0.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-alpha02"
    }

    Kotlin

    dependencies {
        val core_version = "1.15.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.0.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-alpha02")
    }
  2. So erstellen Sie eine Instanz von BroadcastReceiver:

    Kotlin

    val myBroadcastReceiver = MyBroadcastReceiver()
    

    Java

    MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
    
  3. So 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 Broadcast-Empfänger exportiert und für andere Apps auf dem Gerät sichtbar sein soll. Wenn dieser Empfänger auf Übertragungen 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 Empfänger stattdessen nur auf von Ihrer App gesendete Broadcasts wartet, 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, indem Sie registerReceiver() aufrufen:

    Kotlin

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

    Java

    ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);
    
  6. Wenn Sie keine Übertragungen mehr erhalten möchten, rufen Sie unregisterReceiver(android.content.BroadcastReceiver) an. Heben Sie die Registrierung des Empfängers auf, wenn Sie ihn nicht mehr benötigen oder der Kontext nicht mehr gültig ist.

Übertragungsempfänger abmelden

Solange der Broadcast-Empfänger registriert ist, enthält er einen Verweis auf den Kontext, mit dem Sie ihn registriert haben. Dies kann zu Datenlecks führen, wenn der registrierte Umfang des Empfängers den Umfang des Lebenszyklus des Kontexts überschreitet. Das kann beispielsweise passieren, wenn Sie einen Empfänger auf Aktivitätsebene registrieren, aber vergessen, ihn abzumelden, wenn das System die Aktivität zerstört. Daher sollten Sie Ihren Broadcast-Empfänger immer wieder abmelden.

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 Umfang registrieren

Ihr Broadcast-Empfänger sollte nur registriert werden, wenn Sie tatsächlich an dem Ergebnis interessiert sind. Wählen Sie den kleinstmöglichen Empfängerbereich aus:

  • Lifecycle-Methoden von LifecycleResumeEffect oder Aktivität onResume/onPause: Der Broadcast-Empfänger empfängt nur Updates, während die App fortgesetzt wird.
  • Lifecycle-Methoden von LifecycleStartEffect oder Aktivität onStart/onStop: Der Broadcast-Empfänger empfängt nur Updates, während die App fortgesetzt wird.
  • DisposableEffect: Der Broadcast-Empfänger empfängt nur dann Updates, wenn sich das Composeable im Kompositionbaum befindet. Dieser Umfang ist nicht mit dem Umfang des Aktivitätszyklus verknüpft. Sie können den Empfänger im Anwendungskontext registrieren. Das liegt daran, dass das Composed-Element theoretisch den Aktivitätslebenszyklus überdauern und die Aktivität weitergeben könnte.
  • Aktivität onCreate/onDestroy: Der Broadcast-Empfänger empfängt Updates, während sich die Aktivität im Status „Erstellt“ befindet. Melden Sie sich bei onDestroy() und nicht bei onSaveInstanceState(Bundle) ab, da diese Funktion möglicherweise nicht aufgerufen wird.
  • Benutzerdefinierter Umfang: Sie können beispielsweise einen Empfänger in Ihrem ViewModel-Umfang registrieren, damit er bei der Aktivitätswiederherstellung erhalten bleibt. Verwenden Sie den Anwendungskontext, um den Empfänger zu registrieren, da der Empfänger den Gültigkeitszeitraum des Aktivitätszyklus überdauern und die Aktivität weitergeben kann.

Zustandsorientierte und zustandslose composable erstellen

Compose bietet zustandsorientierte und zustandslose Composables. Wenn Sie einen Broadcast-Empfänger in einem Composeable registrieren oder abmelden, wird es zustandsabhängig. Das Composeable ist keine deterministische Funktion, die bei Übergabe derselben Parameter immer denselben Inhalt rendert. Der interne Status kann sich je nach Aufrufen des registrierten Broadcast-Empfängers ändern.

Als Best Practice in Compose empfehlen wir, Ihre Compose-Objekte in zustandsorientierte und zustandslose Versionen aufzuteilen. Wir empfehlen daher, die Erstellung des Broadcastempfängers aus einem Composable zu entfernen, 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 in Ihrem Manifest einen Broadcast-Empfänger deklarieren, startet das System Ihre App, wenn die Übertragung gesendet wird. Wenn die App noch nicht ausgeführt wird, startet das System sie.

So deklarieren Sie einen Broadcast-Empfänger im Manifest:

  1. 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 Übertragungsaktionen an, für die sich der Empfänger registriert hat.

  2. Erstellen Sie eine Unterklasse von BroadcastReceiver und implementieren Sie onReceive(Context, Intent). Der Broadcast-Empfänger im folgenden Beispiel protokolliert und zeigt den Inhalt der Übertragung 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 Empfänger wird dann zu einem separaten Einstiegspunkt in Ihre App. Das bedeutet, dass das System die App starten und die Übertragung senden kann, wenn die App nicht ausgeführt wird.

Das System erstellt ein neues BroadcastReceiver-Komponentenobjekt, um jede empfangene Übertragung zu verarbeiten. Dieses Objekt ist nur für die Dauer des Aufrufs von onReceive(Context, Intent) gültig. Sobald der Code von dieser Methode zurückgegeben wird, betrachtet das System die Komponente als nicht mehr aktiv.

Auswirkungen auf den Prozessstatus

Ob Ihre BroadcastReceiver aktiv ist oder nicht, wirkt sich auf den enthaltenen Prozess aus, was die Wahrscheinlichkeit erhöhen kann, dass das System zum Absturz gebracht 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 die 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, wird er vom System möglicherweise nach onReceive() beendet, um Ressourcen für andere kritischere Prozesse freizugeben. Das ist häufig bei Apps der Fall, mit denen der Nutzer noch nie oder nicht in letzter Zeit interagiert hat.

Daher sollten Broadcastempfänger keine lang laufenden Hintergrundthreads initiieren. Das System kann den Prozess nach onReceive() jederzeit beenden, um den Arbeitsspeicher zurückzufordern, und den erstellten Thread beenden. Um den Prozess aktiv zu halten, planen Sie mit JobScheduler eine JobService vom Empfänger, damit das System weiß, dass der Prozess noch aktiv ist. Weitere Informationen finden Sie unter Hintergrundarbeit – Übersicht.

Nachrichten an alle senden

Android bietet Apps zwei Möglichkeiten, Streams zu senden:

  • Bei der sendOrderedBroadcast(Intent, String)-Methode werden Übertragungen jeweils an einen Empfänger gesendet. Da jeder Empfänger nacheinander ausgeführt wird, kann er ein Ergebnis an den nächsten Empfänger weitergeben. Es kann auch die Übertragung vollständig abbrechen, damit sie andere Empfänger nicht erreicht. Sie können festlegen, in welcher Reihenfolge die Empfänger ausgeführt werden. Verwenden Sie dazu das Attribut „android:priority“ des übereinstimmenden Intent-Filters. Empfänger mit derselben Priorität werden in einer beliebigen Reihenfolge ausgeführt.
  • Mit der Methode sendBroadcast(Intent) werden Broadcasts in einer nicht definierten Reihenfolge an alle Empfänger gesendet. Dies wird als normaler Stream bezeichnet. Das ist effizienter, bedeutet aber, dass Empfänger keine Ergebnisse von anderen Empfängern lesen, keine Daten aus der Übertragung weitergeben und die Übertragung nicht abbrechen können.

Das folgende Code-Snippet zeigt, wie Sie eine Übertragung 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 Broadcast-Nachricht ist in einem Intent-Objekt verpackt. Der action-String der Intent-Aktion muss die Syntax des Java-Paketnamens der App enthalten und das gestreamte Ereignis eindeutig identifizieren. Mit putExtra(String, Bundle) können Sie dem Intent zusätzliche Informationen hinzufügen. Sie können eine Übertragung auch auf eine Reihe von Apps in derselben Organisation beschränken, indem Sie setPackage(String) auf den Intent aufrufen.

Übertragungen mit Berechtigungen einschränken

Mit Berechtigungen können Sie Übertragungen auf die Apps beschränken, die bestimmte Berechtigungen haben. Sie können Einschränkungen für den Absender oder Empfänger einer Übertragung erzwingen.

Übertragungen 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 die Übertragung empfangen. Wenn die Berechtigung gefährlich ist, müssen Sie sie erteilen, bevor der Empfänger die Übertragung empfangen kann. Im folgenden Code wird beispielsweise eine Broadcast-Nachricht 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 Übertragung empfangen werden kann, muss die Empfänger-App 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.

Übertragungen mit Berechtigungen empfangen

Wenn Sie beim Registrieren eines Broadcast-Empfängers einen Berechtigungsparameter angeben (entweder mit registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) oder im <receiver>-Tag in Ihrem Manifest), können nur Sender, die die Berechtigung mit dem <uses-permission>-Tag in ihrem Manifest angefordert haben, einen Intent an den Empfänger senden. Wenn die Berechtigung gefährlich ist, muss sie auch dem Sender gewährt werden.

Angenommen, Ihre Empfänger-App hat einen im Manifest deklarierten Empfänger folgendermaßen:

<!-- 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 die Empfänger-App hat einen kontextregistrierten Empfänger:

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 dann Übertragungen an diese Empfänger gesendet werden können, muss die sendende App 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 Übertragungen:

  • Wenn sich viele Apps in ihrem Manifest für den Empfang derselben Übertragung registriert haben, kann das System viele Apps starten, was sich erheblich auf die Geräteleistung und die Nutzerfreundlichkeit auswirkt. Verwenden Sie daher die Kontextregistrierung anstelle der Manifestdeklaration. Manchmal erzwingt das Android-System selbst die Verwendung von kontextregistrierten Empfängern. Beispielsweise wird die Übertragung CONNECTIVITY_ACTION nur an im Kontext registrierte Empfänger gesendet.

  • Vertrauliche Informationen dürfen nicht mithilfe einer impliziten Absicht gesendet werden. Jede App kann die Informationen lesen, wenn sie sich für den Empfang der Übertragung registriert. Es gibt drei Möglichkeiten, zu steuern, wer deine Übertragungen empfangen kann:

    • Sie können beim Senden einer Übertragung eine Berechtigung angeben.
    • Unter Android 4.0 (API-Level 14) und höher können Sie beim Senden einer Übertragung ein Paket mit setPackage(String) angeben. Das System schränkt die Übertragung auf die Apps ein, die mit dem Paket übereinstimmen.
  • Wenn Sie einen Empfänger registrieren, kann jede App potenziell schädliche Übertragungen an den Empfänger Ihrer App senden. Es gibt mehrere Möglichkeiten, die Anzahl der Übertragungen zu begrenzen, die Ihre App empfängt:

    • Sie können eine Berechtigung angeben, wenn Sie einen Broadcast-Empfänger registrieren.
    • Bei im Manifest deklarierten Empfängern können Sie das Attribut android:exported im Manifest auf „false“ festlegen. Der Empfänger empfängt keine Übertragungen 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, dessen Inhaber Sie sind. Andernfalls kann es unbeabsichtigt zu 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 lang andauernde Aufgaben ausführen müssen, sollten Sie vorsichtig sein, wenn Sie Threads erstellen oder Hintergrunddienste starten. Das System kann den gesamten Prozess beenden, nachdem onReceive() zurückgegeben wurde. Weitere Informationen finden Sie unter Auswirkung auf den Prozessstatus. Für lang andauernde Aufgaben empfehlen wir Folgendes:

    • Rufe goAsync() in der onReceive()-Methode deines Receivers auf und übergebe BroadcastReceiver.PendingResult an einen Hintergrund-Thread. Dadurch bleibt die Übertragung nach der Rückkehr von onReceive() aktiv. Auch bei diesem Ansatz erwartet das System, dass du die Übertragung sehr schnell beendest (unter 10 Sekunden). Sie können aber Arbeit in einen anderen Thread verschieben, um Fehler im Hauptthread zu vermeiden.
    • Einen Job mit der JobScheduler planen Weitere Informationen finden Sie unter Intelligente Jobplanung.
  • Starten Sie keine Aktivitäten von Broadcastempfängern, da dies die Nutzerfreundlichkeit beeinträchtigt, insbesondere wenn es mehrere Empfänger gibt. Sie können stattdessen eine Benachrichtigung anzeigen.