Creo que es posible llamar a métodos Java desde (PhoneGap) Javascript.
¿¿Alguien sabe cómo hacer eso?? (Sé cómo hacerlo cambiando el código fuente de PhoneGap, pero lo evitaría)
Finalmente lo hice funcionar.
Crea una clase con los métodos que quieras usar:
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;
}
}
En su actividad principal agregue una interfaz Javascript para esta clase:
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 la ventana de llamada de Javascript.MyCls métodos:
<script>
$(function(){
$("#phone").text("My telephone number is: " +
window.MyCls.getTelephoneNumber());
});
</script>
Nota:
Como se menciona en el comentario, para la versión 4.2 de Android y superior, agregue @JavascriptInterface
al método al que desea acceder desde su página HTML. Referencia .
addJavaScriptInterface(mc, "MyCls")
sin Gapinit()
ed puede causar el aplastamiento de la aplicación, será mejor que agreguesuper.init()
antesaddJavascriptInterface()
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)); } }
fuente
PhoneGap tiene una API de complemento decente. Escribiría el complemento en Java implementando la interfaz IPlugin. La mayor parte de la magia está en la función 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 mejor manera de comenzar a escribir un complemento es escribiendo primero la API de JavaScript. Normalmente, comenzaría escribiendo una clase javascript personalizada y, en cada método de la clase javascript, ordenaría las variables y llamaría al complemento que desarrolló utilizando el método Phonegap.exec (). Aquí está la firma del método para su referencia.
/* 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)
También debe registrar el complemento. Para ello, agregue el código de registro en la parte inferior de su biblioteca javascript personalizada.
En el siguiente ejemplo, el autor definió una clase de JavaScript BarcodeScanner y la registra utilizando el método addConstructor.
En addConstructor se llevan a cabo dos pasos:
Cree una nueva instancia de BarcodeScanner en javascript y regístrela. Esto es accesible en javascript como window.plugins.barcodeScanner
Registra la clase de complemento personalizada con un nombre de servicio. Este nombre de servicio se pasa como primer argumento a PhoneGap.exec para que PhoneGap pueda crear una instancia de la clase de complemento java y llamar al método execute () en ella.
Código de registro de muestra:
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"); });
fuente
una forma más 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"); }
fuente
Si alguien obtiene una excepción nullPointer usando el código anterior, primero haga super.oncreate () y luego super..init ()
super.onCreate(savedInstanceState); super.init();
Encontré esta solución aquí: Phonegap Google Group
Muchas gracias a @ zorglub76 por la solución ....
fuente
La comunicación de JavaScript a nativo se logra anulando la función de solicitud de JavaScript en el código nativo de Android y el mensaje que se transmite es muy parecido al que se usa en iOS. Solíamos usar WebView.addJavascriptInterface para agregar objetos Java directamente al sandbox de JavaScript, pero eso estaba causando que algunos dispositivos fallaran con Android 2.3. Para llamar a JavaScript desde el nativo, actualmente usamos WebView.loadUrl (”javascript:…”) pero eso tiene algunos problemas, por lo que pronto pasaremos a sondear una cola de mensajes Java que llama a un servidor HTTP local a través de una conexión XHR de larga duración.
Descripción por aquí
fuente