1 package com.example.android.apis.app; 2 3 import com.example.android.apis.R; 4 import com.example.android.apis.app.LocalServiceActivities.Binding; 5 6 import android.app.Activity; 7 import android.content.ComponentName; 8 import android.content.Context; 9 import android.content.Intent; 10 import android.content.ServiceConnection; 11 import android.os.Bundle; 12 import android.os.Handler; 13 import android.os.IBinder; 14 import android.os.Message; 15 import android.os.Messenger; 16 import android.os.RemoteException; 17 import android.view.View; 18 import android.view.View.OnClickListener; 19 import android.widget.Button; 20 import android.widget.TextView; 21 import android.widget.Toast; 22 23 public class MessengerServiceActivities { 24 /** 25 * Example of binding and unbinding to the remote service. 26 * This demonstrates the implementation of a service which the client will 27 * bind to, interacting with it through an aidl interface.</p> 28 * 29 * <p>Note that this is implemented as an inner class only keep the sample 30 * all together; typically this code would appear in some separate class. 31 */ 32 public static class Binding extends Activity { 33 // BEGIN_INCLUDE(bind) 34 /** Messenger for communicating with service. */ 35 Messenger mService = null; 36 /** Flag indicating whether we have called bind on the service. */ 37 boolean mIsBound; 38 /** Some text view we are using to show state information. */ 39 TextView mCallbackText; 40 41 /** 42 * Handler of incoming messages from service. 43 */ 44 class IncomingHandler extends Handler { 45 @Override 46 public void handleMessage(Message msg) { 47 switch (msg.what) { 48 case MessengerService.MSG_SET_VALUE: 49 mCallbackText.setText("Received from service: " + msg.arg1); 50 break; 51 default: 52 super.handleMessage(msg); 53 } 54 } 55 } 56 57 /** 58 * Target we publish for clients to send messages to IncomingHandler. 59 */ 60 final Messenger mMessenger = new Messenger(new IncomingHandler()); 61 62 /** 63 * Class for interacting with the main interface of the service. 64 */ 65 private ServiceConnection mConnection = new ServiceConnection() { 66 public void onServiceConnected(ComponentName className, 67 IBinder service) { 68 // This is called when the connection with the service has been 69 // established, giving us the service object we can use to 70 // interact with the service. We are communicating with our 71 // service through an IDL interface, so get a client-side 72 // representation of that from the raw service object. 73 mService = new Messenger(service); 74 mCallbackText.setText("Attached."); 75 76 // We want to monitor the service for as long as we are 77 // connected to it. 78 try { 79 Message msg = Message.obtain(null, 80 MessengerService.MSG_REGISTER_CLIENT); 81 msg.replyTo = mMessenger; 82 mService.send(msg); 83 84 // Give it some value as an example. 85 msg = Message.obtain(null, 86 MessengerService.MSG_SET_VALUE, this.hashCode(), 0); 87 mService.send(msg); 88 } catch (RemoteException e) { 89 // In this case the service has crashed before we could even 90 // do anything with it; we can count on soon being 91 // disconnected (and then reconnected if it can be restarted) 92 // so there is no need to do anything here. 93 } 94 95 // As part of the sample, tell the user what happened. 96 Toast.makeText(Binding.this, R.string.remote_service_connected, 97 Toast.LENGTH_SHORT).show(); 98 } 99 100 public void onServiceDisconnected(ComponentName className) { 101 // This is called when the connection with the service has been 102 // unexpectedly disconnected -- that is, its process crashed. 103 mService = null; 104 mCallbackText.setText("Disconnected."); 105 106 // As part of the sample, tell the user what happened. 107 Toast.makeText(Binding.this, R.string.remote_service_disconnected, 108 Toast.LENGTH_SHORT).show(); 109 } 110 }; 111 112 void doBindService() { 113 // Establish a connection with the service. We use an explicit 114 // class name because there is no reason to be able to let other 115 // applications replace our component. 116 bindService(new Intent(Binding.this, 117 MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); 118 mIsBound = true; 119 mCallbackText.setText("Binding."); 120 } 121 122 void doUnbindService() { 123 if (mIsBound) { 124 // If we have received the service, and hence registered with 125 // it, then now is the time to unregister. 126 if (mService != null) { 127 try { 128 Message msg = Message.obtain(null, 129 MessengerService.MSG_UNREGISTER_CLIENT); 130 msg.replyTo = mMessenger; 131 mService.send(msg); 132 } catch (RemoteException e) { 133 // There is nothing special we need to do if the service 134 // has crashed. 135 } 136 } 137 138 // Detach our existing connection. 139 unbindService(mConnection); 140 mIsBound = false; 141 mCallbackText.setText("Unbinding."); 142 } 143 } 144 // END_INCLUDE(bind) 145 146 /** 147 * Standard initialization of this activity. Set up the UI, then wait 148 * for the user to poke it before doing anything. 149 */ 150 @Override 151 protected void onCreate(Bundle savedInstanceState) { 152 super.onCreate(savedInstanceState); 153 154 setContentView(R.layout.messenger_service_binding); 155 156 // Watch for button clicks. 157 Button button = (Button)findViewById(R.id.bind); 158 button.setOnClickListener(mBindListener); 159 button = (Button)findViewById(R.id.unbind); 160 button.setOnClickListener(mUnbindListener); 161 162 mCallbackText = (TextView)findViewById(R.id.callback); 163 mCallbackText.setText("Not attached."); 164 } 165 166 private OnClickListener mBindListener = new OnClickListener() { 167 public void onClick(View v) { 168 doBindService(); 169 } 170 }; 171 172 private OnClickListener mUnbindListener = new OnClickListener() { 173 public void onClick(View v) { 174 doUnbindService(); 175 } 176 }; 177 } 178 } 179