Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 37

Android Application Development

Broadcast Receiver
Application Building Blocks Android Component

• UI Component Typically
Activity Corresponding to one screen.

• Responds to notifications or status


Intent Receiver changes. Can wake up your process.

• Faceless task that runs in the


Service background.

ContentProvider • Enable applications to share data.


Application Building Blocks Android Component

Activities Services
1. Provides User Interface 1. No User Interface
2. Usually represents a Single 2. Runs in Background
Screen
3. Extends the Service Base Class
3. Can contain one/more Views
4. Extends the Activity Base class

Application= Set of Android Components


Intent/Broadcast Receiver Content Provider
1. Receives and Reacts to 1. Makes application data
broadcast Intents available to other apps

2. No UI but can start an Activity 2. Data stored in SQLite database


3. Extends the BroadcastReceiver 3. Extends the ContentProvider
Base Class Base class
Broadcast Receivers Android Component

• A broadcast receiver is a component that responds to system-wide


Broadcast announcements.
• Many broadcasts originate from the system—for example, a Broadcast
announcing that the screen has turned off, the battery is low, or a picture
was captured or an SMS is received.
• Applications can also initiate broadcasts—for example, to let other
Applications know that some data has been downloaded to the device
and is available for them to use.
• Although broadcast receivers don't display a user interface, they
may create a status bar notification to alert the user when a broadcast
event occurs.
• More commonly, though, a broadcast receiver is just a "gateway" to
other components and is intended to do a very minimal amount of work.
For instance, it might initiate a service/or start an activity to perform
some work based on the event.
Broadcast Receivers Android Component
Android Application Anatomy Big Picture

Activity 1 Activity 2

UI

Service BroadcastReceiver

Intents
1. Directed Intents
2. Broadcast Intents
OS

BIG PICTURE
Android Application Anatomy Big Picture

1. We’ll use a Broadcast Receiver to capture SMS receive event


2. We capture the SMS receive event and launch an Activity to show the
SMS and give user an option to reply the SMS

Activity

OS BroadcastReceiver
Broadcast Receivers SMS Application

1. Create a new project BroadcastReceiverDemo


2. A broadcast receiver is implemented as a subclass
of BroadcastReceiver and each broadcast is delivered as
an Intent object. In this case the intent is detected by
android.provider.Telephony.SMS_RECEIVED

To do this we’ll create a class SMSReceiver that extends


BroadcastReceiver class and define the method onReceive()
Broadcast Receivers SMS Application

3. We also need to add SMSReceiver as receiver of a particular Intent (SMS


received) which is identified by
android.provider.Telephony.SMS_RECEIVED
Broadcast Receivers SMS Application

4. Also we have to add permission for receiving SMS


Broadcast Receivers SMS Application

5. Now we run the application


6. Now we use emulator control to send sms
Receiving SMS Broadcast Receiver

public void onReceive(Context context, Intent intent) {


Bundle bundle = intent.getExtras();
SmsMessage smsMessage;
try {
if ( bundle != null) {
if (Build.VERSION.SDK_INT >= 19 ) { //kitkat
SmsMessage[] msgs =
Telephony.Sms.Intents.getMessagesFromIntent(intent);
smsMessage = msgs[0];
}else {
Object[] objPdus = (Object[]) bundle.get("pdus");
smsMessage = SmsMessage.createFromPdu((byte[])objPdus[0]);
}
String phoneNumber =
smsMessage.getDisplayOriginatingAddress();
String message = smsMessage.getMessageBody();
Toast.makeText(context, "SenderNum: \n " + phoneNumber + ";
message: \n " + message, Toast.LENGTH_LONG).show();
} }catch (Exception e) { e.printStackTrace();
} }
Sending SMS Broadcast Receiver

1. Add permission in menifest.xml

2. We add the following code for sending SMS from anywhere


of our application
sendTextMessage Parameters

Parameters Descriptions
destinationAddress String: the address to send the message to
scAddress String: is the service center address or null to use the
current default SMSC
text String: the body of the message to send
sentIntent PendingIntent: if not NULL this PendingIntent is broadcast
when the message is successfully sent, or failed. The result
code will be Activity.RESULT_OK for success, or one of
these
errors: RESULT_ERROR_GENERIC_FAILURERESULT_ERROR_
RADIO_OFF RESULT_ERROR_NULL_PDU
deliveryIntent PendingIntent: if not NULL this PendingIntent is broadcast
when the message is delivered to the recipient. The raw
pdu of the status report is in the extended data ("pdu").
Registering BroadcastReceivers Two ways to register

1. Statically
AndroidManifest.XML
2. Dynamically
Context.registerReceiver()
Static Registration Two ways to register

• Include <receiver> in AndroidManifest.xml


<application>
<receiver receiver specs >
<intent-filter> event specs </intent-filter>
</receiver>
</application>

Receiver registered at boot time or when


application package is added
Static Registration (cont.) Two ways to register

<receiver
android:name=".IncomingSms"
android:enabled = "true">
<intent-filter
android:priority="1000">
<action android:name=
"android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Dynamic Registration Dynamic

1. Create an IntentFilter
2. Create a BroadcastReceiver
3. Register BroadcastReceiver to receive Intents
using Context.registerReceiver()
4. When appropriate call
Context.unRegisterReceiver() to unRegister
BroadcastReceiver
Dynamic Registration Dynamic

public class SingleBroadcast extends Activity {

public static final String CUSTOM_INTENT =


"course.examples.BroadcastReceiver.intent.action.TEST1";
final Receiver1 br1 = new Receiver1();
final IntentFilter intfil = new
IntentFilter(CUSTOM_INTENT);
public void onCreate(Bundle savedInstanceState) { …
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
sendBroadcast(new Intent(CUSTOM_INTENT),
android.Manifest.permission.VIBRATE);
}
});
registerReceiver(br1, intfil); }
Dynamic Registration Dynamic


@Override
protected void onDestroy() {
unregisterReceiver(br1);
super.onDestroy();
}

Event Broadcast Broadcast Events

Several broadcast methods supported


• Normal vs. Ordered
• Normal: processing order undefined
• Ordered: sequential processing in priority
order
• Sticky vs. Non-Sticky
• Sticky: Store Event after initial broadcast
• Non-Sticky: Discard Event after initial
broadcast
Normal Broadcasts Broadcast Events

//public abstract class Context …


// send Intent to interested BroadcastReceivers
void sendBroadcast (Intent intent)

// send Intent to interested BroadcastReceivers


// if they have the specified permissions
void sendBroadcast (Intent intent, String
receiverPermission)
Normal Broadcasts (cont.) Broadcast Events

public class SimpleBroadcast extends Activity {


public static final String CUSTOM_INTENT =
"course.examples.BroadcastReceiver.intent.action.TEST2";

public void onCreate(Bundle savedInstanceState) {



Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sendBroadcast(new Intent(CUSTOM_INTENT),
android.Manifest.permission.VIBRATE);
}
});
}
}
Ordered Broadcasts Broadcast Events

//public abstract class Context …

// send Intent to interested BroadcastReceivers in priority order


void sendOrderedBroadcast (Intent intent,
String receiverPermission)
// send Intent to interested BroadcastReceivers in priority order
// sender can provide various parameters for greater control
void sendOrderedBroadcast (Intent intent,
String receiverPermission,
BroadcastReceiver resultReceiver,
Handler scheduler,
int initialCode,
String initialData,
Bundle initialExtras)
sendOrderedBroadcast Parameters

Parameters Descriptions
Intent Intent: The Intent to broadcast; all receivers matching this
Intent will receive the broadcast

receiverPermission String: String naming a permissions that a receiver must


hold in order to receive your broadcast. If null, no
permission is required.
resultReceiver BroadcastReceiver: Your own BroadcastReceiver to treat as
the final receiver of the broadcast.

scheduler Handler: A custom Handler with which to schedule the


resultReceiver callback; if null it will be scheduled in the
Context's main thread.

initialCode int: An initial value for the result code. Often


Activity.RESULT_OK.
initialData String: An initial value for the result data. Often null.
initialExtras Bundle: An initial value for the result extras. Often null.
Ordered Broadcasts (cont.) Broadcast Events

public class CompoundOrderedBroadcast extends Activity


{

public static final String CUSTOM_INTENT =
"course.examples.BroadcastReceiver.intent.action.TEST4
";
public void onCreate(Bundle savedInstanceState) {

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
sendOrderedBroadcast(new
Intent(CUSTOM_INTENT),android.Manifest.permission.VIBR
ATE);
}
});
Ordered Broadcasts (cont.) Broadcast Events

public class
CompoundOrderedBroadcastWithResultReceiver extends
Activity {

public static final String CUSTOM_INTENT =
"course.examples.BroadcastReceiver.intent.action.TEST4";
public void onCreate(Bundle savedInstanceState) {

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
sendOrderedBroadcast(new Intent(CUSTOM_INTENT), null, new
BroadcastReceiver() { @Override public void
onReceive(Context context, Intent intent)
{ System.out.println("Final Result is:" +
getResultData()); } }, null, 0, null, null); } });
Sticky Broadcasts Sticky

• Events sent as sticky broadcasts are cached by


Android
• New intents overwrite older intents they
match
• When later a BroadcastReceiver is registered
dynamically
• Cached sticky Intents matching the
specified IntentFilter are broadcast to the
BroadcastReceiver
• One matching sticky Intent is returned to
the caller
Sticky Broadcasts (Cont.) Sticky Events

//public abstract class Context …


// send sticky Intent to interested BroadcastReceivers
void sendStickyBroadcast (Intent intent)

// send sticky Intent to interested BroadcastReceivers in priority


order
// sender can provide various parameters for greater control
void sendStickyOrderedBroadcast (Intent intent,
BroadcastReceiver resultReceiver,
Handler scheduler,
int initialCode,
String initialData,
Bundle initialExtras)

Must have BROADCAST_STICKY permission to send sticky Intents


Intent Filter Matching Sticky

• Similar to matching for Activities & Services


• Some debugging tips
• Log BroadcastReceivers that match an Intent
• Intent.setFlag(FLAG_DEBUG_LOG_RESOLUTI
ON)
• Print BroadcastReceivers registered to receive
intents
• Dynamic registration
• % adb shell dumpsys activity b
• Static registration
• % adb shell dumpsys package
Event Delivery Broadcast Events

• Events delivered by calling onReceive()


Event Handling in onReceive() Broadcast Events

• onReceive() should be short-lived


• Hosting process has high priority while
onReceive() is executing & is often when
onReceive() returns
• If event handling take a long time, consider
starting a Service, rather than performing
complete operation in onReceive()
• BroadcastReceivers can’t start asynchronous
operations
• e.g. showing a dialog, binding to a Service,
starting an Activity via startActivityForResult
Handling a Normal Broadcast onReceive()

public class Receiver2 extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {
System.out.println(this + ":GOT THE INTENT");
// emulator doesn't support vibration
Vibrator v = (Vibrator) context
.getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(500);
}
}
Handling an Ordered Broadcast onReceive()

Passing results

public class Receiver1 extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {
String tmp = getResultData() != null ?
getResultData() : ""; setResultData(tmp +
":Receiver 1:");
}
}
Handling an Ordered Broadcast onReceive()

Aborting the Broadcast

public class Receiver2 extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {
if (isOrderedBroadcast()) {
System.out.println(this + ":Calling
abortBroadcast()");
abortBroadcast();
}
System.out.println(this + ":GOT THE INTENT");
// emulator doesn't support vibration
Vibrator v = (Vibrator) context
.getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(500);
}
}
Handling a Sticky Broadcast onReceive()

public class StickyIntentBroadcastReceiverActivity


extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView state = (TextView)
findViewById(R.id.level);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context,
Intent intent) {
Handling a Sticky Broadcast (Cont.) onReceive()


If (intent.getAction().equals(
Intent.ACTION_BATTERY_CHANGED)) {
String age = "Reading taken recently";
if (isInitialStickyBroadcast()) {
age = "Reading may be stale";
}
state.setText("Current Battery Level" +
String.valueOf(intent.getIntExtra(
BatteryManager.EXTRA_LEVEL, -1)) + "\n"
+ age);
}
}
}, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

You might also like