AndroidJavaとPhonegapJavascript間の通信?


81

(PhoneGap)JavascriptからJavaメソッドを呼び出すことは可能だと思います。

誰もがそれを行う方法を知っていますか?(PhoneGapのソースコードを変更してそれを行う方法を知っていますが、それは避けたいと思います)

回答:


125

私はついにそれを機能させました。

  • 使用するメソッドを使用してクラスを作成します。

    public class MyClass {
      private WebView mAppView;
      private DroidGap mGap;
    
      public MyClass(DroidGap gap, WebView view)
      {
        mAppView = view;
        mGap = gap;
      }
    
      public String getTelephoneNumber(){
        TelephonyManager tm = 
          (TelephonyManager) mGap.getSystemService(Context.TELEPHONY_SERVICE);
        String number = tm.getLine1Number();
        return number;
      }
    }
    
  • メインアクティビティで、このクラスのJavascriptインターフェースを追加します。

    public class Main extends DroidGap
    {
        private MyClass mc;
    
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            super.init();
    
            mc = new MyClass(this, appView);
            appView.addJavascriptInterface(mc, "MyCls");
    
            super.loadUrl(getString(R.string.url));
        }
    }
    
  • Javascript呼び出しwindow.MyClsメソッド:

    <script>
      $(function(){
        $("#phone").text("My telephone number is: " + 
                window.MyCls.getTelephoneNumber());
      });
    </script>
    

注意:

コメントに記載されているように、Androidバージョン4.2以降の@JavascriptInterface場合は、HTMLページからアクセスするメソッドに追加します。参照


うーん、この例は素晴らしいですが、appViewでnullpointerExceptionが発生します。nullのようです。オブジェクトをどこで初期化しますか?

1
super.init();を追加します。下記の@Karfieldのように、nullpointerExceptionが修正されました。
Renato H.

8
よくやった!ヒント:逆の方法(JavaからJavascriptへ)で通信する場合は、次を使用します。mGap.sendJavascript( "window.myJavascriptFunction( 'some parameter');");
aeldron 2012年

5
E / Web Console(2513):Uncaught TypeError:Object [object Object] has no method'sendEmail 'at file:///android_asset/www/loginfile.js:142 window.Mycls.sendEmail( "rea@gmail.com" ); この行でエラーが発生する
Deepu Mandy 2013

2
私はAndroid4.2.2でこのコードを試しましたが、Deepuと同じような問題に直面しました。つまり、Uncaught TypeError:Object [objectObject]にはfile:/// android_asset / www / app.js:142にメソッド 'getTelephoneNumber'がありません。いくつかのデバッグの後、上記の4.2.2リンクの
Akshay

14

addJavaScriptInterface(mc, "MyCls")ギャップinit()がないとアプリがクラッシュする可能性があるため、super.init()前に追加することをお勧めしますaddJavascriptInterface()

public class Main extends DroidGap
{
   private MyClass mc;

   @Override
   public void onCreate(Bundle savedInstanceState)
   {
       super.onCreate(savedInstanceState);

       super.init();

       mc = new MyClass(this, appView);
       appView.addJavascriptInterface(mc, "MyCls");

       super.loadUrl(getString(R.string.url));
   }
}

9

PhoneGapにはまともなプラグインAPIがあります。IPluginインターフェースを実装することにより、Javaでプラグインを作成します。魔法のほとんどはexecute()関数にあります。

public interface IPlugin {

    /**
     * Executes the request and returns PluginResult.
     *
     * @param action        The action to execute.
     * @param args          JSONArry of arguments for the plugin.
     * @param callbackId    The callback id used when calling back into JavaScript.
     * @return              A PluginResult object with a status and message.
     */
    PluginResult execute(String action, JSONArray args, String callbackId);

        // ... more ...
}

プラグインの作成を開始する最良の方法は、最初にjavascriptAPIを作成することです。通常は、カスタムjavascriptクラスを作成することから始め、javascriptクラスの各メソッドで変数をマーシャリングし、Phonegap.exec()メソッドを使用して開発したプラグインを呼び出します。参照用のメソッドシグネチャは次のとおりです。

/* src/com/phonegap/api/PluginManager.java */
/**
 * Receives a request for execution and fulfills it by finding the appropriate
 * Java class and calling it's execute method.
 *
 * PluginManager.exec can be used either synchronously or async. In either case, a JSON encoded
 * string is returned that will indicate if any errors have occurred when trying to find
 * or execute the class denoted by the clazz argument.
 *
 * @param service       String containing the service to run
 * @param action        String containt the action that the class is supposed to perform. This is
 *                      passed to the plugin execute method and it is up to the plugin developer
 *                      how to deal with it.
 * @param callbackId    String containing the id of the callback that is execute in JavaScript if
 *                      this is an async plugin call.
 * @param args          An Array literal string containing any arguments needed in the
 *                      plugin execute method.
 * @param async         Boolean indicating whether the calling JavaScript code is expecting an
 *                      immediate return value. If true, either PhoneGap.callbackSuccess(...) or
 *                      PhoneGap.callbackError(...) is called once the plugin code has executed.
 *
 * @return              JSON encoded string with a response message and status.
 */
@SuppressWarnings("unchecked")
public String exec(final String service, final String action,
    final String callbackId, final String jsonArgs,
    final boolean async)

プラグインも登録する必要があります。これを行うには、カスタムjavascriptライブラリの下部に登録コードを追加します。

以下の例では、作成者はjavascript BarcodeScannerクラスを定義し、addConstructorメソッドを使用してそれを登録します。

addConstructorでは2つのステップが実行されます。

  1. javascriptでBarcodeScannerの新しいインスタンスを作成し、登録します。これは、javascriptでwindow.plugins.barcodeScannerとしてアクセスできます。

  2. カスタムプラグインクラスをサービス名で登録します。このサービス名は、PhoneGapがJavaプラグインクラスをインスタンス化し、そのクラスでexecute()メソッドを呼び出すことができるように、PhoneGap.execに最初の引数として渡されます。

サンプル登録コード:

PhoneGap.addConstructor(function() {
    /* The following registers an instance of BarcodeScanner in window.plugins.barcodeScanner */
    PhoneGap.addPlugin('barcodeScanner', new BarcodeScanner());

    /* The following associates a service name BarcodeScanner with a class com.beetight.barcodescanner.BarcodeScanner */
    /* The service name is the first argument passed into PhoneGap.exec */
    PluginManager.addService("BarcodeScanner","com.beetight.barcodescanner.BarcodeScanner");
});

このサンプルはどのバージョンのphonegap用ですか?2.0以下について話していると思います。正しい?
Anas Azeem 2013年

6

より単純な形式:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.init(); 
    super.appView.getSettings().setJavaScriptEnabled(true);
    super.appView.addJavascriptInterface(this, "MyCls");
    super.loadUrl("file:///android_asset/www/login.html");
}

5

上記のコードを使用してnullPointer例外が発生した場合は、最初にsuper.oncreate()を実行し、次にsuper..init()を実行します。

super.onCreate(savedInstanceState);
super.init();

私はここでこの解決策を見つけました:Phonegap Google Group

解決策を提供してくれた@ zorglub76に感謝します。


0

JavaScriptからネイティブへの通信は、AndroidネイティブコードのJavaScriptプロンプト関数をオーバーライドすることで実現され、渡されるメッセージはiOSで使用されるものとよく似ています。以前はWebView.addJavascriptInterfaceを使用してJavaオブジェクトをJavaScriptサンドボックスに直接追加していましたが、Android2.3で一部のデバイスがクラッシュしていました。ネイティブからJavaScriptを呼び出すには、現在WebView.loadUrl(” javascript:…”)を使用していますが、これにはいくつかの問題があるため、すぐに、長期間有効なXHR接続を介してローカルHTTPサーバーを呼び出すJavaメッセージキューのポーリングに移行します。

ここでの説明

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.