Aplikacje na Androida wysyłają i odbierają wiadomości rozgłoszeniowe z systemu Android oraz z innych aplikacji na Androida w sposób podobny do wzorca projektowania publikowanie i subskrybowanie. System i aplikacje zwykle wysyłają transmisje po wystąpieniu określonych zdarzeń. Na przykład system Android wysyła transmisje, gdy występują różne zdarzenia systemowe, takie jak uruchamianie systemu lub ładowanie urządzenia. Aplikacje wysyłają też transmisje niestandardowe, aby na przykład powiadomić inne aplikacje o czymś, co może je zainteresować (np. o nowym pobieraniu danych).
Aplikacje mogą się rejestrować, aby otrzymywać określone transmisje. Gdy wysyłasz transmisję, system automatycznie kieruje ją do aplikacji, które subskrybują ten konkretny typ transmisji.
Ogólnie rzecz biorąc, transmisje mogą służyć jako system przesyłania wiadomości w aplikacjach i poza normalnym przepływem informacji. Musisz jednak uważać, aby nie nadużywać możliwości reagowania na transmisje i wykonywania zadań w tle, ponieważ może to spowolnić działanie systemu.
Komunikaty systemowe
System automatycznie wysyła transmisje podczas różnych zdarzeń systemowych, takich jak włączenie i wyłączenie trybu samolotowego. Wszystkie subskrybowane aplikacje otrzymują te transmisje.
Obiekt Intent
otacza wiadomość z rozgłaszaniem. Ciąg tekstowy action
wskazuje, które zdarzenie wystąpiło, np. android.intent.action.AIRPLANE_MODE
.
Intencja może też zawierać dodatkowe informacje w polu dodatkowym.
Na przykład działanie trybu samolotowego zawiera dodatkową wartość logiczną, która wskazuje, czy tryb samolotowy jest włączony.
Więcej informacji o czytaniu intencji i pobieraniu ciągu działania z intencji znajdziesz w artykule Intencje i filtry intencji.
Działania związane z komunikatem systemowym
Pełna lista działań systemowych dotyczących transmisji znajdzie się w pliku BROADCAST_ACTIONS.TXT
w pakiecie Android SDK. Z każdym działaniem związany jest określony typ pola. Na przykład wartość stałej ACTION_AIRPLANE_MODE_CHANGED
to android.intent.action.AIRPLANE_MODE
.
Dokumentacja dotycząca każdego działania w transmisji jest dostępna w powiązanym z nim polu statycznym.
Zmiany w komunikatach systemowych
Wraz z rozwojem platformy Android okresowo zmienia się sposób działania transmisji systemowych. Aby zapewnić obsługę wszystkich wersji Androida, pamiętaj o następujących zmianach.
Android 14
Gdy aplikacje są w stanie pamięci podręcznej, system optymalizuje dostarczanie transmisji w celu zapewnienia prawidłowego działania systemu. Podczas gdy aplikacja jest w stanie buforowania, system opóźnia mniej ważne transmisje, takie jak ACTION_SCREEN_ON
.
Gdy aplikacja przejdzie ze stanu buforowania do cyklu życia aktywnego procesu, system dostarczy opóźnione transmisje.
Ważne transmisje ogłoszone w pliku manifestu tymczasowo usuwają aplikacje z pamięci podręcznej na potrzeby ich dostarczenia.
Android 9
Począwszy od Androida 9 (poziom interfejsu API 28) transmisja NETWORK_STATE_CHANGED_ACTION
nie otrzymuje informacji o lokalizacji użytkownika ani danych umożliwiających identyfikację osoby.
Jeśli aplikacja jest zainstalowana na urządzeniu z Androidem w wersji 9.0 (poziom interfejsu API 28) lub nowszej, system nie uwzględnia w transmisjach Wi-Fi nazw SSID, nazw BSSID, informacji o połączeniu ani wyników skanowania. Aby uzyskać te informacje, zadzwoń pod numer getConnectionInfo()
.
Android 8.0
Począwszy od Androida 8.0 (poziom interfejsu API 26) system nakłada dodatkowe ograniczenia na odbiorniki zadeklarowane w pliku manifestu.
Jeśli Twoja aplikacja jest kierowana na Androida 8.0 lub nowszego, nie możesz użyć pliku manifestu do zadeklarowania odbiornika dla większości niejawnych transmisji (transmisji, które nie są kierowane bezpośrednio na Twoją aplikację). Nadal możesz używać odbiornika zarejestrowanego w kontekście, gdy użytkownik aktywnie korzysta z aplikacji.
Android 7.0
Android 7.0 (poziom interfejsu API 24) i nowsze nie wysyłają tych transmisji systemowych:
Aplikacje kierowane na Androida 7.0 lub nowszego muszą zarejestrować transmisję CONNECTIVITY_ACTION
za pomocą registerReceiver(BroadcastReceiver, IntentFilter)
. Oświadczenie odbiorcy w pliku manifestu nie działa.
Odbieranie transmisji
Aplikacje mogą odbierać transmisje na 2 sposoby: za pomocą odbiorników zarejestrowanych w kontekście lub za pomocą odbiorników zadeklarowanych w pliku manifestu.
Odbiorcom zarejestrowanym w kontekście
Odbiorniki zarejestrowane w kontekście otrzymują transmisje, dopóki ich kontekst rejestracji jest prawidłowy. Zwykle jest to między wywołaniami registerReceiver
i unregisterReceiver
. Kontekst rejestracji staje się nieprawidłowy, gdy system zniszczy odpowiedni kontekst. Jeśli na przykład zarejestrujesz się w kontekście Activity
, będziesz otrzymywać transmisje tak długo, jak długo będzie aktywna dana aktywność. Jeśli zarejestrujesz się w kontekście aplikacji, będziesz otrzymywać transmisje przez cały czas działania aplikacji.
Aby zarejestrować odbiornik w kontekście:
W pliku kompilacji na poziomie modułu aplikacji dołącz bibliotekę AndroidX Core w wersji 1.9.0 lub nowszej:
Odlotowe
dependencies { def core_version = "1.13.1" // 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.13.1" // 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") }
Utwórz instancję
BroadcastReceiver
:Kotlin
val myBroadcastReceiver = MyBroadcastReceiver()
Java
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
Utwórz instancję
IntentFilter
:Kotlin
val filter = IntentFilter("com.example.snippets.ACTION_UPDATE_DATA")
Java
IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");
Wybierz, czy odbiornik strumienia ma być eksportowany i widoczny dla innych aplikacji na urządzeniu. Jeśli ten odbiornik nasłuchuje transmisji wysyłanych z systemu lub z innych aplikacji (nawet innych aplikacji należących do Ciebie), użyj flagi
RECEIVER_EXPORTED
. Jeśli odbiornik ma słuchać tylko transmisji wysyłanych przez Twoją aplikację, użyj flagiRECEIVER_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;
Zarejestruj odbiorcę, dzwoniąc na numer
registerReceiver()
:Kotlin
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)
Java
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);
Aby przestać otrzymywać transmisje, zadzwoń pod numer
unregisterReceiver(android.content.BroadcastReceiver)
. Pamiętaj, aby anulować rejestrację odbiornika, gdy nie będzie już potrzebny lub gdy kontekst przestanie być prawidłowy.
Rejestrowanie odbiornika transmisji
Podczas rejestrowania odbiornika transmisji jest on powiązany z kontekstem, w którym został zarejestrowany. Może to spowodować wycieki danych, jeśli zarejestrowany zakres odbiorcy wykracza poza zakres cyklu życia kontekstu. Może się to zdarzyć, gdy zarejestrujesz odbiornik w zakresie aktywności, ale zapomnisz go odrejestrować, gdy system zniszczy aktywność. Dlatego zawsze odrejestruj odbiornik transmisji.
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
}
}
Rejestrowanie odbiorników w najmniejszym zakresie
Odbiornik transmisji powinien być zarejestrowany tylko wtedy, gdy rzeczywiście interesuje Cię wynik. Wybierz jak najmniejszy możliwy zakres odbiorczy:
LifecycleResumeEffect
lub metody cyklu życia aktywnościonResume
/onPause
: odbiornik transmisji otrzymuje aktualizacje tylko wtedy, gdy aplikacja jest wznowiona.LifecycleStartEffect
lub metody cyklu życia aktywnościonStart
/onStop
: odbiornik transmisji otrzymuje aktualizacje tylko wtedy, gdy aplikacja jest wznowiona.DisposableEffect
: odbiornik transmisji otrzymuje aktualizacje tylko wtedy, gdy kompozyt znajduje się w drzewie kompozycji. Ten zakres nie jest powiązany z zakresem cyklu życia aktywności. Rozważ zarejestrowanie odbiornika w kontekście aplikacji. Dzieje się tak, ponieważ komponent może teoretycznie przetrwać okres życia aktywności i wyciekać z niej.- Aktywność
onCreate
/onDestroy
: odbiornik transmisji otrzymuje aktualizacje, gdy aktywność jest w stanie utworzona. Pamiętaj, aby wyrejestrować się w funkcjionDestroy()
, a nieonSaveInstanceState(Bundle)
, ponieważ ta druga może nie zostać wywołana. - zakres niestandardowy: możesz na przykład zarejestrować odbiornik w zakresie
ViewModel
, aby przetrwał on odtworzenie aktywności; Pamiętaj, aby używać kontekstu aplikacji do rejestrowania odbiornika, ponieważ odbiornik może przetrwać poza zakresem cyklu życia aktywności i wyciekać aktywność.
Tworzenie komponentów stanowych i bezstanowych
Składanka może zawierać komponenty stanowe i bezstanowe. Rejestrowanie lub anulowanie rejestracji odbiornika w ramach usługi kompozytowej powoduje, że usługa staje się zależna od stanu. Funkcja typu „composable” nie jest funkcją deterministyczną, która renderuje ten sam materiał, gdy zostaną przekazane te same parametry. Stan wewnętrzny może się zmieniać w zależności od wywołań zarejestrowanego odbiornika transmisji.
Zgodnie ze sprawdzoną metodą w komponowaniu zalecamy podzielenie komponentów na wersje ze stanem i bez stanu. Dlatego zalecamy przeniesienie funkcji tworzenia odbiornika transmisji z komponowalnego, aby uczynić ją stanową:
@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
}
Odbiorcy zadeklarowani w pliku manifestu
Jeśli w manifeście zadeklarujesz odbiornik transmisji, system uruchomi Twoją aplikację, gdy zostanie wysłana transmisja. Jeśli aplikacja nie jest jeszcze uruchomiona, system ją uruchamia.
Aby zadeklarować odbiornik transmisji w pliku manifestu, wykonaj te czynności:
W pliku manifestu aplikacji określ element
<receiver>
.<!-- 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>
Filtry intencji określają działania przesyłania, do których subskrybuje odbiorca.
Utwórz podklasę
BroadcastReceiver
i zaimplementujonReceive(Context, Intent)
. W tym przykładzie odbiornik transmisji zapisuje i wyświetla zawartość transmisji: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); } } } }
Menedżer pakietów systemowych rejestruje odbiornik po zainstalowaniu aplikacji. Odbiornik staje się wtedy osobnym punktem wejścia do aplikacji, co oznacza, że system może uruchomić aplikację i przekazać transmisję, nawet jeśli aplikacja nie jest uruchomiona.
System tworzy nowy obiekt komponentu BroadcastReceiver
, aby obsługiwać każdą otrzymaną transmisję. Ten obiekt jest ważny tylko przez czas trwania połączenia z onReceive(Context, Intent)
. Gdy kod zwróci wartość z tego metody, system uzna, że komponent nie jest już aktywny.
Wpływ na stan procesu
To, czy BroadcastReceiver
działa, wpływa na zawarty w nim proces, co może zmienić prawdopodobieństwo uszkodzenia systemu. Proces na pierwszym planie wykonuje metodę onReceive()
odbiorcy. System uruchamia proces, z wyjątkiem sytuacji, gdy dochodzi do ekstremalnego obciążenia pamięci.
System dezaktywuje BroadcastReceiver
po onReceive()
.
Znaczenie procesu hosta odbiorcy zależy od komponentów aplikacji. Jeśli proces hostuje tylko odbiornik zadeklarowany w pliku manifestu, system może go zakończyć po onReceive()
, aby zwolnić zasoby dla innych, ważniejszych procesów. Jest to typowe w przypadku aplikacji, z których użytkownik nigdy nie korzystał lub z których nie korzystał od dłuższego czasu.
Dlatego odbiorniki transmisji nie powinny inicjować długotrwałych wątków w tle.
System może przerwać proces w dowolnym momencie po onReceive()
, aby odzyskać pamięć, i w ten sposób zakończyć utworzony wątek. Aby proces nie został przerwany, zaplanuj JobService
z urządzenia odbiorczego za pomocą polecenia JobScheduler
, aby system wiedział, że proces jest nadal aktywny. Więcej informacji znajdziesz w omówieniu pracy w tle.
Wysyłanie transmisji
Aplikacje na Androida mogą wysyłać transmisje na 2 sposoby:
- Metoda
sendOrderedBroadcast(Intent, String)
wysyła transmisje do jednego odbiorcy naraz. Każdy odbiorca wykonuje kod kolejno, przekazując wynik do następnego odbiorcy. Może też całkowicie przerwać transmisję, aby nie dotarła do innych odbiorników. Możesz kontrolować kolejność, w jakiej odbiorcy są wywoływani. Aby to zrobić, użyj atrybutu android:priority filtra intencji dopasowującego. Odbiorcy o tym samym priorytecie są wywoływane w dowolnej kolejności. - Metoda
sendBroadcast(Intent)
wysyła transmisje do wszystkich odbiorców w niezdefiniowanej kolejności. Taki rodzaj transmisji nazywamy transmisją normalną. Jest to bardziej wydajne, ale oznacza, że odbiorcy nie mogą odczytać wyników z innych odbiorników, rozpowszechniać danych otrzymanych z transmisji ani przerywać transmisji.
Ten fragment kodu pokazuje, jak wysłać transmisję, tworząc intencję i wywołując sendBroadcast(Intent)
.
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);
Wiadomość rozgłoszeniowa jest ujęta w obiekt Intent
. Ciąg znaków action
w intencji musi zawierać składnię nazwy pakietu aplikacji w języku Java oraz jednoznacznie identyfikować zdarzenie transmisji. Możesz dołączyć dodatkowe informacje do intencjonalnego korzystania z putExtra(String, Bundle)
. Możesz też ograniczyć transmisję do zbioru aplikacji w tej samej organizacji, wywołując setPackage(String)
w intencji.
Ograniczanie transmisji za pomocą uprawnień
Uprawnienia umożliwiają ograniczenie transmisji do zestawu aplikacji, które mają określone uprawnienia. Możesz narzucić ograniczenia nadawcy lub odbiorcy transmisji.
Wysyłanie transmisji z uprawnieniami
Gdy wywołujesz metodę sendBroadcast(Intent, String)
lub sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String,
Bundle)
, możesz określić parametr uprawnień. Transmisję mogą odbierać tylko odbiorcy, którzy poprosili o to oznaczenie w pliku manifestu za pomocą tagu <uses-permission>
. Jeśli uprawnienia są niebezpieczne, musisz je przyznać, zanim odbiorca będzie mógł odebrać transmisję. Na przykład ten kod wysyła transmisję z uprawnieniem:
Kotlin
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION)
Java
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION);
Aby odbierać transmisje, aplikacja odbiorcza musi poprosić o uprawnienia w ten sposób:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Możesz określić istniejące uprawnienie systemowe, np. BLUETOOTH_CONNECT
, lub zdefiniować uprawnienie niestandardowe za pomocą elementu <permission>
. Informacje o uprawnieniach i zabezpieczeniach znajdziesz w artykule Uprawnienia systemowe.
Odbieranie transmisji z uprawnieniami
Jeśli podczas rejestrowania odbiornika transmisji użyjesz parametru uprawnień (w tagu registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
lub <receiver>
w pliku manifestu), tylko nadawcy, którzy poprosili o uprawnienia za pomocą tagu <uses-permission>
w pliku manifestu, mogą wysyłać intencje do odbiornika. Jeśli uprawnienia są niebezpieczne, nadawca musi je również uzyskać.
Załóżmy na przykład, że aplikacja odbiorcza ma w deklaracji w manifeście odbiornik o takim wyglądzie:
<!-- 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>
Aplikacja odbiorcza może też mieć odbiornik rejestrowany w kontekście w ten sposób:
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
);
Aby móc wysyłać transmisje do tych odbiorców, aplikacja wysyłająca musi poprosić o dostęp w ten sposób:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Zagadnienia związane z bezpieczeństwem
Oto kilka kwestii związanych z bezpieczeństwem przesyłania i odbierania transmisji:
Jeśli wiele aplikacji w swoim pliku manifestu zarejestrowało się do odbioru tej samej transmisji, może to spowodować uruchomienie przez system wielu aplikacji, co może mieć znaczący wpływ zarówno na wydajność urządzenia, jak i wrażenia użytkownika. Aby tego uniknąć, użyj rejestracji kontekstu zamiast deklaracji w pliku manifestu. Czasami system Androida sam wymusza używanie odbiorników zarejestrowanych w kontekście. Na przykład transmisja
CONNECTIVITY_ACTION
jest dostarczana tylko do odbiorników zarejestrowanych w kontekście.Nie przekazuj informacji poufnych za pomocą niejawnych intencji. Każda aplikacja może odczytać te informacje, jeśli zarejestruje się do odbioru transmisji. Możesz kontrolować, kto może odbierać Twoje transmisje na 3 sposoby:
- Podczas wysyłania transmisji możesz określić uprawnienia.
- W Androidzie 4.0 (poziom interfejsu API 14) i nowszych podczas wysyłania transmisji możesz określić pakiet za pomocą
setPackage(String)
. System ogranicza transmisję do zestawu aplikacji dopasowanych do pakietu.
Gdy zarejestrujesz odbiornik, każda aplikacja może wysyłać do niego potencjalnie szkodliwe transmisje. Możesz ograniczyć liczbę transmisji, które otrzymuje Twoja aplikacja, na kilka sposobów:
- Podczas rejestrowania odbiornika transmisji możesz określić uprawnienia.
- W przypadku odbiorników zadeklarowanych w pliku manifestu możesz ustawić w nim atrybut android:exported na „false”. Odbiornik nie odbiera transmisji ze źródeł spoza aplikacji.
Przestrzeń nazw akcji przesyłania jest globalna. Upewnij się, że nazwy działań i inne ciągi znaków są zapisane w Twojej przestrzeni nazw. W przeciwnym razie możesz przypadkowo zakłócić działanie innych aplikacji.
Metoda
onReceive(Context, Intent)
odbiornika działa na głównym wątku, więc powinna się szybko wykonać i zwrócić. Jeśli musisz wykonać długotrwałe zadanie, uważaj na tworzenie wątków lub uruchamianie usług w tle, ponieważ system może zakończyć cały proces po zwróceniu wartości przez funkcjęonReceive()
. Więcej informacji znajdziesz w sekcji Wpływ na stan procesu. Aby wykonać długotrwałe zadanie, zalecamy:- Wywoływanie metody
goAsync()
w metodzieonReceive()
odbiorcy i przekazywanie parametruBroadcastReceiver.PendingResult
do wątku w tle. Dzięki temu transmisja będzie aktywna po powrocie zonReceive()
. Jednak nawet w tym przypadku system wymaga, aby zakończyć transmisję bardzo szybko (w mniej niż 10 sekund). Umożliwia to przeniesienie pracy do innego wątku, aby uniknąć błędów w głównym wątku. - planowania zadania za pomocą
JobScheduler
; Więcej informacji znajdziesz w artykule Inteligentne planowanie zadań.
- Wywoływanie metody
Nie uruchamiaj działań z odbiorników transmisji, ponieważ może to zakłócić działanie aplikacji, zwłaszcza jeśli jest więcej niż 1 odbiornik. Zamiast tego możesz wyświetlić powiadomienie.