2010-10-15 21 views
14

Quiero una aplicación HTML/javascript, ejecutándose en un WebView para hacer llamadas AJAX que se manejan con el código Java.
Ideal sería simplemente interceptar la llamada (fácil, simplemente use shouldOverrideUrlLoading()) y 'devolver' algunos datos.
Sin embargo, no encuentro una forma de 'devolver' una respuesta al WebView, aparte de llamar a una función javascript usando loadUrl().
Esto no funcionará para mí, ya que la aplicación HTML/javascript es una aplicación adicional que no controlo. En lo que respecta a la aplicación HTML/javascript, solo hace una llamada AJAX y recibe algunos datos.Android: interceptar llamada AJAX de WebView

¿Alguna idea de esto?

+0

puede obtener una respuesta ajax después de enviar los datos del formulario? formulario visualización de página web en webview desde la url remota –

Respuesta

2

Al final usé el método descrito en la pregunta de todos modos;

Intercepté algunas solicitudes específicas como: foo://bar/get/1?callback=foobar, luego analicé el URL y llamé a una función de devolución de llamada javascript con los datos reales.
La función de devolución de llamada se define en la consulta de parte de la URL, por lo que en el ejemplo anterior sería: foobar();

llamado que la función era fácil, sólo tiene que utilizar: yourWebView.loadUrl("javascript:foobar('somedata')");

+0

Erik ¿puede explicar, cómo ha sobrecargadoURL para el manejo de solicitudes AJAX y también decirme cómo manejar la solicitud AJAX de Java ... tampoco sé el mecanismo de intercepción de llamadas ... im atrapado en el mismo problema ... Ayuda necesaria ... Gracias – jyotin

31

Buenas noticias todo el mundo: Con API nivel 11, pusieron el método shouldInterceptRequest en la clase WebViewClient. También activa solicitudes en la aplicación dentro de los activadores WebView. Puede modificarlo así:

@Override 
public WebResourceResponse shouldInterceptRequest(WebView view, String url) 
{ 
    if (magicallyMatch(url)) 
     return new WebResourceResponse("application/json", "utf-8", magicallyGetSomeInputStream()); 

    return null; 
} 

Desde el Android Reference: WebResourceResponse pública

shouldInterceptRequest (vista WebView, String url)

desde: Nivel API 11

Notificar la aplicación host de una solicitud de recursos y permiten aplicación para devolver los datos . Si el valor de retorno es nulo, el WebView continuará cargando el recurso como de costumbre. De lo contrario, se utilizará la respuesta de devolución y los datos. NOTA: Este método es llamado por el hilo de red , por lo que los clientes deben tener precaución al acceder a datos privados .

Parámetros

view El WebView que está solicitando el recurso.

url La URL bruta del recurso.

devoluciones

Un WebResourceResponse que contiene la información respuesta o nula si el WebView debe cargar el recurso sí.

También verifique WebResourceResponse.

Espero que esto ayude.

+0

Esto debe marcarse como la respuesta correcta. –

+1

¿No hay forma de hacerlo funcionar en teléfonos que no tienen 3.x? – NoBugs

+1

puede obtener una respuesta ajax después de enviar los datos del formulario? formulario de visualización de página web en webview desde la url remota –

10

Puede utilizar el JavascriptInterface para interceptar la llamadas AJAX junto con los métodos jQuery ajaxStart y ajaxComplete en siguiente manera:

// our JavascriptInterface 
public class AjaxHandler { 

    private static final String TAG = "AjaxHandler"; 
    private final Context context; 

    public AjaxHandler(Context context) { 
     this.context = context; 
    } 

    public void ajaxBegin() { 
     Log.w(TAG, "AJAX Begin"); 
     Toast.makeText(context, "AJAX Begin", Toast.LENGTH_SHORT).show(); 
    } 

    public void ajaxDone() { 
     Log.w(TAG, "AJAX Done"); 
     Toast.makeText(context, "AJAX Done", Toast.LENGTH_SHORT).show(); 
    } 
} 

Y aquí es cómo se utiliza el AjaxHandler en Activity:

public class MainActivity extends Activity { 

    private static final String TAG = "MainActivity"; 

    private WebView webView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.main); 

     // get web view 
     webView = (WebView) findViewById(R.id.web); 

     // configure web view 
     final WebSettings webSettings = webView.getSettings(); 
     webSettings.setBuiltInZoomControls(true); 
     webSettings.setJavaScriptEnabled(true); 

     webView.loadUrl("http://foo.com"); 

     // add javascript interface 
     webView.addJavascriptInterface(new AjaxHandler(this), "ajaxHandler"); 

     // override onPageFinished method of WebViewClient to handle AJAX calls 
     webView.setWebViewClient(new WebViewClient() { 

       @Override 
       public void onPageFinished(WebView view, String url) { 
        super.onPageFinished(view, url); 

        view.loadUrl("javascript:$(document).ajaxStart(function (event, request, settings) { " + 
          "ajaxHandler.ajaxBegin(); " + // Event called when an AJAX call begins 
          "});"); 
        view.loadUrl("javascript:$(document).ajaxComplete(function (event, request, settings) { " + 
          "ajaxHandler.ajaxDone(); " + // Event called when an AJAX call ends 
          "});"); 

      }); 
    } 
} 

La idea principal se toma desde here y se presentan algunos ajustes.
Aunque es un poco tarde para enviar una respuesta, ¡pero espero que esto ayude a otros también!

+0

Es una gran solución. Pero, ¿cómo puedo obtener los parámetros de solicitud en AjaxHandler del código js? –

+1

Gran solución, gracias. Además, solo quiero que sepas que ajaxStop podría ser mejor en este caso porque se dispara cuando el ajax realmente deja de cargarse. source: http://stackoverflow.com/a/4421115/706833 – iGoDa

+0

@ S1LENT WARRIOR Pongo el código tal como está, pero ¿cómo Toast not show –