2011-10-24 14 views
8

私のJavaScriptがサービスとの間でメッセージの送受信を行うためのPhonegap(Android)のプラグインを作成しようとしています。 私の正確な問題は、メッセージが非同期に戻るため、PluginResultをプラグインの実行機能に送ることができないということです。phonegapプラグインからアンドロイド・サービス・リターン・メッセージを受け取る方法

これは、プラグインのコードです:本当の悩みをプラグインこのことから

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

私が考えることができる唯一の解決策は、応答をデータベースまたは変数に格納し、javascriptでsetIntervalを実行して変更を確認し続けることです。しかし、私はこの解決策があまり好きではありません。私はJavaScriptがメッセージが返されたことを知らせるコールバック関数のいくつかの並べ替えを使用したいと思いますが、私はどのように考えている。私は何か助けとアイデアを大いに感謝します。

は、 ヴラド

答えて

6

です遅い答えが、私は約5ヶ月のCordova Pluginで作業を始めました私はちょうどあなたの質問を見ました。あなたが正しい答えを選んでいないので、私はあなたの質問に答えたいと思っていました。

非同期プロセスがあり、リスナーとメソッド(成功と失敗)があるとすると、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

をいただき、ありがとうございます。この問題への一般的な解決策は、(データベースのような)永続ストレージにサービス店に応答があり、その後、放送の意図をオフに解雇することです。次に、ServiceClient_pluginクラスのBroadcastRecieverにブロードキャストを待ちます。この方法では、データがまだ到着していないかどうかをポーリングし続ける必要はありません。

+0

BroadcastRecieverの回答でgithub.comのサンプルプラグインが表示されましたが、実際に私が探していたものが見つかりました。 –

4

私の問題に対する答えは、実際にはPluginResultオブジェクトと成功メソッドです。 私は同じ問題に直面していたプラグインを見つけました。このコードから、私は答えを見つけ出すことができました。これは、hereというonPhoneStatusChangeプラグインです!

謎は、これらの行にある:

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

あなたはこのようsuccess()機能を使用してPluginResultを送ることができます。

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

ここcallbackはこれがあるかもしれないcallbackId​​の機能

関連する問題