Связь между Android Java и Phonegap Javascript?

81

Я считаю, что можно вызывать методы Java из (PhoneGap) Javascript.

Кто-нибудь знает, как это сделать ?? (Я знаю, как это сделать, изменив исходный код PhoneGap, но я бы этого не сделал)

zorglub76
источник

Ответы:

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 методы MyCls:

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

Заметка:

Как упоминалось в комментарии, для Android версии 4.2 и выше добавьте @JavascriptInterfaceметод, к которому вы хотите получить доступ со своей HTML-страницы. Ссылка .

zorglub76
источник
хм, этот пример отличный, но я получаю исключение с нулевым указателем в appView, кажется, оно пустое. Где вы инициализируете объект?
最 白 目
1
добавление super.init (); как @Karfield, упомянутый ниже, исправил для меня исключение nullpointer.
Renato H.
8
Прекрасная работа! Совет: если вы хотите общаться наоборот (с Java на Javascript), используйте это: mGap.sendJavascript ("window.myJavascriptFunction ('some parameter');");
элдрон
5
E / Web Console (2513): Uncaught TypeError: Object [object Object] не имеет метода sendEmail в файле: ///android_asset/www/loginfile.js: 142 window.Mycls.sendEmail ("rea@gmail.com" ); получить ошибку в этой строке
Deepu Mandy
2
Я пробовал этот код для Android 4.2.2, я столкнулся с проблемой, похожей на Deepu, т.е. Uncaught TypeError: Object [object Object] не имеет метода getTelephoneNumber в файле: ///android_asset/www/app.js: 142. После некоторой отладки я обнаружил, что вам нужно добавить @JavascriptInterface для доступа к любому методу, к которому вы хотите получить доступ в javascript по ссылке
Акшай
14

addJavaScriptInterface(mc, "MyCls")без Gap init()ed может привести к сбою приложения, вам лучше добавить 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 плагинов. Вы бы написали плагин на Java, реализовав интерфейс IPlugin. Большая часть волшебства заключается в функции 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 ...
}

Лучший способ начать писать плагин - это сначала написать javascript API. Обычно вы начинаете с написания собственного класса 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 выполняются два шага:

  1. Создайте новый экземпляр BarcodeScanner в javascript и зарегистрируйте его. Это доступно в javascript как window.plugins.barcodeScanner

  2. Регистрирует настраиваемый класс подключаемого модуля с именем службы. Это имя службы передается в качестве первого аргумента в PhoneGap.exec, чтобы PhoneGap мог создать экземпляр класса плагина Java и вызвать для него метод execute ().

Образец регистрационного кода:

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");
});
Чуй Тей
источник
Для какой версии телефонного разговора предназначен этот образец? Я думаю, вы говорите ниже 2.0. Правильно?
Анас Азим
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");
}
Heladio Benicio
источник
5

Если кто-то получает исключение nullPointer, используя приведенный выше код, сначала выполните super.oncreate (), а затем super..init ()

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

Я нашел это решение здесь: Phonegap Google Group

Большое спасибо @ zorglub76 за решение ....

Дхайрья Вора
источник
0

Связь между JavaScript и собственным кодом достигается путем переопределения функции подсказки JavaScript в собственном коде Android, а передаваемое сообщение очень похоже на используемое в iOS. Раньше мы использовали WebView.addJavascriptInterface для добавления объектов Java непосредственно в песочницу JavaScript, но это приводило к сбою некоторых устройств с Android 2.3. Для вызова JavaScript из нативного языка мы в настоящее время используем WebView.loadUrl («javascript:…»), но у него есть некоторые проблемы, поэтому мы скоро переходим к опросу очереди сообщений Java, вызывая локальный HTTP-сервер через долговременное соединение XHR.

Описание здесь

Бодил
источник