1 / 60

Android Services

Android Services. Mobile Application Development Selected Topics – CPIT 490. Objective. Working in Background Services BroadcastReceiver AsyncTask. Android Application Components. Activity Views Service Broadcast Receiver Content Provider Intents Widgets. Services.

nicolew
Télécharger la présentation

Android Services

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Android Services Mobile Application Development Selected Topics – CPIT 490

  2. Objective • Working in Background • Services • BroadcastReceiver • AsyncTask

  3. Android Application Components • Activity • Views • Service • Broadcast Receiver • Content Provider • Intents • Widgets

  4. Services • A Service is an application component that runs in the background, not interacting with the user, for an indefinite period of time. • A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of. A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors). • Higher priority than inactive Activities, so less likely to be killed • If killed, they can be configured to re-run automatically (when resources available) • If a service and the respective activity are run on the same thread, then the activity will become unresponsive when the service is being executed • 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>

  5. Services • Services can be started with Context.startService() and Context.bindService() in the main thread of the application’s process. • CPU intensive tasks must be offloaded to background threads using Thread or AsyncTask • startService(new Intent(getBaseContext(), MyService.class)); • startService(new Intent(“net.learn2develop.MyService”)); • To stop a service: stopService(new Intent(getBaseContext(), MyService.class) or stopSelf() • Alarms can be used to fire Intents at set times. These can start services, open Activities, or broadcast Intents • The written services class should extend Service class and has three methods • public IBinder onBind(Intent arg0) { ... } • public int onStartCommand(Intent intent, int flags, int startId) { ... } • public void onDestroy() { ... }

  6. Creating a Service • Subclass Service, then override: • onStartCommand() -- called when startService() is called. Then you can call stopSelf() or stopService() • 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. This is the easiest, provided you don't need to handle multiple requests.

  7. Services Lifecycle • A Service has three lifecycle methods: • 1. void onCreate() • 2. void onStartCommand() • 3. void onDestroy() • onStartCommand() is invoked when a service is explicitly started using startService() method • onDestroy() is invoked when a service is stopped using stopService() method

  8. Services Lifecycle • To handle a block for code for specified time period, use Timer class within the service • private void doSomethingRepeatedly() { • timer.scheduleAtFixedRate(new TimerTask() { • public void run() { Log.d(“MyService”, String.valueOf(++counter));} • }, 0, UPDATE_INTERVAL); } • You passed an instance of the TimerTask class to the scheduleAtFixedRate() method so that you can execute the block of code within the run() method repeatedly • The second parameter to the scheduleAtFixedRate() method specifies the amount of time, in milliseconds, before first execution • The third parameter specifies the amount of time, in milliseconds, between subsequent executions • TimerTask class itself implements Runnable interface and thus can be run on a separate thread. So, no need to wrap it in AsyncTask class

  9. Creating a Service import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyService extends Service { @Override public void onCreate() { // TODO: Actions to perform when service is created. } @Override public IBinder onBind(Intent intent) { // TODO: Replace with service binding implementation. return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Launch a background thread to do processing. return Service.START_STICKY; } @Override public void onDestroy () { // TODO: Actions to perform when service is ended. } }

  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. Starting a Service • Call startService • // Implicitly start a Service • Intent myIntent = new Intent(MyService.ORDER_PIZZA) ; • myIntent.putExtra("TOPPING", "Margherita"); • startService(myIntent) ; • // Explicitly start a Service • startService(new Intent(this, MyService.class)) ; • (To use this example, would need to include a ORDER_PIZZA constant in MyService class and use an Intent Filter to register the Service as a provider of ORDER_PIZZA)

  12. Stopping a Service • Call stopService • ComponentName service = startService(new Intent(this, BaseballWatch.class)) ; • // Stop a service using the service name. • stopService(new Intent(this, service.getClass())); • // Stop a service. • // try { • // Class serviceClass = Class.forName(service.getClassName()); • // stopService(new Intent(this, serviceClass)); • // } catch (ClassNotFoundException e) {}

  13. Passing Data b/w service & activity • public void startService(View view) { • Intent intent = new Intent(getBaseContext(), MyService.class); • try { URL[] urls = new URL[] { • new URL(“http://www.amazon.com/somefiles.pdf”), • new URL(“http://www.wrox.com/somefiles.pdf”), • intent.putExtra(“URLs”, urls); • } catch (MalformedURLException e) { e.printStackTrace(); } • startService(intent); } • // use Bundle to pass data between activitiy and service • public int onStartCommand(Intent intent, int flags, int startId) { // in service side • Object[] objUrls = (Object[]) intent.getExtras().get(“URLs”); • URL[] urls = new URL[objUrls.length]; • // In Java, casting from one array type to another is not possible directly. Thus do for each element • for (int i=0; i<objUrls.length-1; i++) { urls[i] = (URL) objUrls[i]; } • new DoBackgroundTask().execute(urls); return START_STICKY; }

  14. Binding Activities to Services • Activity maintains reference to a Service • Activity can make calls on the Service just as any other instantiated class. Thus an activity can directly access members and methods inside a service • To support this, implement onBind for the Service (in Service part) • // create an instance of the MyBinder class • private final IBinder binder = new MyBinder(); • // override the onBind() method to return the MyBinder instance • @Override • public IBinder onBind(Intent intent) { return binder; } • // create an inner class that extends Binder class and implement getService() method • public class MyBinder extends Binder { • MyService getService() { return MyService.this; } • }

  15. Binding Activities to Services • In onStartCommand() method (in service part) • new DoBackgroundTask().execute(urls); • In Activity part • Create instance of service and intent • MyService serviceBinder; • Intent i; • Monitor the state of the service using an instance of ServiceConnection class • The onServiceConnected() method is called when the activity is connected to the service • The onServiceDisconnected()method is called when the service is disconnected from the activity.

  16. Binding Activities to Services • In onServiceConnected() method, get the instance of service using getService() method and assign it to serviceBinder object • Bind the activity to the service • public void startService(View view) { • i = new Intent(ServicesActivity.this, MyService.class); • bindService(i, connection, Context.BIND_AUTO_CREATE); } • bindService has three arguments: an Intent object, a ServiceConnection object, and a flag to indicate how the service should be bound • Start the service with startService(intentobject) using an intent object • Once Service is bound, all public methods and properties are available through the serviceBinder object obtained from the onServiceConnected handler

  17. Binding Activities to Services private MyService serviceBinder; // Reference to the service // Handles the connection between the service and activity private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // Called when the connection is made. serviceBinder = ((MyService.MyBinder)service).getService(); } public void onServiceDisconnected(ComponentName className) { // Received when the service unexpectedly disconnects. serviceBinder = null; } }; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); // Bind to the service Intent bindIntent = new Intent(MyActivity.this, MyService.class) ; bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE); }

  18. Services • Declare services in manifest • Service Lifecycle: • onCreate, onStartCommand, onDestroy • Can start services by passing in an intent similar to starting an activity • Must stop service before starting up another instance • Best to start service in onCreate/onResume and stop in onPause

  19. Background threads • To make application responsive, move all time-consuming operations off main app thread to child thread. Very important! • Two options: • AsyncTask • Create an inner class that extends AsyncTask class. The AsyncTask class enables handling of background execution without manually handling threads and handlers • private class abcextends AsyncTask<URL, Integer, Long> { • The inner class has three methods: doInBackground() has an array of first generic type (URL in this case) specified in abc as parameter and the third generic type (Long in this case) as the result; onProgressUpdate() accepts an array of 2nd generic type (Integer in this case) as parameter; onPostExecute() accepts 3rd generic type (Long in this case) as parameter • Write own Threads

  20. AsyncTask<Params, Progress, Result> • Execution of asynchronous task goes through following main steps: • doInBackground(Params...): used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result will be passed to onPostExecute(). publishProgress(Progress...), which is invoked from doInBackground(), is used to publish one or more units of progress by calling onProgressUpdate(Progress...). • onProgressUpdate(Progress...): invoked after a call to publishProgress(Progress...). Used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field. • onPostExecute(Result): invoked after the background computation finishes. The result of the background computation is passed to this step as a parameter.

  21. AsyncTask<Params, Progress, Result> • Pressing the back button in the emulator or device will close the activity but the task will keep on running • To stop the AsyncTask subclass, you need to get an instance of it first. To stop the task, call its cancel() method. Within the task, you call the isCancelled() method to check whether the task should be terminated • public class ThreadingActivity extends Activity { • static TextView txtView1; DoCountingTask task; • public void stopCounter(View view) { task.cancel(true); } • private class DoCountingTask extends AsyncTask<Void, Integer, Void> { • protected Void doInBackground(Void... params) { publishProgress(i); … • if (isCancelled()) break; } • return null; } • protected void onProgressUpdate(Integer... progress) { … } } • protected void onPause() { super.onPause(); stopCounter(txtView1); }

  22. Creating AsyncTask • new DownloadFilesTask().execute(url1, url2, url3); //this call in onStartCommand() • private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { • @Override • protected Long doInBackground(URL... urls) { //Background thread. Do not interact with UI • int myProgress = 0; long result=0; • // [... Perform background processing task, update myProgress ...] • PublishProgress(myProgress) • // [... Continue performing background processing task ...] • // Return the value to be passed to onPostExecute • return result; } • @Override • protected void onProgressUpdate(Integer... progress) { //Post interim updates to UI thread; access UI • // [... Update progress bar, Notification, or other UI element ...] • } • @Override • protected void onPostExecute(Long result) { //Run when doInBackground completed; access UI • // [... Report results via UI update, Dialog, or notification ...] • showDialog("Downloaded " + result + " bytes"); • } }

  23. Services using IntentService class • To easily create a service that runs a task asynchronously and terminates itself when it is done, you can use the IntentService class • The IntentService class is a base class for Service that handles asynchronous requests on demand • It is started just like a normal service; and it executes its task within a worker thread and terminates itself when the task is completed • // Create a class that extends IntentService class instead of Service class • public class MyIntentService extends IntentService { } • // create a constructor and call superclass with the name of the intent service as a string • public MyIntentService() { super(“MyIntentServiceName”); } • // onHandleIntent() is executed on a worker thread • protected void onHandleIntent(Intent intent) { … }

  24. Services using IntentService class • The IntentService class does the following: • Creates a default worker thread that executes all intents delivered to onStartCommand() separate from your application's main thread. • Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading. • Stops the service after all start requests have been handled, so you never have to call stopSelf(). • Provides default implementation of onBind() that returns null. • Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation. • All you have to do is handle onHandleIntent().

  25. Services using IntentService class public class HelloIntentService extends IntentService { // A constructor is required, and must call the super IntentService(String) // constructor with a name for the worker thread. public HelloIntentService() { super("HelloIntentService"); } // The IntentService calls this method from the default worker thread with the intent that started // the service. When this method returns, IntentService stops the service, as appropriate. @Override protected void onHandleIntent(Intent intent) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. long endTime = System.currentTimeMillis() + 5*1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) { } }}}}

  26. Running a Service in Foreground • To request running in foreground: startForeground() • To remove from foreground: stopForeground() Notification notification =newNotification(R.drawable.icon,getText(R.string.ticker_text), System.currentTimeMillis()); Intent notificationIntent =newIntent(this,ExampleActivity.class); PendingIntent pendingIntent =PendingIntent.getActivity(this,0, notificationIntent,0); notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION, notification);

  27. Creating own threads • // write your own thread using Thread and Runnable class • new Thread(new Runnable() { • public void run() { • // don’t update the UI directly from here because in Android updating UI from a separate thread wont work properly • for (int i=0; i<=1000; i++) { txtView1.setText(String.valueOf(i)); } // WRONG • // update using post method of any view with Runnable • //---update UI like this --- • txtView1.post(new Runnable() { • public void run() { … } }); } }).start(); • Write the task within the run() method • Start the Runnable block using the Thread class • A Runnable is a block of code that can be executed by a thread

  28. Creating own threads • Updating from another thread is possible using Handler class • A Handler enables you to send and process messages, similar to using the post() method of a View • import android.os.Handler; • //---used for updating the UI on the main activity--- • static Handler UIupdater = new Handler() { @Override • public void handleMessage(Message msg) { byte[] buffer = (byte[]) msg.obj; • //---convert the entire byte array to string--- • String strReceived = new String(buffer); //-display the text received on the TextView--- • txtView1.setText(strReceived); • public void startCounter(View view) { new Thread(new Runnable() { • @Override • public void run() { //---update the main activity UI--- • ThreadingActivity.UIupdater.obtainMessage(0, String.valueOf(i).getBytes() ).sendToTarget(); • Refer: http://developer.android.com/reference/android/os/Handler.html

  29. BroadcastReceiver • Component that responds to system-wide broadcast announcements. • Example system broadcasts: screen has turned off, the battery is low, user is present using phone, or a picture was captured. • Applications can initiate broadcasts—e.g., to let other applications know that some data has been downloaded to the device and is available for them to use. • Don’t display a UI, but can create a status bar notification to alert the user when a broadcast event occurs.

  30. BroadcastReceiver • Usually, 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 to perform some work based on the event. • Important: you must complete tasks in a BroadcastReceiver within <10s. If you have a task that will take longer, you must start a new thread to avoid application assassin OS.

  31. BroadcastReceiver Lifecycle • The system delivers a broadcast Intent to all interested broadcast receivers, which handle the Intent sequentially.

  32. BroadcastReceiver Lifecycle • A broadcast receiver has a single callback method: • void onReceive(Context curContext, Intent broadcastMsg) • 1. When a broadcast message arrives to a receiver, Android calls its onReceive() method and passes it the Intent object containing the message. • 2. The broadcast receiver is considered to be active only while it is executing this method. • 3. When onReceive() returns, it is inactive.

  33. Example • Starting Broadcast public static final String NEW_LIFEFORM_DETECTED = “com.paad.action.NEW_LIFEFORM”; Intent intent = new Intent(NEW_LIFEFORM_DETECTED); intent.putExtra(“lifeformName”, lifeformType); sendBroadcast(intent); • BroadcastReceiver import android.content.BroadcastReceiver; import android.content.Intent; import android.content.Context; public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive( Context context, Intent intent) { //TODO: React to the Intent received. } }

  34. Example 2 • Starting Broadcast • //---send a broadcast to inform the activity • Intent broadcastIntent = new Intent(); • broadcastIntent.setAction(“FILE_DOWNLOADED_ACTION”); // only those activities listening for this intent will be invoked • getBaseContext().sendBroadcast(broadcastIntent); • BroadcastReceiver • public void onResume() { super.onResume(); • //---intent to filter for file downloaded intent--- • intentFilter = new IntentFilter(); intentFilter.addAction(“FILE_DOWNLOADED_ACTION”); • //---register the receiver--- • registerReceiver(intentReceiver, intentFilter); } • private BroadcastReceiver intentReceiver = new BroadcastReceiver() { • @Override • public void onReceive(Context context, Intent intent) { … } };

  35. Manifest • The manifest of applications using Android Services must include: • If the application defines a BroadcastReceiver as an independent class, it must include a <receiver> clause identifying the component. In addition an <intent-filter> entry is needed to declare the actual filter the service and the receiver use.

  36. Manifest • <?xml version = "1.0" encoding = "utf-8" ?> • <manifest xmlns:android = "http://schemas.android.com/apk/res/android" • package = "cs495.demos" android:versionCode = "1“ android:versionName = "1.0.0" > • <uses-sdk android:minSdkVersion = "4" ></uses-sdk> • <application android:icon = "@drawable/icon" android:label = "@string/app_name" > • <activity android:name = ".MyServiceDriver2“ > • <intent-filter> • <action android:name = "android.intent.action.MAIN" /> • <category android:name = "android.intent.category.LAUNCHER" /> • </intent-filter> • </activity> • <service android:name = “.MyService2" /> • <receiver android:name = “.MyBroadcastReceiver" > • <intent-filter> • <action android:name = "com.paad.action.NEW_LIFEFORM" /> • </intent-filter> • </receiver> • </application> </manifest>

  37. Native Broadcasts • ACTION_BOOT_COMPLETED • ACTION_CAMERA_BUTTON • ACTION_DATE_CHANGED and ACTION_TIME_CHANGED • ACTION_MEDIA_BUTTON • ACTION_MEDIA_EJECT • ACTION_MEDIA_MOUNTED and ACTION_MEDIA_UNMOUNTED • ACTION_SCREEN_OFF and ACTION_SCREEN_ON • ACTION_TIMEZONE_CHANGED • For comprehensive list: • http://code.google.com/android/reference/android/content/Intent.html

  38. Device Power • Just because you have code in a BroadcastReceiver or Service doesn’t mean it will run if the phone goes into a low-power state • Common problem: create a Broadcast receiver. Create a thread from within it to run code.... • All works fine when phone is on and plugged into computer during development • Fails under normal use because phone shuts down quickly in power management state • Need to use a WakeLock!

  39. WakeLock • Control the power state on device (somewhat) • Used to • Keep the CPU running • Prevent screen dimming or going off • Prevent backlight from turning on • Only use when necessary and release as quickly as possible • Need to request the • android.permission.WAKE_LOCK permission in the <uses-permission> element of the manifest file.

  40. Creating a WakeLock • PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); • WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock"); • wakeLock.acquire(); • [ ... Do things requiring the CPU stay active ... ] • wakeLock.release(); • PARTIAL_WAKE_LOCK keeps the CPU running without the screen on

  41. Project Ideas • Security • ODU Secure Application • Localization • Taking random pictures from your cell at home when it is on a table. Could you locate the phone using the ceiling feature? • Medical/health/activity monitoring • Parkin's disease detection • EEG Set • Transportation • Detecting and identifying whether group of people are on the same transport unit using correlation of accelerometer, gyro, etc

  42. Project Ideas • Education • Engineering management game • Misc • Understanding Interface activities power consumption • Extension of MagnoTricoder • Bird Sound Detection • Last Year Projects: • http://www.cs.odu.edu/~nadeem/classes/cs495-F11/projects.htm

  43. Example 1. A very Simple Service • The main application starts a service. The service prints lines on the DDMS LogCat until the main activity stops the service. • // a simple service is started & stopped • package cs495.demos; • import android.app.Activity; import android.content.ComponentName; • import android.content.Intent; • import android.os.Bundle;import android.view.View; • import android.view.View.OnClickListener; • import android.widget.*; • public class ServiceDriver1 extends Activity { • TextView txtMsg; • Button btnStopService; • ComponentName service; • Intent intentMyService;

  44. Example 1 Contd… • @Override • public void onCreate( Bundle savedInstanceState) { • super .onCreate(savedInstanceState); • setContentView(R.layout. main); • txtMsg= ( TextView ) findViewById(R.id. txtMsg); • intentMyService = new Intent(this, MyService1.class); • service = startService(intentMyService); • btnStopService= ( Button ) findViewById(R.id. btnStopService); • btnStopService.setOnClickListener( new OnClickListener() { • public void onClick( View v) { • try { • stopService((intentMyService)); • txtMsg.setText("After stopingService: \n" + service.getClassName()); • } catch (Exception e) { • Toast. makeText(getApplicationContext(), e.getMessage(), 1).show(); • } } • } ); • } }

  45. Example 1 Contd… Service • //non CPU intensive service running the main task in its main thread • package cs495.demos; • Import android.app.Service; • Import android.content.Intent; • Import android.os.IBinder; • Import android.util.Log; • public class MyService1 extends Service { • @Override • public IBinderonBind(Intent arg0) {return null ; } • @Override • public void onCreate() {super .onCreate(); Log. i("<<MyService1-onStart>>", "I am alive-1!"); } • @Override • public void onStart(Intent intent, intstartId) { • super .onStart(intent, startId); Log. i("<<MyService1-onStart>>", "I did something very quickly"); } • @Override • public void onDestroy() { • super.onDestroy(); • Log. i("<<MyService1-onDestroy>>", "I am dead-1"); • } • }//MyService1

  46. Example 1 Contd… Manifest • <?xml version= "1.0" encoding="utf-8"?> • <manifest xmlns:android= "http://schemas.android.com/apk/res/android" • package= "cs495.demos" • android:versionCode= "1" • android:versionName= "1.0"> • <application android:icon= "@drawable/icon" • android:label= "@string/app_name"> • <activity android:name= ".ServiceDriver1" • android:label= "@string/app_name"> • <intent-filter> • <action android:name= "android.intent.action.MAIN" /> • <category android:name= "android.intent.category.LAUNCHER" /> • </intent-filter> • </activity> • <service android:name= ".MyService1"> </service> • </application> • <uses-sdk android:minSdkVersion= "4" /> • </manifest>

  47. Example 1 Contd… Layout • <?xml version= "1.0" encoding="utf-8"?> • <AbsoluteLayout • android:id= "@+id/widget32“ android:layout_width= "fill_parent“ • android:layout_height= "fill_parent“ • xmlns:android= "http://schemas.android.com/apk/res/android" • /> • <EditText • android:id= "@+id/txtMsg“ android:layout_width= "fill_parent“ • android:layout_height= "120px“ android:textSize= "18sp“ • android:layout_x= "0px“ android:layout_y= "57px“ • / > • </EditText> • <Button android:id= "@+id/btnStopService“ android:layout_width= "151px“ • android:layout_height= "wrap_content“ android:text= " Stop Service“ • android:layout_x= "43px“ android:layout_y= "200px" > • </Button> • </AbsoluteLayout>

  48. Example 1 Contd… Running • According to the Log • 1. Main Activity is started (no displayed yet) • 2. Service is started (onCreate, onStart) • 3. Main Activity UI is displayed • 4. User stops Service

  49. Example 2. Realistic Activity-Service Interaction • 1. The main activity starts the service and registers a receiver . • 2. The service is slow, therefore it runs in a parallel thread its time consuming task. • 3. When done with a computing cycle, the service adds a message to an intent. • 4. The intents broadcasted using the filter: cs495.action.DEMO2 • 5. A BroadcastReceiver (defined inside the main Activity) uses the previous filter and catches the message (displays the contents on the main UI ). • 6. At some point the main activity stops the service and finishes executing.

  50. Example 2 Contd… Layout <?xml version= "1.0" encoding="utf-8"?> <LinearLayout android:id= "@+id/widget32" android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:orientation= "vertical" xmlns:android="http://schemas.android.com/apk/res/android" > <EditText android:id= "@+id/txtMsg" android:layout_width= "fill_parent" android:layout_height= "120px" android:textSize= "12sp" > </EditText> <Button android:id= "@+id/btnStopService" android:layout_width= "151px" android:layout_height= "wrap_content" android:text= "Stop Service" > </Button> </LinearLayout>

More Related