android - example - Interceptar y anular las solicitudes HTTP de WebView
webview evaluatejavascript (7)
Aquí está mi solución que uso para mi aplicación.
Tengo varias carpetas de activos con archivos de fuentes css / js / img anf.
La aplicación obtiene todos los nombres de archivo y busca si se solicita un archivo con este nombre. En caso afirmativo, lo carga desde la carpeta de activos.
//get list of files of specific asset folder
private ArrayList listAssetFiles(String path) {
List myArrayList = new ArrayList();
String [] list;
try {
list = getAssets().list(path);
for(String f1 : list){
myArrayList.add(f1);
}
} catch (IOException e) {
e.printStackTrace();
}
return (ArrayList) myArrayList;
}
//get mime type by url
public String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
if (extension.equals("js")) {
return "text/javascript";
}
else if (extension.equals("woff")) {
return "application/font-woff";
}
else if (extension.equals("woff2")) {
return "application/font-woff2";
}
else if (extension.equals("ttf")) {
return "application/x-font-ttf";
}
else if (extension.equals("eot")) {
return "application/vnd.ms-fontobject";
}
else if (extension.equals("svg")) {
return "image/svg+xml";
}
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
//return webresourceresponse
public WebResourceResponse loadFilesFromAssetFolder (String folder, String url) {
List myArrayList = listAssetFiles(folder);
for (Object str : myArrayList) {
if (url.contains((CharSequence) str)) {
try {
Log.i(TAG2, "File:" + str);
Log.i(TAG2, "MIME:" + getMimeType(url));
return new WebResourceResponse(getMimeType(url), "UTF-8", getAssets().open(String.valueOf(folder+"/" + str)));
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
//@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@SuppressLint("NewApi")
@Override
public WebResourceResponse shouldInterceptRequest(final WebView view, String url) {
//Log.i(TAG2, "SHOULD OVERRIDE INIT");
//String url = webResourceRequest.getUrl().toString();
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
//I have some folders for files with the same extension
if (extension.equals("css") || extension.equals("js") || extension.equals("img")) {
return loadFilesFromAssetFolder(extension, url);
}
//more possible extensions for font folder
if (extension.equals("woff") || extension.equals("woff2") || extension.equals("ttf") || extension.equals("svg") || extension.equals("eot")) {
return loadFilesFromAssetFolder("font", url);
}
return null;
}
Tengo una WebView en mi aplicación en la que se abre un sitio (siempre igual, es mi propia página). El sitio tiene un código JS que carga algunas imágenes desde el host remoto.
Quiero interceptar solicitudes a tales imágenes (por patrón de URL) y devolver mi propio contenido (es decir, otra imagen), o dejar la solicitud intacta dependiendo de la lógica interna de la aplicación.
¿Es posible hacer eso?
EDITAR : El estado actual de la pregunta ...
WebView
tiene la capacidad de establecer un WebViewClient
(como lo señala Axarydax). WebViewClient
tiene dos métodos útiles
-
shouldOverrideUrlLoading
-
onLoadResource
shouldOverrideUrlLoading
puede interceptar cualquier carga de url, si la carga se desencadena por la interacción de la página (es decir, se hace clic en el enlace de una página, WebView.loadURL ("") no activa este método). También puede cancelar la carga de URL al devolver falso. Este enfoque no es utilizable, porque ''no es capaz de interceptar la carga de los recursos de la página (y las imágenes, lo que necesito interceptar, es un recurso de esa página).
onLoadResource
se activa cada vez que se carga el recurso de la página (y las imágenes! thx a jessyjones), pero no hay forma de cancelarlo. Eso hace que este método no sea adecuado para mi tarea también.
Esto puede ayudar:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
WebResourceResponse response = super.shouldInterceptRequest(view, request);
// load native js
if (url != null && url.contains(INJECTION_TOKEN/* scheme define */)) {
response = new WebResourceResponse(
"text/javascript",
"utf-8",
loadJsInputStream(url, JsCache.getJsFilePath(path) /* InputStream */));
}
return response;
}
No mencionas la versión API, pero desde la API 11 está el método WebViewClient.shouldInterceptRequest
Tal vez esto podría ayudar?
Parece que el nivel 11 de API tiene soporte para lo que necesita. Ver WebViewClient.shouldInterceptRequest()
.
Por lo que sé, shouldOverrideUrlLoading no se llama para imágenes sino para hipervínculos ... Creo que el método apropiado es
@Override public void onLoadResource(WebView view, String url)
Este método se utiliza para cada recurso (imagen, hoja de estilo, secuencia de comandos) que carga la vista web, pero dado que es un vacío, no he encontrado una forma de cambiar esa url y reemplazarla para que cargue un recurso local ...
Prueba esto, lo he usado en una aplicación personal tipo wiki:
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("foo://")) {
// magic
return true;
}
return false;
}
});
Una solución definitiva sería incorporar un servidor http simple escuchando en su puerto ''secreto'' en loopback. Luego puede sustituir la URL src de la imagen coincidente con algo como http://localhost:123/.../mypic.jpg