2011-10-24 12 views
8

मैं फोनगैप (एंड्रॉइड) के लिए प्लगइन बनाने की कोशिश कर रहा हूं जो मेरी जावास्क्रिप्ट को सेवा भेजने/प्राप्त करने की अनुमति देता है। मेरी सटीक समस्या यह है कि, क्योंकि संदेश एसिंक्रोनस लौटते हैं, मैं प्लगइन के निष्पादन फ़ंक्शन में प्लगइनरसेट भेज नहीं सकता।फ़ोनगैप प्लगइन से एंड्रॉइड सेवा रिटर्न संदेश कैसे प्राप्त करें

:

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

} 

इस से प्लगइन असली मुसीबत कोड के इस भाग है, जो बदले गए संदेशों और प्लगइन वापसी (जो जावास्क्रिप्ट को जाता है) संभालती के साथ आता है:

इस प्लगइन कोड है

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

एकमात्र समाधान जिसे मैं सोच सकता हूं, डेटाबेस या चर में प्रतिक्रिया संग्रहीत कर रहा है और जावास्क्रिप्ट को परिवर्तनों की जांच करने के लिए एक सेट अंतराल है। हालांकि मैं इस समाधान का बहुत शौक नहीं हूं। मैं कुछ प्रकार के कॉलबैक फ़ंक्शन का उपयोग करना चाहता हूं ताकि जावास्क्रिप्ट को यह पता चल सके कि संदेश वापस आ गया है लेकिन मुझे नहीं पता कि कैसे। मैं किसी भी मदद और विचारों की सराहना करता हूं।

धन्यवाद, Vlad

उत्तर

6

की callbackId है यह एक हो सकता है देर से जवाब दिया लेकिन मैंने 5 महीने के आसपास कॉर्डोवा प्लगइन के साथ काम करना शुरू कर दिया ओ और मैंने अभी आपका प्रश्न देखा है। चूंकि आपने सही उत्तर नहीं चुना है, इसलिए मैं आपके प्रश्न का उत्तर देना चाहता हूं।

मान लें कि आपके पास एसिंक्रोनस प्रक्रिया है और आपके पास श्रोता और विधियां, सफलता और असफलता है, इसे onSuccess() और onFail() पर कॉल करें। जब तक आप pluginResult.setKeepCallback(true) के साथ सच भेजते हैं, तो प्रक्रिया अधूरा रहेगी, इसलिए जब आप पृष्ठभूमि प्रक्रिया के साथ होते हैं तो आप अपना प्लगइन परिणाम डेटा भेज सकते हैं। यहां एक उदाहरण देखें।

@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; 

    } 
1

इस समस्या का समाधान सामान्य सेवा की दुकान (एक डेटाबेस की तरह) स्थायी संग्रह में प्रतिक्रिया और फिर एक प्रसारण का आशय बताएं है। फिर प्रसारण के लिए सुनकर अपनी सेवा क्लाइंट_प्लगिन कक्षा में ब्रॉडकास्ट रिसीवर रखें। इस तरह आपको यह देखने के लिए मतदान करना होगा कि डेटा अभी तक पहुंच गया है या नहीं।

+0

त्वरित उत्तर के लिए धन्यवाद, आपका ब्रॉडकास्ट रिसीवर जवाब मुझे github.com पर कुछ नमूना प्लगइन का नेतृत्व करता है और मुझे वास्तव में वह मिला जो मैं वहां देख रहा था। –

4

मेरी समस्या का उत्तर वास्तव में प्लगइनResult ऑब्जेक्ट और सफलता विधि में था। मुझे एक प्लगइन मिला है जो काम करने के लिए एक ही समस्या का सामना करना पड़ा था, और इस कोड से मैं अपना जवाब समझने में सक्षम था। यह एक ऑन-फ़ोनस्टैटस चेंज प्लगइन है, जिसे here मिल सकता है!

रहस्य इन पंक्तियों में निहित है:

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

आप PluginResult इस तरह success() समारोह का उपयोग कर भेज सकते हैं:

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); 
    } 
} 
यहाँ

callbackexecute() समारोह

संबंधित मुद्दे