Services and BroadcastReceiverssite.iugaza.edu.ps/rsalamah/files/2015/02/lecture8.pdf · the...

Post on 20-Jun-2020

2 views 0 download

transcript

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

?