Cómo obtener valor de retorno de javascript en webview de android?

Quiero obtener un valor de retorno de Javascript en Android. Puedo hacerlo con el iPhone, pero no puedo con Android. Utilicé loadUrl, pero devolvió void en lugar de un objeto. ¿Puede alguien ayudarme? Gracias.

Aquí hay un truco sobre cómo puede lograrlo:

Agregue este cliente a su WebView:

final class MyWebChromeClient extends WebChromeClient { @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { Log.d("LogTag", message); result.confirm(); return true; } } 

Ahora en su llamada javascript hacer:

 webView.loadUrl("javascript:alert(functionThatReturnsSomething)"); 

Ahora en la llamada onJsAlert "mensaje" contendrá el valor devuelto.

Lo mismo que Keith pero la respuesta más corta

 webView.addJavascriptInterface(this, "android"); webView.loadUrl("javascript:android.onData(functionThatReturnsSomething)"); 

E implementar la función

 @JavascriptInterface public void onData(String value) { //.. do something with the data } 

No olvide quitar el onData de la lista proguard (si ha habilitado proguard)

Use addJavascriptInterface() para agregar un objeto Java al entorno Javascript. Haga que su Javascript llame a un método en ese objeto Java para proporcionar su "valor de retorno".

Esto es lo que me ocurrió hoy. Es un thread-safe, razonablemente eficiente, y permite la ejecución de Javascript sincrónica desde Java para un WebView de Android .

Funciona en Android 2.2 o superior. (Requiere commons-lang porque necesito mis fragmentos de código pasados ​​a eval () como una cadena Javascript. Podrías eliminar esta dependencia envolviendo el código entre comillas, pero en function(){} )

Primero, agregue esto a su archivo Javascript:

 function evalJsForAndroid(evalJs_index, jsString) { var evalJs_result = ""; try { evalJs_result = ""+eval(jsString); } catch (e) { console.log(e); } androidInterface.processReturnValue(evalJs_index, evalJs_result); } 

A continuación, agrega esto a tu actividad de Android:

 private Handler handler = new Handler(); private final AtomicInteger evalJsIndex = new AtomicInteger(0); private final Map<Integer, String> jsReturnValues = new HashMap<Integer, String>(); private final Object jsReturnValueLock = new Object(); private WebView webView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); webView = (WebView) findViewById(R.id.webView); webView.addJavascriptInterface(new MyJavascriptInterface(this), "androidInterface"); } public String evalJs(final String js) { final int index = evalJsIndex.incrementAndGet(); handler.post(new Runnable() { public void run() { webView.loadUrl("javascript:evalJsForAndroid(" + index + ", " + "\"" + StringEscapeUtils.escapeEcmaScript(js) + "\")"); } }); return waitForJsReturnValue(index, 10000); } private String waitForJsReturnValue(int index, int waitMs) { long start = System.currentTimeMillis(); while (true) { long elapsed = System.currentTimeMillis() - start; if (elapsed > waitMs) break; synchronized (jsReturnValueLock) { String value = jsReturnValues.remove(index); if (value != null) return value; long toWait = waitMs - (System.currentTimeMillis() - start); if (toWait > 0) try { jsReturnValueLock.wait(toWait); } catch (InterruptedException e) { break; } else break; } } Log.e("MyActivity", "Giving up; waited " + (waitMs/1000) + "sec for return value " + index); return ""; } private void processJsReturnValue(int index, String value) { synchronized (jsReturnValueLock) { jsReturnValues.put(index, value); jsReturnValueLock.notifyAll(); } } private static class MyJavascriptInterface { private MyActivity activity; public MyJavascriptInterface(MyActivity activity) { this.activity = activity; } // this annotation is required in Jelly Bean and later: @JavascriptInterface public void processReturnValue(int index, String value) { activity.processJsReturnValue(index, value); } } 

La solución que @Felix Khazin sugirió obras, pero hay un punto clave que falta.

La llamada javascript debe hacerse después de cargar la página web en el WebView . Agregue este WebViewClient al WebView , junto con el WebChromeClient .

Ejemplo Completo:

 @Override public void onCreate(Bundle savedInstanceState) { ... WebView webView = (WebView) findViewById(R.id.web_view); webView.getSettings().setJavaScriptEnabled(true); webView.setWebViewClient(new MyWebViewClient()); webView.setWebChromeClient(new MyWebChromeClient()); webView.loadUrl("http://example.com"); } private class MyWebViewClient extends WebViewClient { @Override public void onPageFinished (WebView view, String url){ view.loadUrl("javascript:alert(functionThatReturnsSomething())"); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return false; } } private class MyWebChromeClient extends WebChromeClient { @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { Log.d("LogTag", message); result.confirm(); return true; } } 

En API 19+, la mejor manera de hacerlo es llamar a EvaluationJavascript en su WebView:

 webView.evaluateJavascript("foo.bar()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { // value is the result returned by the Javascript as JSON } }); 

Respuesta relacionada con más detalles: https://stackoverflow.com/a/20377857

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.