したがって、CordovaPlugin
を拡張するクラスを作成してexecute()
をオーバーライドし、JSとネイティブJava(Androidの場合)の間にブリッジを作成することを誰もが知っています。 。さらに、PluginResult
を使用して結果をJSに返します。
したがって、JSからJavaプラグインへのリクエストが発生したときに、これらすべてが発生します。私の質問は、結果をJSに返す方法(そしてしたがって、HTMLへ)非同期に?
単語非同期がここにあるかどうかはわかりません。問題は、すぐにJSに何かを送り返すことです(たとえば、wifiが有効/無効になったとき)。
私はすでにこれについて調査しましたが、私のケースに合うものはありません。
私が試したことは-
BroadcastReceiver
クラスを使用してWiFi
イベントをリスニングするWifiManager
を作成しました。Toast
が有効/無効になっているときにWiFi
をポップし、CallbackContext
を使用して結果を送信しますcallbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, "Wifi Connected"))
および別のメッセージで切断された場合。MyPlugin.Java
import org.Apache.cordova.CallbackContext;
import org.Apache.cordova.CordovaPlugin;
import org.Apache.cordova.PluginResult;
import org.json.JSONArray;
...
public class MyPlugin extends CordovaPlugin {
private WifiReceiver wifiBroadcastReceiver = null;
private CallbackContext callbackContext = null;
...
public MyPlugin() {
wifiBroadcastReceiver = new WifiReceiver();
...
}
...
public boolean execute(String action, final JSONArray args,
final CallbackContext callbackId) throws JSONException {
IntentFilter wifiFilter = new IntentFilter(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
cordova.getActivity().registerReceiver(wifiBroadcastReceiver, wifiFilter);
this.callbackContext = callbackId;
...
}
public class WifiReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
Toast.makeText(cordova.getActivity(), "Wifi Connected", Toast.LENGTH_SHORT).show();
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, "Wifi Connected"));
} else {
Toast.makeText(cordova.getActivity(), "Wifi Disconnected", Toast.LENGTH_SHORT).show();
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Wifi Disconnected"));
}
}
}
}
Toast
はポップしますが、PluginResult
はJSに送信されません。
PS: WiFiイベントをリッスンすることは私の実際の問題ではありません。Android Bluetooth Chat
Phonegapのアプリ。したがって、それは本質的に非同期でなければなりません。
あと少しですが、PluginResultでKeepCallbackをtrueに設定する必要があります。 Java側からの後続の結果がない場合、JavaScript側にコールバックはありません。このタイプのコーディングの最良の例は、Cordovaコアのネットワークプラグインです。ここにソースへのリンク:
したがって、コードを次のように更新する必要があります。
public boolean execute(String action, final JSONArray args,
final CallbackContext callbackId) throws JSONException {
IntentFilter wifiFilter = new IntentFilter(
WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
cordova.getActivity().registerReceiver(wifiBroadcastReceiver,
wifiFilter);
this.callbackContext = callbackId;
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
result.setKeepCallback(true);
this.callbackContext.sendPluginResult(result);
return true;
}
public class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
PluginResult result;
if (intent.getBooleanExtra(
WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
Toast.makeText(cordova.getActivity(), "Wifi Connected",
Toast.LENGTH_SHORT).show();
result = new PluginResult(PluginResult.Status.OK,
"Wifi Connected");
} else {
Toast.makeText(cordova.getActivity(), "Wifi Disconnected",
Toast.LENGTH_SHORT).show();
result = new PluginResult(PluginResult.Status.ERROR,
"Wifi Disconnected");
}
result.setKeepCallback(false);
if (callbackContext != null) {
callbackContext.sendPluginResult(result);
callbackContext = null;
}
}
}
}
「2番目のコールバック」警告への回答...
この警告をトリガーするCordovaソースコードは、57行目の次の場所にあります。
したがって、CallbackContextオブジェクトに「finished = true」があるため、警告が発生します。
この原因として最も可能性が高いのは次の呼び出しです:callbackContext.sendPluginResult(pluginResult);
最初の呼び出しなし:pluginResult.setKeepCallback(true);
そうでない場合...CallbackContextオブジェクトを誤ってキャッシュしている可能性があります
Execute()関数は、呼び出されるたびにCallbackContextを割り当てる必要があります。にリンクされている コードSimonの125〜127行目を参照してください :
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
if (action.equals("getConnectionInfo")) {`
this.connectionCallbackContext = callbackContext;
...
完全なイベントの適切なシーケンス:
プラグインを最初に呼び出します。
プラグインは、渡されたCallbackContextオブジェクトへの参照を保存します。
SetKeepCallback(true)で結果を返す間、CallbackContextオブジェクト参照を保持します。
シーケンスが終了したら、setKeepCallback(false)で戻ります(デフォルト)。
じゃあ後で...
プラグインをもう一度呼び出します。
プラグインは、保存されたCallbackContext参照を上書きし、渡されたオブジェクトで置き換えます。
次に、上記と同じ手順3〜4を実行します。
それが役に立てば幸い:)