BroadcastReceiver


A BroadcastReceiver is an android component responsible for listening to system-wide broadcast events or intents.

In Android, most system events are broadcast through Intent objects. To do this these Intent objects get sent to the BroadcastReceivers using the Context.sendBroadcast() methods.

When such an event is broadcasted the BroadcastReceiver will receive the event and react by either creating a status bar notification or performing a given task.

A BroadcastReceiver is an android component like Activity and Service hence most of the times it needs to be registered in the android manifest file.

However unlike the Activity, BroadcastReceivers don't have any user interface.

BroadcastReceiver as a class is abstract, hence normally has a method called onReceive() that we do override to do the task we want to happen when the task is received.

Most of the standard system events are defined as action strings and can be found in the API documentation for the Intent class.

Suppose for example, if your app needs to be notified whenever the user connects or disconnects the charger to the device, two broadcast actions defined in the Intent class do that:

  1. ACTION_POWER_DISCONNECTED
  2. ACTION_POWER_CONNECTED.

Here's an example.

public class PhoneChargerConnectedListener extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
            context.startService(
            new Intent(MyService.ACTION_POWER_CONNECTED));
        } else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
        context.startService(
        new Intent(MyService.ACTION_POWER_DISCONNECTED));
        }
    }
}

In this method, the only thing you do is call Context.startService() to delegate the event to a service that performs the actual work.

How do I register BroadcastReceiver?

Well we can register broadcastReceiver in two ways.

1. Via AndroidManifest.xml

The default method for implementing BroadcastReceivers is to declare them in the android manifest. Because of that, it’s possible for the BroadcastReceiver to notify your service even though the user hasn’t started your application.

This is especially useful for applications that should start on certain system events without user interaction.

<receiver android:name=".PhoneChargerConnectedListener">
    <intent-filter>
        <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
        <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
    </intent-filter>
</receiver>

This method is also the easiest way.

By using AndroidManifest.xml to register BroadcastReceiver, your application will be getting the Broadcasts until you uninstall the application. This means you sacifice a little bit of control or the BroadcastReceiver's lifecycle as you can't just register it and unregister it as you wish.

To do that, you check the next way of registering broadcast receivers.

2. Programmatically

BroadcastReceivers can also be registered programmatically within Activities and Services.

Infact some broadcast Intents can only be registered programmatically. On the other hand some only work if you declare them in your manifest.

When you register a BroadcastReceiver programmatically you also have to remember to unregister it in the matching callback.

Here's an example:

public class MyActivity extends AppCompatActivity {
    private PhoneChargerConnectedListener myPhoneChargerConnectedListener;
    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
        intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
        myPhoneChargerConnectedListener = new PhoneChargerConnectedListener();
        registerReceiver(myPhoneChargerConnectedListener, intentFilter);
    }
    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(myPhoneChargerConnectedListener);
    }
}

In this case we have registered the BroadcastReceiver programmatically using the the registerReceiver() method of the Context class. By using this method, we can control our BroadcastReceiver's lifecycle by registering and un-registering them as per our requirement.

BroadcastReceiver Example with AlarmManager

Let's look at a simple broadcast receiver example with alarm manager.

Full Code

We will have one activity and one class.

(a). MainActivity.java

Start by creating an activity in your android studio.

Here we have Our MainActivity class. This class will be Deriving from AppCompatActivity which resides in the support library.

We will have three methods:

  1. onCreate(),
  2. initializeViews(),
  3. go().

This activity's user interface will be inflated from content_main.xml using the setContentView() method.

The views we use are EditTexts and Buttons. We Reference them from our layout specification using findViewById().

We will Initialize and start our alarm in the go() method.

package com.tutorials.hp.alarmmanagerstarter;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button startBtn;
    EditText timeTxt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

         initializeViews();

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

    }

    /*
    INITIALIZE VIEWS
     */
    private void initializeViews()
    {
        timeTxt= (EditText) findViewById(R.id.timeTxt);
        startBtn= (Button) findViewById(R.id.startBtn);

        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               go();
            }
        });
    }

    /*
    INITIALIZE AND START OUR ALARM
     */
    private void go()
    {
        //GET TIME IN SECONDS AND INITIALIZE INTENT
        int time=Integer.parseInt(timeTxt.getText().toString());
        Intent i=new Intent(this,MyReceiver.class);

        //PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
        PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);

        //INITIALIZE ALARM MANAGER
        AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);

        //SET THE ALARM
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(time*1000),pi);
        Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
    }

}
(b). MyReciever.java
  • Our MyReciever class.
  • Derives from android.content.BroadcastReceiver class.
  • Methods: onReceive().
  • We show a toast message in ouronReceive() method to simulate alarm ringing.
package com.tutorials.hp.alarmmanagerstarter;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
    /*
    RING ALARM WHEN IN WHEN WE RECEIVE OUR BROADCAST
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
    }
}

(c) activity_main.xml

  • Our ContentMain.xml file.
  • Shall get inflated to MainActivity.
  • Root tag is relativeLayout.
  • Contains an EditText and a button.
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout 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="com.tutorials.hp.alarmmanagerstarter.MainActivity"
    >

    <EditText
        android:id="@+id/timeTxt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="28dp"
        android:ems="10"
        android:hint="Number of seconds"
        android:inputType="numberDecimal" />

    <Button
        android:id="@+id/startBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/timeTxt"
        android:layout_below="@+id/timeTxt"
        android:layout_marginRight="60dp"
        android:layout_marginTop="120dp"
        android:text="Start" />
</RelativeLayout>

(d)AndroidManifest.xml

We will have to register our BroadcastReceiver class in our android manifest.

Here's my manifest in full:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorials.hp.alarmmanagerstarter">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name="MyReceiver" >
        </receiver>
    </application>

</manifest>

Quick BroadcastReceiver Examples

1. Listen to Network State Changes with BroadcastReceiver

First we need to create a java class, and then have it derive from android.content.BroadcastReceiver.

As instance fields we will have a boolean isNetWorkConnected which will hold for us the a true or false indicating whether network is connected or not.

We will also have a Context object.

We provide two constructors, one which will inject into our class the Context object. Then we override the onReceive() method of the BroadcastReceiver class. Normally this method receives two objects, one a Context object and the other an Intent object.

Here we will initialize a ConnectivityManager using the getSystemService() ,method of the Context class.

Using the ConnectivityManager instance, we invoke the getActiveNetworkInfo() method to receive network information which we hold in an android.net.NetworkInfo object.

Ultimately we set the isConnected() value to isNetWorkConnected boolean.

Then we also have the isNetWorkAvailable() method, which will basically check for us if network is available.

It's just a public method that needs the instance of this class to be invoked as we will see in a short while.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;
import java.util.concurrent.CopyOnWriteArrayList;

public class NetWorkStateReceiver extends BroadcastReceiver {
    public boolean isNetWorkConnected;
    private Context mContext;

    public NetWorkStateReceiver() {
        super();
    }
    public NetWorkStateReceiver(Context context) {
        mContext = context;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager connectivityManager = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.isConnected()) {
            isNetWorkConnected = true;
        } else {
            isNetWorkConnected = false;
            Toast.makeText(context, "No network Connection", Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * Check if network is available
     * @return
     */
    public boolean isNetWorkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager)
                mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        if (networkInfo != null) {
            return networkInfo.isConnected();
        }
        return false;
    }
}

Then in your MainActivity or wherever, you can come and start by instantiating the above class:

    publi class MainActivity extends AppCompatActivity{
        NetWorkStateReceiver receiver;
        @Override
        public void onCreate(Bundle savedInstanceState){
            .....
           receiver = new NetWorkStateReceiver(this);
           if(receiver.isNetWorkAvailable())
           {
               //do something network is available
           }
        }
    }

In you AndroidManifest.xml you must firts add the appropriate permissions as well as register your BroadcastReceiver:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <application>
        ....
        <receiver
            android:name=".broadcasts.NetWorkStateReceiver"
            android:enabled="true"
            android:exported="true" />
        ....                
    </application>

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think

Dear readers drop us your comments below. We are building a community of students and learners. Start by dropping us your suggestions below. What tutorials do you want us to do for example? Where can we improve? What are some awesome resources out there? Do you have any code you want to share with us?
By the way that example or snippet you have lying in your computer can really help beginner programmers. We can share it here with other students.

Previous Post Next Post