Cómo obtener un mensaje de devolución de servicio de Android desde un plugin de teléfono

Estoy tratando de hacer un complemento para Phonegap (Android) que permite a mi javascript para enviar y recibir mensajes a / de un servicio. Mi problema exacto es que, como los mensajes vuelven asíncronos, no puedo enviar el PluginResult a la función de ejecución del complemento.

Este es el código del complemento:

public class ServiceClient_plugin extends Plugin { Messenger messenger_service=null; boolean connected_to_service=false; final Messenger messenger_receive = new Messenger(new IncomingHandler()); @Override public PluginResult execute(String action, JSONArray data, String callbackId) { PluginResult result = null; try { if (action.toUpperCase().equals("CONNECT")) { result = ConnectService(); } else if (action.toUpperCase().equals("DISCONNECT")) { result = DisconnectService(); } else if (action.toUpperCase().equals("IS_CONNECTED")) { result = new PluginResult(Status.OK,connected_to_service); } else if (action.toUpperCase().equals("COMMAND")) { sendMSG (data.getString(0)); result = new PluginResult(Status.OK); } else { result = new PluginResult(Status.INVALID_ACTION); } } catch(JSONException e) { result= new PluginResult(PluginResult.Status.JSON_EXCEPTION); } return result; } private PluginResult ConnectService() { doBindService(); return new PluginResult(Status.OK); } private PluginResult DisconnectService() { doUnbindService(); return new PluginResult(Status.OK); } class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MoMe_Service.MSG_COMMAND: Log.i("CLIENT","Received from service: " + msg.getData().getString("MSG")); break; default: super.handleMessage(msg); } } } private ServiceConnection service_connection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { messenger_service = new Messenger(service); connected_to_service=true; try { Message msg = Message.obtain(null, My_Service.MSG_REGISTERED); msg.replyTo = messenger_receive; messenger_service.send(msg); } catch (RemoteException e) { // In this case the service has crashed before we could even // do anything with it; we can count on soon being // disconnected (and then reconnected if it can be restarted) // so there is no need to do anything here. } } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. messenger_service = null; connected_to_service=false; } }; private void doBindService() { // Establish a connection with the service. We use an explicit // class name because there is no reason to be able to let other // applications replace our component. this.ctx.bindService(new Intent(this.ctx, My_Service.class), service_connection, Context.BIND_AUTO_CREATE); } private void doUnbindService() { if (connected_to_service) { if (messenger_service != null) { try { Message msg = Message.obtain(null, My_Service.MSG_UNREGISTERED); msg.replyTo = messenger_receive; messenger_service.send(msg); } catch (RemoteException e) { // There is nothing special we need to do if the service // has crashed. } } // Detach our existing connection. this.ctx.unbindService(service_connection); connected_to_service = false; } } private void sendMSG (String message) { try { Message msg=Message.obtain(null, My_Service.MSG_COMMAND); Bundle msg_bundle=new Bundle(); msg_bundle.putString("MSG", message); msg.setData(msg_bundle); messenger_service.send(msg); } catch (RemoteException e) { doUnbindService(); } } } 

Desde este plugin el verdadero problema viene con esta parte del código, que maneja los mensajes de retorno y el retorno de plugin (que va al javascript):

  @Override public PluginResult execute(String action, JSONArray data, String callbackId) { PluginResult result = null; try { result = new PluginResult(Status.ok); } } catch(JSONException e) { result= new PluginResult(PluginResult.Status.JSON_EXCEPTION); } return result; } class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MoMe_Service.MSG_COMMAND: msg.getData().getString("MSG")); // THIS IS THE DATA I NEED RETURNED break; default: super.handleMessage(msg); } } } 

La única solución que puedo pensar, es almacenar la respuesta en una base de datos o una variable y tener el javascript hacer un setInterval para seguir buscando los cambios. Sin embargo, no soy muy aficionado a esta solución. Me gustaría usar algún tipo de función de devolución de llamada para que el javascript sepa que el mensaje ha vuelto pero no tengo idea de cómo hacerlo. Agradecería mucho cualquier ayuda e ideas.

Gracias, Vlad

Esto podría ser una respuesta tardía, pero empecé a trabajar con Cordova Plugin hace 5 meses y acabo de ver tu pregunta. Como no eligió la respuesta correcta, quise responder a su pregunta.

Suponiendo que tiene un proceso asíncrono y tiene un oyente y los métodos, el éxito y el error, vamos a llamar a onSuccess() y onFail() . Siempre y cuando envíe true con pluginResult.setKeepCallback(true) , el proceso permanecerá como inacabado, por lo que puede enviar los datos de los resultados de complemento más adelante cuando haya terminado con el proceso de fondo. Aquí está un ejemplo echar un vistazo.

 @Override public boolean execute(String action, JSONArray data, String callbackId) throws JSONException { if (action.equals("start")) { start(); } else { PluginResult pluginResult = new PluginResult(PluginResult.Status.INVALID_ACTION); callbackContext.sendPluginResult(pluginResult); return false; } } private boolean start() throws JSONException { MyClass.startProcess(new MyInterface() { @Override public void onSuccess(String data) { PluginResult result = new PluginResult(PluginResult.Status.OK, data); result.setKeepCallback(false); callbackContext.sendPluginResult(result); } @Override public void onFail() { PluginResult result = new PluginResult(PluginResult.Status.ERROR); result.setKeepCallback(false); callbackContext.sendPluginResult(result); } }); PluginResult.Status status = PluginResult.Status.NO_RESULT; PluginResult pluginResult = new PluginResult(status); pluginResult.setKeepCallback(true); callbackContext.sendPluginResult(pluginResult); return true; } 

La respuesta a mi problema fue en realidad en el objeto PluginResult y el método de éxito. He encontrado un complemento que tuvo que hacer frente al mismo problema con el fin de trabajar, y de este código he sido capaz de averiguar mi answer.This es un plugin onPhoneStatusChange, que se puede encontrar aquí !

El misterio está en estas líneas:

 PluginResult res = new PluginResult(PluginResult.Status.OK, obj); res.setKeepCallback(true); success(res, callbackId); 

La solución genérica a este problema es tener el almacén de servicios la respuesta en almacenamiento persistente (como una base de datos) y luego disparar una intención de difusión. Entonces sólo tiene un BroadcastReciever en su clase ServiceClient_plugin escuchando la emisión. De esta manera usted woun't tiene que seguir sondeando para ver si los datos han llegado todavía.

Puede enviar PluginResult utilizando la función success() siguiente manera:

 public PluginResult execute(String action, JSONArray data, String callbackId) {} private BroadcastReceiver Wifi_Receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { MyClass.this.success(new PluginResult(PluginResult.Status.OK,"count"+count),callback); } } 

Aquí callback es callbackId de la función execute()

  • Google Map en dispositivos móviles
  • Deshabilitar el almacenamiento en caché, las cookies y todo lo demás en un WebView
  • Descargar el archivo a la carpeta de descargas ios / android using phonegap
  • Android Development - Para hacer referencia a un campo, ¿es necesario usar "this"?
  • Android - Webview, cuadros de entrada dobló?
  • Cómo crear directorios anidados en Phonegap
  • Ejecución de la ecuación matemática en Android
  • Concatenar y minify los archivos del plugin cordova / phonegap
  • window.close equivalente en Phonegap con InAppBrowser
  • JQuery Autocompletar trabajando en Chrome pero no en android usando phonegap
  • Crear un objeto dos veces produce resultados diferentes
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.