Android Broadcast Receiver Example

This article is about Android broadcasts, broadcastReceiver, and how to work with the broadcastReceiver with the help of a simple example.

Broadcasts

Broadcasts are messages that the Android system and Android apps send when an event of interest occurs. The broadcast message itself is wrapped in an Intent object.

There are two types of broadcasts:

  • System broadcasts are delivered by the system.
  • Custom broadcasts are delivered by your app.

System broadcasts

system broadcast is a message that the Android system sends when a system event occurs.

System broadcasts are sent to all apps that are subscribed to receive the event.

System broadcasts Example:

  • When the device boots, the system broadcasts a system Intent with the action ACTION_BOOT_COMPLETED.
  • When a wired headset is connected or disconnected, the system sends a system Intent with the action field android.intent.action.HEADSET_PLUG and also contains more data about the event in its extra field, for example, a boolean extra indicating whether a headset is connected or disconnected.

Custom broadcasts

Custom broadcasts are broadcasts that your app sends out. To create a custom broadcast, define a custom Intent action.

For example, use a custom broadcast when you want to let other apps know that data has been downloaded to the device and is available for them to use.

BroadcastReceiver

Broadcast receivers are app components that listen for the events that have been broadcast from apps or from the Android system and respond accordingly.

For instance, if you are implementing a media app and you’re interested in knowing when the user connects or disconnects a headset, register for the ACTION_HEADSET_PLUG intent action.

Follow the two steps to make BroadcastReceiver works for your application:

  • Creating the Broadcast Receiver
  • Registering a BroadcastReceiver / Receiving Broadcasts

Creating the Broadcast Receiver

  • To create a broadcast receiver, define a subclass of the BroadcastReceiver class and implement the onReceive() method. This subclass is where Intent objects are delivered if they match the intent filters you register for.
class MyReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        // logic of the code needs to be written here
    }
}

Registering a BroadcastReceiver

There are two types of broadcast receivers:

  • Static receivers or Manifest-declared receivers: register in the Android manifest file.
  • Dynamic receivers or Context-registered receivers: register using a context.
Manifest-declared receivers

To register a manifest-declared receiver, include the following attributes inside the <receiver> element in your AndroidManifest.xml file:

<receiver android:name=".MyReceiver"  android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.BATTERY_LOW" />
    </intent-filter>
</receiver>
  • android: name: name of the BroadcastReceiver subclass.
  • android: exported (optional): If this boolean value is set to false, other apps cannot send broadcasts to your receiver.
  • <intent-filter>:  specify the broadcast Intent actions that your broadcast receiver component is listening for.

Note: For Android 8.0 (API level 26) and higher, static receivers can’t receive most implicit broadcasts (Implicit broadcasts are broadcasts that don’t target your app specifically). Even if you register for these broadcasts in the manifest, the Android system won’t deliver them to your app. However, you can still use a dynamic receiver to register for these broadcasts. To learn more, see the complete list of implicit broadcast exceptions.

Context-registered receivers

To register a dynamic receiver use an application context or an Activity context. A dynamic receiver receives broadcasts as long as the registering context is valid.

To register a Context-registered receiver, follow the below steps:

1. Create an instance of BroadcastReceiver.

val br: BroadcastReceiver = MyReceiver()

2. Create an instance of IntentFilter and register the receiver by calling registerReceiver(BroadCastReceiver, IntentFilter).

IntentFilter("com.c1ctech.broadcast.CUSTOM_INTENT").also {
    // registering the receiver
    // it parameter which is passed in  registerReceiver() function
    // is the intent filter that we have just created
    registerReceiver(br, it)
}

Be sure to unregister the receiver when you no longer need it or the context is no longer valid using unregisterReceiver(BroadcastReceiver).

Sending broadcasts

Android provides three ways for apps to send broadcast:

Ordered Broadcasts
  • sends broadcasts to one receiver at a time.
  • As each receiver executes in turn, it can propagate a result to the next receiver.
  • Receiver can abort the broadcast and hence no broadcast is received by other receivers.
  • The order of receivers is managed and controlled by the attribute android:priority in corresponding intent-filter.
  • If receivers will have the same priority then they may run in any order.
  • These broadcasts are sent with sendOrderedBroadcast(Intent, String) method.
Normal broadcasts
  • Sends broadcasts to all receivers in an undefined order.
  • This is more efficient.
  • Receivers cannot read results from other receivers.
  • They cannot propagate data received from the broadcast, or abort the broadcast.
  • These broadcasts are sent with sendBroadcast(Intent) method.
Local Broadcasts
  • sends broadcasts to receivers that are in the same app as the sender.
  • Use local broadcasts, if you don’t need to send broadcasts across apps.
  • The implementation is much more efficient (no interprocess communication needed).
  • No security issues related to other apps being able to receive or send your broadcasts.
  • These broadcasts are sent with LocalBroadcastManager.sendBroadcast method.

Creating new project

1 . Create a new project by going to File  New Android Project, select Empty Activity , provide app name, select language to kotlin and then finally click on finish.

2 . Open activity_main.xml layout file to include a button to broadcast the custom intent.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_send_broadcast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show Broadcast"
        android:textSize="20sp"
        android:textAllCaps="false"
        android:padding="15dp"
        android:background="@color/colorPrimary"
        android:textColor="@android:color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

3 . Create a new Kotlin class by simply Go to app > java > your package name(in which the MainActicity is present) > right-click > New > Kotlin File/Class and name the file as MyReceiver.

MyReceiver.kt

// MyReceiver class extending BroadcastReceiver class
class MyReceiver : BroadcastReceiver() {

    //executed when sendBroadcast() is called on button click
    override fun onReceive(context: Context?, intent: Intent?) {

        val data = intent!!.extras!!.getString("data")

        Toast.makeText(context, " Broadcast Received with data " + data, Toast.LENGTH_LONG).show()
    }
}

4 . In MainActivity.kt file, we are receiving broadcast dynamically and sending broadcast at the click of a button.

MainActivity.kt

package com.c1ctech.broadcastreceiverexp
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    lateinit var br: MyReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //creating BroadcastReceiver instance
        br = MyReceiver()

        IntentFilter("com.c1ctech.broadcast.CUSTOM_INTENT").also {
            // registering the receiver
            // it parameter which is passed in  registerReceiver() function
            // is the intent filter that we have just created
            registerReceiver(br, it)
        }

        btn_send_broadcast.setOnClickListener {

            Intent().also { intent ->
                intent.setAction("com.c1ctech.broadcast.CUSTOM_INTENT")
                intent.putExtra("data", "Hello World!")
                sendBroadcast(intent)
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // unregister the BroadcastReceiver
        unregisterReceiver(br)
    }
}

When you run the app it will look like this:

Leave a Reply