1
Services and
BroadcastReceivers
3
OBJECTIVE
Working in Background
Services
BroadcastReceiver
4
ANDROID APPLICATION COMPONENTS
Activity
Views
Service
Broadcast Receiver
Content Provider
Intents
5
SERVICES
A Service is an application component that runs in
the background, not interacting with the user, for
an indefinite period of time.
Services are used for repetitive and potentially
long running operations, i.e., Internet downloads,
checking for new data, data processing, updating
content providers and the like.
Services run with a higher priority than inactive or
invisible activities and therefore it is less likely that
the Android system terminates them.
6
SERVICES
Each service class must have a corresponding <service>
declaration in its package's AndroidManifest.xml
<service android:name=‖.MyService‖ />
To make service available to other applications
<service android:name=‖.MyService‖>
<intent-filter>
<action android:name=‖net.learn2develop.MyService‖ />
</intent-filter>
</service>
7
SERVICES
Services can be started with startService() and
bindService() in the main thread of the
application’s process.
Execute in the main thread of the application’s
process.
CPU intensive tasks must be offloaded to
background threads using Thread or AsyncTask
Alarms can be used to fire Intents at set times.
These can start services, open Activities, or
broadcast Intents
8
SERVICES LIFECYCLE
A Service has three lifecycle methods:
onStartCommand() -- called when startService() is called.
onBind() -- called when bindService() is called. Returns an IBinder (or null if you don't want to be bound).
onCreate() -- called before above methods.
onDestroy() -- called when about to be shut down.
There are two classes you can subclass:
Service: you need to create a new thread, since it is not created by default.
IntentService. This uses a worker thread to perform the requests, and all you need to do is override onHandleIntent.
9
CREATING A SERVICE
10
ONSTARTCOMMAND
Called whenever the Service is started with
startService call
So beware: may be executed several times in
Service’s lifetime!
Controls how system will respond if Service
restarted
(START_STICKY) means the service will run
indefinitely until explicitly stopped
Run from main GUI thread, so standard pattern
is to create a new Thread from
onStartCommand to perform processing and
stop Service when complete
11
START AND STOP A SERVICE
To start a service Call startService
startService(new Intent(getBaseContext(),
MyService.class));
To stop a service Call stopService
stopService(new Intent(getBaseContext(),
MyService.class));
12
EXAMPLE
BACKGROUND THREADS
To make app responsive, move all time-consuming
operations off main app thread to child thread. Very
important!
Two options:
– AsyncTask
– Write own Threads
For details use try it out page 435 textbook
14
THE INTENT SERVICE
The Intent Service is a convenient wrapper class that
implements the best practice pattern for background Services
that perform set of tasks on demand, such as recurring
Internet updates or data processing.
Other application components request an Intent Service
complete a task by starting the Service and passing in an
Intent containing the parameters necessary to complete the
task.
The Intent Service queues request Intents as they are
received and processes them consecutively on an
asynchronous background Thread.
After every received Intent has been processed, the Intent
Service will terminate itself.
The Intent Service handles all the complexities around
queuing multiple requests, background Thread creation, and
UI Thread synchronization.
THE INTENT SERVICE
To implement a Service as an Intent Service, extend
IntentService and override the onHandleIntent handler
public class MyIntentService extends IntentService {
public MyIntentService(String name) {
super(name);
// TODO Complete any required constructor tasks.
}
@Override
public void onCreate() {
super.onCreate();
// TODO: Actions to perform when service is created.
}
@Override
protected void onHandleIntent(Intent intent) {
// This handler occurs on a background thread.
// TODO The time consuming task should be implemented here.
// Each Intent supplied to this IntentService will be
// processed consecutively here. When all incoming Intents
// have been processed the Service will terminate itself.
}
}
BROADCAST RECEIVER
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 are notified by the Android runtime once this
event happens.
You can use Intents to broadcast messages
anonymously between components via the
sendBroadcast method
Applications can register Broadcast Receivers to
listen for, and react to, these Broadcast Intents.
This enables you to create event-driven
applications based on internal, system, or third-
party application events.
BROADCAST RECEIVER
Android broadcasts Intents to announce system
events, such as changes in Internet connectivity or
battery charge levels.
The native Android applications, such as the Phone
Dialer and SMS Manager, simply register
components that listen for specific Broadcast
Intents — such as ―incoming phone call‖ or ―SMS
message received‖ — and react accordingly.
As a result, you can replace many of the native
applications by registering Broadcast Receivers
that listen for the same Intents.
Within your application, construct the Intent you
want to broadcast and call sendBroadcast to send
it.
Set the action, data, and category of your Intent in a
way that lets Broadcast Receivers accurately
determine their interest.
In this scenario, the Intent action string is used to
identify the event being broadcast, so it should be a
unique string that identifies the event.
IMPLEMENTING 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();
}
<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>
IMPLEMENTING THE BROADCAST RECEIVER
The onReceive method will be executed on the
main application thread when a Broadcast Intent is
received that matches the Intent Filter used to
register the Receiver.
The onReceive handler must complete within five
seconds; otherwise, the Force Close dialog will be
displayed.
Typically, Broadcast Receivers will update content,
launch Services, update Activity UI, or notify the
user using the Notification Manager.
The five-second execution limit ensures that major
processing cannot, and should not, be done within
the Broadcast Receiver itself.
REGISTERING BROADCAST RECEIVER
Broadcast Receivers are used to listen for Broadcast Intents.
For a Receiver to receive broadcasts, it must be registered, either:
in code
or within the application manifest (a manifest Receiver).
In either case, use an Intent Filter to specify which Intent actions and data your Receiver is listening for.
In the case of applications that include manifest Receivers, the applications don’t have to be running when the Intent is broadcast for those receivers to execute; they will be started automatically when a matching Intent is broadcast.
REGISTERING BROADCAST RECEIVER
IN ANDROIDMANIFEST.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.
Now whenever your Android device gets booted, it will be intercepted
by BroadcastReceiver MyReceiverand implemented logic
inside onReceive() will be executed.
<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 GENERATED EVENTS
Event Constant Description
android.intent.action.BATTERY_CHANGED Sticky broadcast containing the charging state, level,
and other information about the battery.
android.intent.action.BATTERY_LOW Indicates low battery condition on the device.
android.intent.action.BATTERY_OKAY Indicates the battery is now okay after being low.
android.intent.action.BOOT_COMPLETED This is broadcast once, after the system has finished
booting.
android.intent.action.BUG_REPORT Show activity for reporting a bug.
android.intent.action.CALL Perform a call to someone specified by the data.
android.intent.action.CALL_BUTTON The user pressed the "call" button to go to the dialer or
other appropriate UI for placing a call.
android.intent.action.DATE_CHANGED The date has changed.
android.intent.action.REBOOT Have the device reboot.
REGISTERING BROADCAST RECEIVERS IN
CODE
Broadcast Receivers that affect the UI of a
particular Activity are typically registered in code.
A Receiver registered programmatically will
respond to Broadcast Intents only when the
application component it is registered within is
running.
This is useful when the Receiver is being used to
update UI elements in an Activity.
In this case, it’s good practice to register the
Receiver within the onResume handler and
unregister it during onPause.
registerReceiver(receiver, filter);
unregisterReceiver(receiver);
public class Android Example extends Activity {
private BroadcastReceiver the_receiver = new BroadcastReceiver(){
@Override
public void onReceive(Context c, Intent i) {
}
}; // Set When broadcast event will fire.
private IntentFilter filter = new
IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
@Override
public void onCreate(Bundle savedInstanceState) {
……………………………….
}
@Override
protected void onResume() {
// Register reciever if activity is in front
this.registerReceiver(the_receiver, filter);
super.onResume();
}
@Override
protected void onPause() {
// Unregister reciever if activity is not in front
this.unregisterReceiver(the_receiver);
super.onPause();
}
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.
public void onclick1(View view)
{
Intent intent = new Intent();
intent.setAction("com.tutorialspoint.CUSTOM_INTENT");
sendBroadcast(intent);
}
BROADCASTING CUSTOM INTENTS
This intent com.tutorialspoint.CUSTOM_INTENT can also be
registered 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.tutorialspoint.CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
</application>
EXAMPLE
public class SimpleIntentService extends IntentService {
public static final String PARAM_IN_MSG = "imsg";
public static final String PARAM_OUT_MSG = "omsg";
public SimpleIntentService() {
super("SimpleIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
String msg = intent.getStringExtra(PARAM_IN_MSG);
SystemClock.sleep(30000); // 30 seconds
String resultTxt = msg + " "
+ DateFormat.format("MM/dd/yy h:mmaa", System.currentTimeMillis());
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(ResponseReceiver.ACTION_RESP);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra(PARAM_OUT_MSG, resultTxt);
sendBroadcast(broadcastIntent);
}
EXAMPLE (CONTINUE..)
public class ResponseReceiver extends BroadcastReceiver {
public static final String ACTION_RESP =
"com.mamlambo.intent.action.MESSAGE_PROCESSED";
@Override
public void onReceive(Context context, Intent intent) {
TextView result = (TextView) findViewById(R.id.txt_result);
String text =
intent.getStringExtra(SimpleIntentService.PARAM_OUT_MSG);
result.setText(text);
}
}
public class IntentServiceBasicsActivity extends Activity {
private ResponseReceiver receiver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//onclick method
EditText input = (EditText) findViewById(R.id.txt_input);
String strInputMsg = input.getText().toString();
Intent msgIntent = new Intent(this, SimpleIntentService.class);
msgIntent.putExtra(SimpleIntentService.PARAM_IN_MSG, strInputMsg);
startService(msgIntent);
//onResume method
IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new ResponseReceiver();
registerReceiver(receiver, filter);
}
}
END
Any Questions
?