BroadCast Receivers



Broadcast receivers: 

A broadcast receiver (short receiver) is an Android component which allows you to register for system or application events. All registered receivers for an event will be notified by the Android runtime once this event happens.

For example applications can register for the ACTION_BOOT_COMPLETED system event which is fired once the Android system has completed the boot process.

Broadcast Receivers simply respond to broadcast messages from other applications or from the system itself. These messages are sometime called events or intents. For example, applications can also initiate broadcasts to let other applications know that some data has been downloaded to the device and is available for them to use, so this is broadcast receiver who will intercept this communication and will initiate appropriate action.

There are following two important steps to make BroadcastReceiver works for the systen broadcasted intents:


  • Creating the Broadcast Receiver.
  • Registering Broadcast Receiver
  • Implementation

A receiver can be registered via the AndroidManifest.xml file.

Alternatively to this static registration, you can also register a broadcast receiver dynamically via theContext.registerReceiver() method.

The implementing class for a receiver extends the BroadcastReceiver class.

If the event for which the broadcast receiver has registered happens the onReceive() method of the receiver is called by the Android system.


Lifecycle of a broadcast receiver :

After the onReceive() of the BroadcastReceiver has finished, the Android system can recycle theBroadcastReceiver.

Before API11 you could not perform any asynchronous operation in the onReceive() method because once theonReceive() method is finished the Android system was allowed to recyled that component. If you have potentially long running operations you should trigger a service for that.

As for API11 you can call the goAsync() method. If this method was called it returns an object of thePendingResult type. The Android system considers the receiver as alive until you call thePendingResult.finish() on this object. With this option you can trigger asynchronous processing in a receiver. As soon as that thread has completed its task is calls finish() to indicate to the Android system that this component can be recycled.

Restrictions for defining broadcast receiver :

As of Android 3.1 the Android system will by default exclude all BroadcastReceiver from receiving intents if the corresponding application has never been started by the user or if the user explicitly stopped the application via the Android menu (in Manage Application).

This is an additional security features as the user can be sure that only the applications he started will receive broadcast intents.

Creating the Broadcast Receiver :

A broadcast receiver is implemented as a subclass of BroadcastReceiver class and overriding the onReceive() method where each message is received as a Intent object parameter.

public class MyReceiver extends BroadcastReceiver {

   @Override
   public void onReceive(Context context, Intent intent) {
      Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
   }
 }


Registering Broadcast Receiver :

An application listens for specific broadcast intents by registering a broadcast receiver inAndroidManifest.xml file. Consider we are going to register MyReceiver for system generated event ACTION_BOOT_COMPLETED which is fired by the system once the Android system has completed the boot process.


<application
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:theme="@style/AppTheme" >

   <receiver android:name="MyReceiver">
      <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED">
      </action>
      </intent-filter>
   </receiver>

</application>



System broadcasts : 

Several system events are defined as final static fields in the Intent class. Other Android system classes also define events, e.g. the TelephonyManager defines events for the change of the phone state.

The following table lists a few important system events.

Event
Description
Intent.ACTION_BOOT_COMPLETED
Boot completed.
Requires the android.permission.
RECEIVE_BOOT_COMPLETED
permission.
Intent.ACTION_POWER_CONNECTED
Power got connected to the device.
Intent.ACTION_POWER_DISCONNECTED
Power got disconnected to the device.
Intent.ACTION_BATTERY_LOW
Battery gets low, typically 
used to reduce activities 
in your app which consume power.
Intent.ACTION_BATTERY_OKAY
Battery status good again.


Broadcasting Custom Intents :

If you want your application itself should generate and send custom intents then you will have to create and send those intents by using the sendBroadcast() method inside your activity class. If you use thesendStickyBroadcast(Intent) method, the Intent is sticky, meaning the Intent you are sending stays around after the broadcast is complete.

public void broadcastIntent(View view)
{
   Intent intent = new Intent();
   intent.setAction("com.xyz.CUSTOM_INTENT");
   sendBroadcast(intent);
}


This intent com.xyz.CUSTOM_INTENT can also be regsitered in similar way as we have regsitered system generated intent.


<application
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:theme="@style/AppTheme" >

   <receiver android:name="MyReceiver">
      <intent-filter>
         <action android:name="com.xyz.CUSTOM_INTENT">
      </action>
      </intent-filter>
   </receiver>

</application>


Pending Intent :

A PendingIntent is a token that you give to another application (e.g. Notification Manager, Alarm Manager or other 3rd party applications), which allows this other application to use the permissions of your application to execute a predefined piece of code.

To perform a broadcast via a pending intent so get a PendingIntent via the getBroadcast() method of thePendingIntent class. To perform an activity via an pending intent you receive the activity viaPendingIntent.getActivity().




Broadcast Receiver : 

We will define a broadcast receiver which listens to telephone state changes. If the phone receives a phone call then our receiver will be notified and log a message.

Create a new project . Create a dummy activity as this is required so that the BroadcastReceiver also gets activated. Create the following AndroidManifest.xml file.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.receiver.phone"
    android:versionCode="1"
    android:versionName="1.0" >

     <uses-sdk android:minSdkVersion="15" />
    
    <uses-permission android:name="android.permission.READ_PHONE_STATE" >
    </uses-permission>

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
           <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

  

</manifest> 


Create the MyPhoneReceiver class.


package com.example.receiver.phone;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;

public class MyPhoneReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    Bundle extras = intent.getExtras();
    if (extras != null) {
      String state = extras.getString(TelephonyManager.EXTRA_STATE);
      Log.w("MY_DEBUG_TAG", state);
      if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
        String phoneNumber = extras
            .getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
        Log.w("MY_DEBUG_TAG", phoneNumber);
      }
    }
  }
}



Install your application and simulate a phone call via the DDMS perspective in Eclipse. Your receiver is called and logs a message to the console.


No comments:

Post a Comment