Cómo enlazar una actividad a un servicio y controlar y administrar el servicio desde la actividad

Estoy tratando de enlazar una actividad a un servicio local para interactuar con ella. Pero en mi actividad sólo puedo hacer llamadas a los métodos definidos en mi LocalBinder y no en mi LocalService. ¿Qué estoy haciendo mal?

No empezar a cero He leído otra pregunta y he leído un poco cómo código de código de ejemplo y mi código se asemeja a ese código de ejemplo. También he estado leyendo algunos de la documentación de servicio por conveniencia aquí es una pequeña cotización de esa sección de la documentación:

Un servicio enlazado ofrece una interfaz cliente-servidor que permite a los componentes interactuar con el servicio, enviar solicitudes, obtener resultados e incluso hacerlo a través de procesos Con la comunicación interproceso (IPC) Un servicio enlazado se ejecuta sólo siempre y cuando otro componente de la aplicación está vinculado a ella.Múltiples componentes pueden enlazar al servicio a la vez, pero cuando todos ellos se desvinculan, el servicio se destruye.

Pero no puedo hacer eso. Como se mencionó anteriormente lo mejor que puedo hacer es tener mis métodos de llamada de actividad definidos en mi LocalBinder. No he conseguido nada como la parte destacada en negro arriba.

Si esto ayuda aquí están las porciones relevantes de mi código.

LocalService estará obligado a:

/************************************************************************************************** * Filename: LocalService.java * Project name: Local Service Sample * Application name: Local Service * Description: This file contains the LocalService (extends Service) for our Local Service app **************************************************************************************************/ package com.marie.localservicesample; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.Intent; import android.os.Bundle; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; import android.widget.Toast; public class LocalService extends Service { private NotificationManager mNM; // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. private int NOTIFICATION = R.string.local_service_started; // just some arbitrary numbers for test purposes public static int statusCode = 99; public static int emptyMsg = 549; // I get my Extras from onStartCommand and use in ServiceWorker() thread public static final String EXTRA_MAC = "com.marie.localservicesample.EXTRA_MAC"; private String macString; public static final String EXTRA_MESSENGER = "com.marie.localservicesample.EXTRA_MESSENGER"; private Messenger messenger; private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //private static final String macString = "00:06:66:02:D0:EC"; Boolean stop_receive_data = false; // This is the object that receives interactions from clients. See // RemoteService for a more complete example - or not because // this is a local service private final IBinder mBinder = new LocalBinder(); @Override public IBinder onBind(Intent intent) { Log.i("onBind", "called in LocalService" ); Log.i("onBind", "intent: " + intent.toString()); Log.i("onBind", "mBinder: " + mBinder); return mBinder; } @Override public void onCreate() { mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); // Display a notification about us starting. We put an icon in the status bar. showNotification(); } // Call this at the end of onStartCommand() after we got the Extras public void afterStartCommand() { Thread thr = new Thread(null, new ServiceWorker(), "LocalService"); thr.start(); } /* * This is the ServiceWorker thread that passes messages to the handler defined in * the Controller activity. */ class ServiceWorker implements Runnable { public void run() { // do background processing here... something simple Looper.prepare(); BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothDevice btDevice = btAdapter.getRemoteDevice(macString); BluetoothSocket btSocket = null; InputStream btIstream = null; OutputStream btOstream = null; try { btSocket = btDevice.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e1) { e1.printStackTrace(); } try { btSocket.connect(); } catch (IOException e1) { e1.printStackTrace(); } try { btIstream = btSocket.getInputStream(); btOstream = btSocket.getOutputStream(); } catch (IOException e1) { e1.printStackTrace(); } try { int data = btIstream.read(); // reset the bluetooth device while (data != 63) { Log.d("LocalService", "resetting bluetooth device"); btOstream.write('r'); data = btIstream.read(); } StringBuffer strBuffer = new StringBuffer(""); Boolean dataBegin = false; int ndxPlus = 0; while (data != -1) { char printableB = (char) data; if (data < 32 || data > 126) { //printableB = ' '; } //Log.d("LocalService", Character.toString(printableB) + "(" + data + ")"); if (data == 63) { btOstream.write('$'); btOstream.write(','); } if (data == 45) { btOstream.write('1'); btOstream.write(','); dataBegin = true; } if (dataBegin == true) { strBuffer = strBuffer.append(Character.toString(printableB)); } if (data == 13) { dataBegin = false; //Log.d("LocalServiceDataString", strBuffer.toString()); // send data to the handler to plot the data Message msg = Message.obtain(); msg.what = Controller.MESSAGE_MAC; msg.obj = strBuffer; try { messenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); } strBuffer = new StringBuffer(""); if (ndxPlus < 0) { btOstream.write('+'); ndxPlus++; } } data = btIstream.read(); if (stop_receive_data) data = -1; } } catch (IOException e1) { e1.printStackTrace(); } try { btSocket.close(); } catch (IOException e1) { e1.printStackTrace(); } LocalService.this.stopSelf(); Looper.loop(); // stop the service when done... // Or use the unbindBtn in the MainActivity class? } } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("LocalService", "Received start id " + startId + ": " + intent); Bundle extras = intent.getExtras(); messenger = (Messenger)extras.get(EXTRA_MESSENGER); macString = extras.getString(EXTRA_MAC); afterStartCommand(); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } @Override public void onDestroy() { // Cancel the persistent notification. mNM.cancel(NOTIFICATION); stop_receive_data = true; // Tell the user we stopped. Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); } /** * Show a notification while this service is running. */ private void showNotification() { // In this sample, we'll use the same text for the ticker and the expanded notification CharSequence text = getText(R.string.local_service_started); // Set the icon, scrolling text and timestamp Notification notification = new Notification(R.drawable.stat_sample, text, System.currentTimeMillis()); // The PendingIntent to launch our activity if the user selects this notification PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Controller.class), 0); // Set the info for the views that show in the notification panel. notification.setLatestEventInfo(this, getText(R.string.local_service_label), text, contentIntent); // Send the notification. mNM.notify(NOTIFICATION, notification); } } 

Actividad que se enlaza a LocalService:

 /************************************************************************************************** * Filename: Binding.java * Project name: Local Service Sample * Application name: Local Service * Description: This file contains the Binding class for our Local Service application **************************************************************************************************/ package com.marie.localservicesample; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; /* * Example of binding and unbinding to the local service. * This demonstrates the implementation of a service which the client will * bind to, receiving an object through which it can communicate with the service. */ public class Binding extends Activity { private ILocalBinder mBoundService; private boolean mIsBound; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. Because we have bound to a explicit // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it. mBoundService = (ILocalBinder)service; int statusCode = mBoundService.getStatusCode(); Log.d("Binding.java","called onServiceConnected. statusCode: " + statusCode); Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show(); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Log.d("Binding", "called onServiceDisconnected"); Toast.makeText(Binding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show(); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } void doUnbindService() { if (mIsBound) { int statusCode = mBoundService.getStatusCode(); if (statusCode != 0) Log.d("doUnbindService", "Binding.java statusCode: " + statusCode); // Tell the user we did an unbind Toast.makeText(this, R.string.local_service_unbound, Toast.LENGTH_SHORT).show(); // Detach our existing connection. unbindService(mConnection); mIsBound = false; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.local_service_binding); // Watch for button clicks. Button button = (Button)findViewById(R.id.bind); button.setOnClickListener(mBindListener); button = (Button)findViewById(R.id.unbind); button.setOnClickListener(mUnbindListener); } private OnClickListener mBindListener = new OnClickListener() { public void onClick(View v) { doBindService(); } }; private OnClickListener mUnbindListener = new OnClickListener() { public void onClick(View v) { doUnbindService(); } }; @Override protected void onDestroy() { super.onDestroy(); doUnbindService(); } } 

Mi ILocalBinder y LocalBinder:

 /************************************************************************************************** * Filename: ILocalBinder.java * Project name: Local Service Sample * Application name: Local Service * Description: This file contains an example interface for my LocalBinder **************************************************************************************************/ package com.marie.localservicesample; public interface ILocalBinder { public int getStatusCode(); } /************************************************************************************************** * Filename: LocalBinder.java * Project name: Local Service Sample * Application name: Local Service * Description: This file contains the LocalBinder class for our Local Service application **************************************************************************************************/ package com.marie.localservicesample; import android.os.Binder; import com.marie.localservicesample.LocalService; /** * Class for clients to access. Because we know this service always * runs in the same process as its clients, we don't need to deal with * IPC. */ public class LocalBinder extends Binder implements ILocalBinder { @Override public int getStatusCode() { return LocalService.statusCode; } } 

¡Gracias!

Vea el ejemplo del servicio local .

Simplemente copie el código de la clase del encuadernador que tienen en su servicio en lugar de crear un archivo separado para él: (dentro de la declaración de clase LocalService)

 public class LocalService { // This is the object that receives interactions from clients. See // RemoteService for a more complete example. private final IBinder mBinder = new LocalBinder(); /** * Class for clients to access. Because we know this service always * runs in the same process as its clients, we don't need to deal with * IPC. */ public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } } ... } 

y entonces:

 public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. Because we have bound to a explicit // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it. mBoundService = ((LocalService.LocalBinder)service).getService(); 

Ahora puede acceder a su servicio directamente usando mBoundService.

  • Descubrimiento del servicio de red error de tutorial android: Servicio perdido, el teléfono se desactiva
  • El servicio de Android solo se inicia en modo de depuración
  • Servicio de Android y tareas repetitivas que se ejecutan en subprocesos
  • Android: mantener el servicio en ejecución cuando se mata la aplicación
  • GCM de Android SERVICE_NOT_AVAILABLE
  • Detectar el evento "botón de inicio presionado" en el servicio android que muestra una interfaz de usuario (similar a los cabezales de chat de Facebook)
  • Cómo repetir la notificación diaria en el tiempo específico en androide a través del servicio de fondo
  • Iniciar servicio desde la notificación
  • Cómo iniciar una tarea de fondo de larga ejecución en el servicio de Android
  • Android ¿cómo espero hasta que un servicio esté realmente conectado?
  • ¿Es posible utilizar la herencia en las interfaces AIDL?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.