Kommunikation zwischen Android Java und Phonegap Javascript?

81

Ich glaube, dass es möglich ist, Java-Methoden aus (PhoneGap) Javascript aufzurufen.

Weiß jemand wie man das macht ?? (Ich weiß, wie es geht, indem ich den Quellcode von PhoneGap ändere, aber das würde ich vermeiden.)

zorglub76
quelle

Antworten:

125

Ich habe es endlich geschafft.

  • Erstellen Sie eine Klasse mit Methoden, die Sie verwenden möchten:

    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;
      }
    }
  • Fügen Sie in Ihrer Hauptaktivität eine Javascript-Schnittstelle für diese Klasse hinzu:

    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));
        }
    }
  • Im Javascript-Aufruffenster.MyCls-Methoden:

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

Hinweis:

Fügen Sie, wie im Kommentar erwähnt, für Android Version 4.2 und höher @JavascriptInterfacedie Methode hinzu, auf die Sie über Ihre HTML-Seite zugreifen möchten. Referenz .

zorglub76
quelle
hmm, dieses Beispiel ist großartig, aber ich bekomme eine Nullzeiger-Ausnahme in appView, es scheint null zu sein. Wo initialisieren Sie das Objekt?
白 目
1
Hinzufügen von super.init (); wie @Karfield unten erwähnt hat die Nullpointer-Ausnahme für mich behoben.
Renato H.
8
Gut gemacht! Tipp: Wenn Sie umgekehrt kommunizieren möchten (von Java nach Javascript), verwenden Sie Folgendes: mGap.sendJavascript ("window.myJavascriptFunction ('some parameter');");
Aeldron
5
E / Web Console (2513): Nicht erfasster Typ Fehler: Objekt [Objekt Objekt] hat keine Methode 'sendEmail' in der Datei: ///android_asset/www/loginfile.js: 142 window.Mycls.sendEmail ("[email protected]") ); Fehler in dieser Zeile erhalten
Deepu Mandy
2
Ich habe diesen Code für Android 4.2.2 ausprobiert. Ich hatte ein ähnliches Problem wie Deepu, dh Uncaught TypeError: Object [object Object] hat keine Methode 'getTelephoneNumber' in der Datei: ///android_asset/www/app.js: 142. Nach einigem Debuggen stellte ich fest, dass Sie @JavascriptInterface hinzufügen müssen, um auf eine Methode zuzugreifen, auf die Sie in Javascript über den obigen Link
Akshay
14

addJavaScriptInterface(mc, "MyCls")Ohne Lücke init()kann die App beschädigt werden. Fügen Sie sie besser super.init()vorher hinzuaddJavascriptInterface()

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));
   }
}
Karfield
quelle
9

PhoneGap hat eine anständige Plugin-API. Sie würden das Plugin in Java schreiben, indem Sie die IPlugin-Schnittstelle implementieren. Der größte Teil der Magie steckt in der Funktion 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 ...
}

Der beste Weg, um mit dem Schreiben eines Plugins zu beginnen, besteht darin, zuerst die Javascript-API zu schreiben. Sie beginnen normalerweise mit dem Schreiben einer benutzerdefinierten Javascript-Klasse. In jeder Methode der Javascript-Klasse werden die Variablen gemarshallt und das Plugin aufgerufen, das Sie mit der Phonegap.exec () -Methode entwickelt haben. Hier ist die Methodensignatur als Referenz.

/* 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)

Sie müssen auch das Plugin registrieren. Dazu fügen Sie den Registrierungscode unten in Ihrer benutzerdefinierten Javascript-Bibliothek hinzu.

Im folgenden Beispiel hat der Autor eine Javascript-BarcodeScanner-Klasse definiert und mit der Methode addConstructor registriert.

Im addConstructor werden zwei Schritte ausgeführt:

  1. Erstellen Sie eine neue Instanz von BarcodeScanner in Javascript und registrieren Sie sie. Dies ist in Javascript als window.plugins.barcodeScanner zugänglich

  2. Registriert die benutzerdefinierte Plugin-Klasse mit einem Dienstnamen. Dieser Dienstname wird als erstes Argument an PhoneGap.exec übergeben, damit PhoneGap die Java-Plugin-Klasse instanziieren und die Methode execute () darauf aufrufen kann.

Beispielregistrierungscode:

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");
});
Chui Tey
quelle
Für welche Version von Phonegap ist dieses Beispiel gedacht? Ich denke, Sie sprechen unter 2.0. Richtig?
Anas Azeem
6

eine einfachere Form:

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");
}
Heladio Benicio
quelle
5

Wenn jemand mit dem obigen Code eine nullPointer-Ausnahme erhält, führen Sie zuerst super.oncreate () und dann super..init () aus.

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

Ich habe diese Lösung hier gefunden: Phonegap Google Group

Vielen Dank an @ zorglub76 für die Lösung ....

Dhairya Vora
quelle
0

Die Kommunikation von JavaScript zu Native wird durch Überschreiben der JavaScript-Eingabeaufforderungsfunktion im nativen Android-Code erreicht. Die übergebene Nachricht ähnelt der in iOS verwendeten. Früher haben wir WebView.addJavascriptInterface verwendet, um Java-Objekte direkt zur JavaScript-Sandbox hinzuzufügen. Dies führte jedoch dazu, dass einige Geräte mit Android 2.3 abstürzten. Um JavaScript von nativ aufzurufen, verwenden wir derzeit WebView.loadUrl (”javascript:…”), aber das hat einige Probleme, so dass wir bald eine Java-Nachrichtenwarteschlange abfragen, die einen lokalen HTTP-Server über eine langlebige XHR-Verbindung aufruft.

Beschreibung von hier

Bodil
quelle