Comment obtenir un message de retour du service Android à partir d'un plugin Phonegap

J'essaie de créer un plugin pour Phonegap (Android) qui permet à mon javascript d'envoyer et de recevoir des messages à partir d'un service. Mon problème exact est que, parce que les messages retournent de manière asynchrone, je ne peux pas envoyer le PluginResult à la fonction d'exécution du plugin.

C'est le code du plugin:

  • Obtenez le compte de messagerie principal du téléphone Android
  • Raw Sockets sur Android
  • Modification de la couleur du diviseur NumberPicker
  • NoClassDefFoundError avec Android Studio sur Android 4
  • Y a-t-il déjà une classe StopWatch pour Android et pourquoi ma mise en œuvre ne fonctionne-t-elle pas?
  • Contenu central de TextView verticalement et horizontalement - LinearLayout
  • 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(); } } } 

    À partir de ce plugin, le problème réel vient avec cette partie du code, qui gère les messages de retour et le retour du plugin (ce qui correspond au 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 seule solution pour laquelle je peux penser est de stocker la réponse soit dans une base de données ou dans une variable, et javascript doit faire un setInterval pour continuer à vérifier les modifications. Cependant, je ne suis pas très friand de cette solution. J'aimerais utiliser une sorte de fonction de rappel pour permettre au javascript de savoir si le message est revenu, mais je n'ai aucune idée de la façon dont. J'apprécierais grandement toute aide et toute idée.

    Merci Vlad

  • Comment supprimer des dossiers dans sdcard of file explorer dans Android
  • GSON lance "BEGIN_OBJECT attendu mais BEGIN_ARRAY"?
  • Quels sont les fichiers IML dans Android Studio?
  • Android TransitionDrawable avec plusieurs éléments
  • Numéro de téléphone formant un EditText dans Android
  • Comment puis-je gérer Map Pass Fin en utilisant Google Maps pour Android V2?
  • 4 Solutions collect form web for “Comment obtenir un message de retour du service Android à partir d'un plugin Phonegap”

    Ce pourrait être une réponse tardive, mais j'ai commencé à travailler avec Cordova Plugin il y a environ 5 mois et je viens de voir votre question. Comme vous n'avez pas choisi la bonne réponse, je voulais répondre à votre question.

    En supposant que vous avez un processus asynchrone et que vous avez un auditeur et des méthodes, réussissez et échouez, appelez-le onSuccess() et onFail() . Tant que vous envoyez true avec pluginResult.setKeepCallback(true) , le processus restera inachevé, afin que vous puissiez envoyer vos données de résultats de plugin plus tard lorsque vous avez terminé le processus de fond. Voici un exemple, regardez.

     @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 réponse à mon problème était en fait dans l'objet PluginResult et la méthode de succès. J'ai trouvé un plugin qui devait faire face au même problème pour fonctionner, et à partir de ce code, j'ai pu trouver ma réponse. C'est un plugin onPhoneStatusChange, qui peut être trouvé ici !

    Le mystère réside dans ces lignes:

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

    La solution générique à ce problème est de faire en sorte que le service stocke la réponse dans un stockage persistant (comme une base de données) puis déclenche une intention de diffusion. Ensuite, il suffit d'avoir BroadcastReciever dans votre classe ServiceClient_plugin en écoutant la diffusion. De cette façon, vous devrez garder le sondage pour voir si les données sont encore arrivées.

    Vous pouvez envoyer PluginResult utilisant success() fonction comme ceci:

     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); } } 

    Ici callback is callbackId de la fonction execute()

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.