publicclassLocalServiceextendsService{// Binder given to clientsprivatefinalIBindermBinder=newLocalBinder();// Random number generatorprivatefinalRandommGenerator=newRandom();/** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */publicclassLocalBinderextendsBinder{LocalServicegetService(){// Return this instance of LocalService so clients can call public methodsreturnLocalService.this;}}@OverridepublicIBinderonBind(Intentintent){returnmBinder;}/** method for clients */publicintgetRandomNumber(){returnmGenerator.nextInt(100);}}
publicclassBindingActivityextendsActivity{LocalServicemService;booleanmBound=false;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);}@OverrideprotectedvoidonStart(){super.onStart();// Bind to LocalServiceIntentintent=newIntent(this,LocalService.class);bindService(intent,mConnection,Context.BIND_AUTO_CREATE);}@OverrideprotectedvoidonStop(){super.onStop();// Unbind from the serviceif(mBound){unbindService(mConnection);mBound=false;}}/** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute) */publicvoidonButtonClick(Viewv){if(mBound){// Call a method from the LocalService.// However, if this call were something that might hang, then this request should// occur in a separate thread to avoid slowing down the activity performance.intnum=mService.getRandomNumber();Toast.makeText(this,"number: "+num,Toast.LENGTH_SHORT).show();}}/** Defines callbacks for service binding, passed to bindService() */privateServiceConnectionmConnection=newServiceConnection(){@OverridepublicvoidonServiceConnected(ComponentNameclassName,IBinderservice){// We've bound to LocalService, cast the IBinder and get LocalService instanceLocalBinderbinder=(LocalBinder)service;mService=binder.getService();mBound=true;}@OverridepublicvoidonServiceDisconnected(ComponentNamearg0){mBound=false;}};}
publicclassMessengerServiceextendsService{/** For showing and hiding our notification. */NotificationManagermNM;/** Keeps track of all current registered clients. */ArrayList<Messenger>mClients=newArrayList<Messenger>();/** Holds last value set by a client. */intmValue=0;/** * Command to the service to register a client, receiving callbacks * from the service. The Message's replyTo field must be a Messenger of * the client where callbacks should be sent. */staticfinalintMSG_REGISTER_CLIENT=1;/** * Command to the service to unregister a client, ot stop receiving callbacks * from the service. The Message's replyTo field must be a Messenger of * the client as previously given with MSG_REGISTER_CLIENT. */staticfinalintMSG_UNREGISTER_CLIENT=2;/** * Command to service to set a new value. This can be sent to the * service to supply a new value, and will be sent by the service to * any registered clients with the new value. */staticfinalintMSG_SET_VALUE=3;/** * Handler of incoming messages from clients. */classIncomingHandlerextendsHandler{@OverridepublicvoidhandleMessage(Messagemsg){switch(msg.what){caseMSG_REGISTER_CLIENT:mClients.add(msg.replyTo);break;caseMSG_UNREGISTER_CLIENT:mClients.remove(msg.replyTo);break;caseMSG_SET_VALUE:mValue=msg.arg1;for(inti=mClients.size()-1;i>=0;i--){try{mClients.get(i).send(Message.obtain(null,MSG_SET_VALUE,mValue,0));}catch(RemoteExceptione){// The client is dead. Remove it from the list;// we are going through the list from back to front// so this is safe to do inside the loop.mClients.remove(i);}}break;default:super.handleMessage(msg);}}}/** * Target we publish for clients to send messages to IncomingHandler. */finalMessengermMessenger=newMessenger(newIncomingHandler());@OverridepublicvoidonCreate(){mNM=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);// Display a notification about us starting.showNotification();}@OverridepublicvoidonDestroy(){// Cancel the persistent notification.mNM.cancel(R.string.remote_service_started);// Tell the user we stopped.Toast.makeText(this,R.string.remote_service_stopped,Toast.LENGTH_SHORT).show();}/** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */@OverridepublicIBinderonBind(Intentintent){returnmMessenger.getBinder();}/** * Show a notification while this service is running. */privatevoidshowNotification(){// In this sample, we'll use the same text for the ticker and the expanded notificationCharSequencetext=getText(R.string.remote_service_started);// The PendingIntent to launch our activity if the user selects this notificationPendingIntentcontentIntent=PendingIntent.getActivity(this,0,newIntent(this,RemoteService.Controller.class),0);// Set the info for the views that show in the notification panel.Notificationnotification=newNotification.Builder(this).setSmallIcon(R.drawable.stat_sample)// the status icon.setTicker(text)// the status text.setWhen(System.currentTimeMillis())// the time stamp.setContentTitle(getText(R.string.local_service_label))// the label of the entry.setContentText(text)// the contents of the entry.setContentIntent(contentIntent)// The intent to send when the entry is clicked.build();// Send the notification.// We use a string id because it is a unique number. We use it later to cancel.mNM.notify(R.string.remote_service_started,notification);}}//END_INCLUDE(service)
publicclassActivityMessengerextendsActivity{/** Messenger for communicating with the service. */MessengermService=null;/** Flag indicating whether we have called bind on the service. */booleanmBound;/** * Class for interacting with the main interface of the service. */privateServiceConnectionmConnection=newServiceConnection(){publicvoidonServiceConnected(ComponentNameclassName,IBinderservice){// This is called when the connection with the service has been// established, giving us the object we can use to// interact with the service. We are communicating with the// service using a Messenger, so here we get a client-side// representation of that from the raw IBinder object.mService=newMessenger(service);mBound=true;}publicvoidonServiceDisconnected(ComponentNameclassName){// This is called when the connection with the service has been// unexpectedly disconnected -- that is, its process crashed.mService=null;mBound=false;}};publicvoidsayHello(Viewv){if(!mBound)return;// Create and send a message to the service, using a supported 'what' valueMessagemsg=Message.obtain(null,MessengerService.MSG_SAY_HELLO,0,0);try{mService.send(msg);}catch(RemoteExceptione){e.printStackTrace();}}@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);}@OverrideprotectedvoidonStart(){super.onStart();// Bind to the servicebindService(newIntent(this,MessengerService.class),mConnection,Context.BIND_AUTO_CREATE);}@OverrideprotectedvoidonStop(){super.onStop();// Unbind from the serviceif(mBound){unbindService(mConnection);mBound=false;}}}