Komunikacja między Android Java i Phonegap Javascript?

81

Uważam, że możliwe jest wywołanie metod Java z (PhoneGap) Javascript.

Każdy wie, jak to zrobić? (Wiem, jak to zrobić, zmieniając kod źródłowy PhoneGap, ale unikałbym tego)

zorglub76
źródło

Odpowiedzi:

125

Wreszcie udało mi się.

  • Utwórz klasę z metodami, których chcesz użyć:

    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;
      }
    }
    
  • W swojej głównej aktywności dodaj interfejs Javascript dla tej klasy:

    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));
        }
    }
    
  • W wywołaniu JavaScript metody window.MyCls:

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

Uwaga:

Jak wspomniano w komentarzu, dla Androida w wersji 4.2 i nowszych dodaj @JavascriptInterfacedo metody, do której chcesz uzyskać dostęp ze swojej strony HTML. Odniesienie .

zorglub76
źródło
hmm, ten przykład jest świetny, ale otrzymuję wyjątek nullpointer w appView, wydaje się, że jest null. Gdzie inicjalizujesz przedmiot?
最 白 目
1
dodanie super.init (); jak @Karfield wspomniany poniżej, naprawił dla mnie wyjątek nullpointer.
Renato H.
8
Dobra robota! Wskazówka: jeśli chcesz komunikować się w drugą stronę (z Java do Javascript), użyj tego: mGap.sendJavascript ("window.myJavascriptFunction ('jakiś parametr');");
aeldron
5
E / Web Console (2513): Uncaught TypeError: Object [object Object] nie ma metody „sendEmail” w pliku: ///android_asset/www/loginfile.js: 142 window.Mycls.sendEmail („[email protected]” ); get Error na tej linii
Deepu Mandy,
2
Wypróbowałem ten kod dla Androida 4.2.2, napotkałem problem podobny do Deepu, tj. Uncaught TypeError: Object [object Object] nie ma metody „getTelephoneNumber” w pliku: ///android_asset/www/app.js: 142. Po pewnym debugowaniu stwierdziłem, że musisz dodać @JavascriptInterface, aby uzyskać dostęp do dowolnej metody, do której chcesz uzyskać dostęp w javascript na powyższym linku
Akshay
14

addJavaScriptInterface(mc, "MyCls")bez Luki init()może spowodować awarię aplikacji, lepiej dodaj super.init()wcześniejaddJavascriptInterface()

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
źródło
9

PhoneGap ma przyzwoity interfejs API wtyczek. Napisałbyś wtyczkę w Javie, implementując interfejs IPlugin. Większość magii tkwi w funkcji 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 ...
}

Najlepszym sposobem na rozpoczęcie pisania wtyczki jest najpierw napisanie API javascript. Zwykle zaczynasz od napisania niestandardowej klasy javascript, a w każdej metodzie klasy javascript zorganizujesz zmienne i wywołaj wtyczkę, którą opracowałeś za pomocą metody Phonegap.exec (). Oto podpis metody w celach informacyjnych.

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

Musisz także zarejestrować wtyczkę. Robisz to, dodając kod rejestracyjny na dole swojej niestandardowej biblioteki javascript.

W poniższym przykładzie autor zdefiniował klasę javascript BarcodeScanner i rejestruje ją za pomocą metody addConstructor.

W addConstructor wykonywane są dwa kroki:

  1. Utwórz nowe wystąpienie BarcodeScanner w javascript i zarejestruj je. Jest to dostępne w javascript jako window.plugins.barcodeScanner

  2. Rejestruje niestandardową klasę wtyczki z nazwą usługi. Ta nazwa usługi jest przekazywana jako pierwszy argument do PhoneGap.exec, dzięki czemu PhoneGap może utworzyć instancję klasy wtyczki java i wywołać na niej metodę execute ().

Przykładowy kod rejestracyjny:

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
źródło
Do jakiej wersji phonegap jest przeznaczony ten przykład? Myślę, że mówisz o poniżej 2.0. Dobrze?
Anas Azeem,
6

prostsza forma:

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
źródło
5

Jeśli ktoś otrzyma wyjątek nullPointer przy użyciu powyższego kodu, najpierw wykonaj super.oncreate (), a następnie super..init ()

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

Znalazłem to rozwiązanie tutaj: Phonegap Google Group

Wielkie dzięki dla @ zorglub76 za rozwiązanie ....

Dhairya Vora
źródło
0

Komunikację z JavaScript do natywnego uzyskuje się przez zastąpienie funkcji zachęty JavaScript w natywnym kodzie Androida, a przekazywana wiadomość jest podobna do tej używanej w iOS. Kiedyś używaliśmy WebView.addJavascriptInterface do dodawania obiektów Java bezpośrednio do piaskownicy JavaScript, ale to powodowało awarie niektórych urządzeń z Androidem 2.3. Aby wywołać JavaScript z natywnego, obecnie używamy WebView.loadUrl („javascript:…”), ale wiąże się to z pewnymi problemami, więc wkrótce przejdziemy do odpytywania kolejki wiadomości Java wywołującej lokalny serwer HTTP przez długotrwałe połączenie XHR.

Opis tutaj

Bodil
źródło