Broadcasts – Übersicht

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:

  1. 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")
    }
  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 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 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 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-Methoden onResume/onPause: Der Übertragungsempfänger empfängt nur Updates, wenn sich die App im fortgesetzten Zustand befindet.
  • LifecycleStartEffect- oder Aktivitäts-Lifecycle-Methoden onStart/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 in onDestroy() und nicht in onSaveInstanceState(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:

  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 Broadcast-Aktionen an, für die Ihr Empfänger registriert ist.

  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 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 Attribut android:priority des 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_ACTION wird 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 von onReceive() 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 Methode onReceive() Ihres Receivers auf und übergeben Sie BroadcastReceiver.PendingResult an einen Hintergrundthread. Dadurch bleibt die Übertragung aktiv, wenn du von onReceive() 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 JobScheduler Weitere Informationen finden Sie unter Intelligent Job Scheduling.
  • 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.