Notificar a un servicio de Android cuando un cliente vinculado se desconecta

Tengo un servicio androide en un proceso remoto que puede tener múltiples enlaces de diferentes clientes. Mi pregunta es, ¿cómo puede notificarse el servicio cuando un cliente vinculado específico se desconecta inesperadamente (es decir, el cliente se ha estrellado)? No puedo usar onUnbind() , porque sólo se llama después de que todos los clientes se han desconectado.

 public class MyService extends Service { final Messenger mServiceMessenger = new Messenger(new IncomingHandler()); @Override public IBinder onBind(Intent intent) { return mServiceMessenger.getBinder(); } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return Service.START_STICKY; } class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { // Handling messages logic... } } } 

2 Solutions collect form web for “Notificar a un servicio de Android cuando un cliente vinculado se desconecta”

Puede utilizar el manejador IncomingHandler que tiene y enviar un mensaje desde el cliente que será unbinded antes de llamar unbindService (serviceConnection), manteniendo arraylist de los mensajeros (clientes) y agregar / quitar cuando se recibe un mensaje.

También puede intentar enviar mensajes falsos y si recibe RemoteException significa que el cliente remoto está muerto.

Compruebe este ejemplo http://developer.android.com/reference/android/app/Service.html

extraer:

 class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; case MSG_SET_VALUE: mValue = msg.arg1; for (int i=mClients.size()-1; i>=0; i--) { try { mClients.get(i).send(Message.obtain(null, MSG_SET_VALUE, mValue, 0)); } catch (RemoteException e) { // 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); } } } 

Esto se puede hacer por el mecanismo Binder.linkToDeath() – Tendrá que pedir a cada cliente que envíe un new Binder() objeto new Binder() que inició y luego enlazar con su muerte (de sus clientes). Voy a explicar cómo hacer esto utilizando los archivos AIDL .

(Usted puede elegir cualquier mecanismo del IPC del androide mientras usted pueda pasar los objetos de la carpeta de su cliente a su servicio)

Ejemplo de código –

Dentro de su archivo .AIDL – Cree un método para pasar el objeto IBinder desde el cliente al servicio

 void registerProcessDeath(in IBinder clientDeathListener, String packageName); 

En el lado del cliente – Inicialice un nuevo objeto y lo pasará a su servicio a través de la interfaz AIDL.

 public void onServiceConnected(ComponentName className, IBinder service) { mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); //Call the registerProcessDeath method from the AIDL file and pass //the new Binder object and the client's package name mIMyAidlInterface.registerProcessDeath(new Binder(),getPackageName()); } 

En el lado del servicio

1. Obtener la Binder del cliente y registrarse en su linkToDeath() .
2. Utilizar la clase auxiliar para manejar todos los clientes a través de la clase IBinder.DeathRecipient de android

 public class MyService extends Service { //Helper class to handle all client's deaths. private volatile ClientsDeathWatcher mClientsList; @Override public IBinder onBind(Intent intent) { mClientsList = new ClientsDeathWatcher(); return mStub; } private final IMyAidlInterface.Stub mStub = new IMyAidlInterface.Stub() { @Override public void registerProcessDeath(IBinder cb, String packageName){ boolean isRegistered = mClientsList.register(cb , packageName); } }; } //This is thread-safe helper class to handle all //the client death related tasks. //All you care abut is the clientDeath() method. public class ClientsDeathWatcher { private ArrayMap<String, DeathCallBack> mCallbacks = new ArrayMap<>(); private final class DeathCallBack implements IBinder.DeathRecipient { private String pn; private IBinder mBinder; DeathCallBack(String packageName,IBinder binder) { pn = packageName; mBinder = binder; } public void binderDied() { synchronized (mCallbacks) { mBinder.unlinkToDeath(this,0); clientDeath(pn); } } } //To be called only from thread-safe functions private void clientDeath(String packageName) { mCallbacks.remove(packageName); //Do your stuff here. //$$$$$$$$$ } public boolean register(IBinder token, String packageName) { synchronized (mCallbacks) { try { if (!mCallbacks.containsKey(packageName)) { DeathCallBack mDeathCallBack = new DeathCallBack(packageName,token); mCallbacks.put(packageName, mDeathCallBack); //This is where the magic happens token.linkToDeath(mDeathCallBack, 0); } return true; } catch (RemoteException e) { e.printStackTrace(); return false; } } } } 
  • ¿Qué es un servicio web en android?
  • ¿Cómo enviar notificaciones a la aplicación de Android desde el servidor de Java mediante GCM?
  • Los datos Xml se convierten en datos Json en android
  • Envío de un mensaje sencillo de Servicio a Actividad
  • Envío de un archivo pdf al cliente desde el servidor a través del servicio web
  • StartForeground () no muestra mi notificación
  • Excepción de puntero nulo que hace difícil pasar un arreglo usando ksoap
  • Se esperaba BEGIN_OBJECT pero era BEGIN_ARRAY en la línea 1 columna 2 (edición pequeña)
  • ¿Cómo acceder a un contexto de aplicación ya en ejecución desde un servicio de adaptador de sincronización en Android?
  • ¿Por qué utilizar sqlite Database en Android?
  • Consumir servicio REST Web y analizar datos XML en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.