ejemplo - Cómo obtener un enlace URL en Android WebView con HitTestResult para una imagen vinculada(y no la imagen-URL) con Longclick
webview android studio 2018 (4)
Intento capturar longclicks de webview para mostrar un menú contextual. (Consulte el código a continuación) Cuando hace clic largo en una imagen, siempre obtengo la imagen URL como extra (para una imagen no vinculada con IMAGE_TYPE y para una imagen vinculada con SRC_IMAGE_ANCHOR_TYPE). ¿Pero cómo puedo obtener el Link-URL (y no el image-URL) para una imagen con un hipervínculo?
Mejor, Sebastian
mywebview.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v) {
final WebView webview = (WebView) v;
final WebView.HitTestResult result = webview.getHitTestResult();
if (result.getType() == SRC_ANCHOR_TYPE) {
return true;
}
if (result.getType() == SRC_IMAGE_ANCHOR_TYPE) {
return true;
}
if (result.getType() == IMAGE_TYPE) {
return true;
}
return false;
}
});
Comprobé el código fuente de WebView y parece que la uri de la imagen es la única información adicional que puede obtener para SRC_IMAGE_ANCHOR_TYPE. Pero no te enojes aquí. Tengo una solución rápida y sucia para ti:
webview.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
final WebView webview = (WebView) v;
final HitTestResult result = webview.getHitTestResult();
if(result.getType()==HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
webview.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 2. and here we get the url (remember to remove the WebView client and return true so that the hyperlink will not be really triggered)
mUrl = url; // mUrl is a member variant of the activity
view.setWebViewClient(null);
return true;
}
});
// 1. the picture must be focused, so we simulate a DPAD enter event to trigger the hyperlink
KeyEvent event1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
webview.dispatchKeyEvent(event1);
KeyEvent event2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER);
webview.dispatchKeyEvent(event2);
// 3. now you can do something with the anchor url (and then clear the mUrl for future usage)
String url = mUrl;
if (url!=null) {
Toast.makeText(webview.getContext(), url, Toast.LENGTH_SHORT).show();
}
mUrl = null;
}
return false;
}
});
Probé el código en un dispositivo Android 2.1 de gama baja y un dispositivo Android 4.0 de alta gama, ambos funcionan como un encanto.
Saludos
Ziteng Chen
En lugar de llamar a esta función myWebView.requestFocusNodeHref(msg);
, intente llamar a esta función myWebView.requestImageRef(msg);
La solución de Ziteng Chen funciona con Android 4.0 (API de nivel 15) pero, por alguna razón, KeyEvent down & up no funciona en API LEVEL 16+ (Android 4.1+ JELLY_BEAN). No dispara el loadUrl de WebView. Así que tuve que reemplazar el dispatchKeyEvent con dispatchTouchEvent. Aquí está el código:
...
MotionEvent touchDown = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, touchX, touchY, 0);
webView.dispatchTouchEvent(touchDown);
touchDown.recycle();
MotionEvent touchUp = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, touchX, touchY, 0);
webView.dispatchTouchEvent(touchUp);
touchUp.recycle();
String url = mUrl;
...
Probablemente tendrías que esperar (usar un AsyncTask) para obtener el mUrl en dispositivos más lentos donde es nulo inmediatamente después de disparar el dispatchTouchEvents
Espero eso ayude.
Ninguna de las soluciones anteriores funcionó para mí en Android 4.2.2. Así que busqué en el código fuente del navegador web android predeterminado. Extraje la solución a este problema exacto: obtener el enlace URL desde el enlace de la imagen.
Solución extraída:
Oyente LongClick:
...
mWebview.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
HitTestResult result = mWebview.getHitTestResult();
if (result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
Message msg = mHandler.obtainMessage();
mWebview.requestFocusNodeHref(msg);
}
}
});
...
Manejador para obtener la URL:
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// Get link-URL.
String url = (String) msg.getData().get("url");
// Do something with it.
if (url != null) ...
}
};