Broadcast Receiver is an Android component that listens to and processes system Broadcast messages, such as network state changes, battery level, SMS reception, or app installation. It is launched by the operating system when an event occurs and executes its task on the main thread or through a background service. According to the Android Developer Guide, 2026, Broadcast Receiver allows an application to react to global system events even when it is not running, making it a key mechanism for background event processing in the Android ecosystem.
Key Takeaways
Broadcast Receiver is an Android component designed to receive and process Intent messages distributed by the operating system or other applications. Unlike Activity and Service, Broadcast Receiver has no user interface — its task is to execute a short action when an event occurs.
Broadcast Receiver works through the Intent mechanism. The system or an application sends an Intent via sendBroadcast or sendOrderedBroadcast, and the operating system delivers it to registered receivers. Each receiver receives the Intent in the onReceive method, which executes on the main thread.
According to the Android Compatibility Definition Document, a Broadcast Receiver must complete onReceive within 10 seconds — otherwise the system considers it hung and terminates the process. For long-running background tasks, use JobScheduler or WorkManager launched from the receiver.
Android supports two main types of Broadcasts: Normal Broadcast and Ordered Broadcast. The difference lies in delivery order and the ability to interrupt the processing chain. Additionally, Broadcasts are divided into system (generated by the OS) and custom (created by the application).
Normal Broadcast is delivered to all registered receivers asynchronously without guaranteed order. The system may process such Broadcasts in parallel — each receiver gets the Intent in its own thread. Calling abortBroadcast on Normal Broadcast has no effect: delivery to other receivers cannot be cancelled.
Ordered Broadcast is delivered sequentially — to each receiver in descending order of the android:priority attribute (from 0 to 999). After processing, the receiver can pass the result to the next one via setResultExtras or interrupt the chain by calling abortBroadcast. This is used for scenarios where processing order matters — for example, SMS receivers.
Android generates many system Broadcasts: ACTION_BOOT_COMPLETED (device boot), ACTION_BATTERY_LOW, ACTION_POWER_CONNECTED, CONNECTIVITY_ACTION, ACTION_PACKAGE_ADDED, and others. Each Intent contains additional data in Extras — battery level, connection type, package name.
| Broadcast Type | Order | abortBroadcast | Performance |
|---|---|---|---|
| Normal | Not guaranteed | Does not work | High (parallel) |
| Ordered | By priority | Works | Medium (sequential) |
| Sticky | Single value | Not applicable | Low (deprecated since API 21) |
Sticky Broadcast is a deprecated type that kept the last sent value. Instead, use LiveData, StateFlow, or shared SharedPreferences to store the latest state.
Broadcast Receiver can be registered in two ways: statically via AndroidManifest.xml or dynamically in code via registerReceiver. The choice depends on the scenario: static registration works even if the application is not running, dynamic registration only works while the registering component is active.
Static registration is declared in the manifest with the <receiver> tag inside <application>. For each receiver, the handler class and an Intent filter with the actions to intercept are specified. The system loads such receivers when a Broadcast occurs even if the application is not running.
<!-- Static Broadcast Receiver registration in manifest -->
<receiver android:name=".BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Dynamic registration is performed using the registerReceiver method in Activity, Service, or Fragment code. The receiver lives only as long as the component that registered it is alive. Always call unregisterReceiver in onPause or onDestroy — otherwise a memory leak occurs, and the system may terminate the process.
For Ordered Broadcast, the delivery order is determined by the android:priority attribute. A receiver with a higher priority gets the Intent first. If it calls abortBroadcast after processing, receivers with lower priority will not receive the Intent. For static receivers, priority is set in the manifest's Intent filter.
Receivers in Ordered Broadcast can pass data to the next in the chain via setResultExtras or setResultData. This allows pipeline processing: the first receiver enriches the Intent with additional data, the second uses it, the third completes the chain. The getResultExtras method reads data passed by the previous receiver.
For Normal Broadcast, order is not guaranteed, so all receivers get the original Intent unchanged. If you need receivers to affect each other, use sendOrderedBroadcast instead of sendBroadcast.
Android 8 (API 26, Oreo) introduced significant restrictions on background Broadcasts. Most implicit Broadcasts — those not addressed to a specific application — no longer work with static registration. The system blocks receivers registered in the manifest for actions such as CONNECTIVITY_ACTION or ACTION_BATTERY_LOW.
Google has fixed a list of Broadcasts that continue to work with static registration: BOOT_COMPLETED, TIME_TICK, Alarm, and package changes — about a dozen exceptions total. All other implicit Broadcasts now require dynamic registration via Context.registerReceiver, which only works when the app is in the foreground.
For background tasks that were previously handled through Broadcast Receiver, Android recommends WorkManager (deferred tasks with execution guarantee), JobScheduler (periodic tasks considering device state), and NotificationListenerService (notification monitoring). These components work without Android 8 restrictions and are optimized for power consumption.
Let's create a Broadcast Receiver for tracking network connectivity. The receiver will capture the CONNECTIVITY_ACTION Broadcast and log the connection type. For Android 8+, we will register it dynamically since this is an implicit Broadcast excluded from static registration.
// Broadcast Receiver for network state tracking
class NetworkReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = cm.activeNetwork
val caps = cm.getNetworkCapabilities(network)
val connectionType = when {
caps?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true -> "WiFi"
caps?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> "Cellular"
else -> "Disconnected"
}
Log.d("NetworkReceiver", "Connection type: $connectionType")
}
}
// Dynamic registration in Activity
class MainActivity : AppCompatActivity() {
private val networkReceiver = NetworkReceiver()
override fun onStart() {
super.onStart()
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
registerReceiver(networkReceiver, filter)
}
override fun onStop() {
super.onStop()
unregisterReceiver(networkReceiver)
}
}
Always unregister the receiver in onStop — if the Activity goes to the background but the receiver remains registered, the system cannot free resources. For Service, use onDestroy. In fragments, register the receiver in onStart and unregister in onStop, following the fragment lifecycle.
Frequently Asked Questions
Broadcast Receiver is an Android component for processing system and custom Broadcast messages. It receives an Intent in the onReceive method, which runs on the main thread, and must complete within 10 seconds. For long-running tasks, use WorkManager or JobScheduler.
Normal Broadcast is delivered to all receivers asynchronously and in parallel — order is not guaranteed, abortBroadcast does not work. Ordered Broadcast is delivered sequentially by priority, each receiver can interrupt the chain or pass data to the next via setResultExtras.
Static registration (in the manifest) allows the receiver to work even if the application is not running. Dynamic registration (via registerReceiver) only works while the registering component is active. Starting with Android 8, many implicit Broadcasts require dynamic registration.
Android 8 (API 26) prohibited static registration for most implicit Broadcasts, such as CONNECTIVITY_ACTION or ACTION_BATTERY_LOW. Exceptions include BOOT_COMPLETED, Alarm, time, and a few others. For background tasks, use WorkManager instead of Broadcast.
Use LiveData, StateFlow, EventBus, or LocalBroadcastManager to pass data from onReceive to the UI. Do not try to update the UI directly from onReceive — it runs on the main thread, but the receiver does not guarantee the Activity is visible. LocalBroadcastManager is a deprecated option for internal communication.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also