web-dev-qa-db-fra.com

Communication entre Android Java et Phonegap Javascript?

Je crois qu'il est possible d'appeler les méthodes Java à partir de (PhoneGap) Javascript.

Tout le monde sait comment faire ça ?? (Je sais comment le faire en changeant le code source de PhoneGap, mais j'éviterais cela)

80
zorglub76

Je l'ai finalement fait fonctionner.

  • Créez une classe avec les méthodes que vous souhaitez utiliser:

    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;
      }
    }
    
  • Dans votre activité principale, ajoutez une interface Javascript pour cette classe:

    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));
        }
    }
    
  • En Javascript, appelez window.MyCls méthodes:

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

Remarque:

Comme mentionné dans le commentaire, pour Android version 4.2 et supérieure, ajoutez @JavascriptInterface à la méthode à laquelle vous souhaitez accéder depuis votre page HTML. Référence .

125
zorglub76

addJavaScriptInterface(mc, "MyCls") sans Gap init() ed peut provoquer l'écrasement de l'application, vous feriez mieux d'ajouter super.init() avant 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));
   }
}
14
Karfield

PhoneGap a une API de plugin décente. Vous écririez le plugin dans Java en implémentant l'interface IPlugin. La plupart de la magie est dans la fonction 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 ...
}

La meilleure façon de commencer à écrire un plugin est d'écrire d'abord l'API javascript. Vous commencerez généralement par écrire une classe javascript personnalisée, et dans chaque méthode de la classe javascript, regroupez les variables et appelez le plugin que vous avez développé à l'aide de la méthode Phonegap.exec (). Voici la signature de méthode pour votre référence.

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

Vous devez également enregistrer le plugin. Pour ce faire, ajoutez le code d'enregistrement au bas de votre bibliothèque javascript personnalisée.

Dans l'exemple ci-dessous, l'auteur a défini une classe javascript BarcodeScanner et l'enregistre à l'aide de la méthode addConstructor.

Deux étapes sont effectuées dans l'addConstructor:

  1. Créez une nouvelle instance de BarcodeScanner en javascript et enregistrez-la. Ceci est accessible en javascript comme window.plugins.barcodeScanner

  2. Enregistre la classe Plugin personnalisée avec un nom de service. Ce nom de service est transmis comme premier argument à PhoneGap.exec afin que PhoneGap puisse instancier la classe de plug-in Java et y appeler la méthode execute ().

Exemple de code d'enregistrement:

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");
});
9
Chui Tey

une forme plus simple:

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

Si quelqu'un obtient l'exception nullPointer en utilisant le code ci-dessus, faites d'abord super.oncreate () puis super..init ()

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

J'ai trouvé cette solution ici: Phonegap Google Group

Merci beaucoup à @ zorglub76 pour la solution ....

5
Dhairya Vora

La communication de JavaScript vers le natif est obtenue en remplaçant la fonction d'invite JavaScript dans le code natif Android et le message transmis ressemble beaucoup à celui utilisé dans iOS. Auparavant, nous utilisions WebView.addJavascriptInterface pour ajouter Java objets directement au bac à sable JavaScript, mais cela provoquait le blocage de certains appareils avec Android 2.3. Pour appeler JavaScript depuis le natif, nous utilisons actuellement WebView.loadUrl (”javascript:…”) ​​mais cela a quelques problèmes, nous allons donc bientôt passer à l'interrogation d'une file d'attente de messages Java appelant un serveur HTTP local via un long- vécu connexion XHR.

Description d'ici

0
Bodil