In the browser, you can longClick on URLs. In my WebView, you cannot. How can I make it so you can?
6 Answers
I had this same problem.
Unfortunately, I could not find a way to make the standard browser menu options appear. You have to implement each one yourself. What I did was to register the WebView for context menus with activity.registerForContextMenu(webView)
. Then I subclassed the WebView and overrode this method:
@Override
protected void onCreateContextMenu(ContextMenu menu) {
super.onCreateContextMenu(menu);
HitTestResult result = getHitTestResult();
MenuItem.OnMenuItemClickListener handler = new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// do the menu action
return true;
}
};
if (result.getType() == HitTestResult.IMAGE_TYPE ||
result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
// Menu options for an image.
//set the header title to the image url
menu.setHeaderTitle(result.getExtra());
menu.add(0, ID_SAVEIMAGE, 0, "Save Image").setOnMenuItemClickListener(handler);
menu.add(0, ID_VIEWIMAGE, 0, "View Image").setOnMenuItemClickListener(handler);
} else if (result.getType() == HitTestResult.ANCHOR_TYPE ||
result.getType() == HitTestResult.SRC_ANCHOR_TYPE) {
// Menu options for a hyperlink.
//set the header title to the link url
menu.setHeaderTitle(result.getExtra());
menu.add(0, ID_SAVELINK, 0, "Save Link").setOnMenuItemClickListener(handler);
menu.add(0, ID_SHARELINK, 0, "Share Link").setOnMenuItemClickListener(handler);
}
}
If you want to do something other than a context menu, then use an OnLongClickListener
. However you want to intercept the long click event, the HitTestResult
is the key. That's what will allow you to figure out what the user clicked on and do something with it.
I haven't actually implemented "Save Link" myself, I just included it as an example here. But to do so you would have to do all the processing yourself; you'd have to make an HTTP GET request, receive the response, and then store it somewhere on the user's SD card. There is no way that I know of to directly invoke the Browser app's download activity. Your "Save Link" code will look something like this:
HitTestResult result = getHitTestResult();
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(result.getExtra());
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
URL url = new URL(result.getExtra());
//Grabs the file part of the URL string
String fileName = url.getFile();
//Make sure we are grabbing just the filename
int index = fileName.lastIndexOf("/");
if(index >= 0)
fileName = fileName.substring(index);
//Create a temporary file
File tempFile = new File(Environment.getExternalStorageDirectory(), fileName);
if(!tempFile.exists())
tempFile.createNewFile();
InputStream instream = entity.getContent();
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
//Read bytes into the buffer
ByteArrayBuffer buffer = new ByteArrayBuffer(50);
int current = 0;
while ((current = bufferedInputStream.read()) != -1) {
buffer.append((byte) current);
}
//Write the buffer to the file
FileOutputStream stream = new FileOutputStream(tempFile);
stream.write(buffer.toByteArray());
stream.close();
}

- 9,310
- 13
- 80
- 146

- 18,367
- 15
- 63
- 70
-
I can't test this code yet, because of where I am, but do you have to write the code for those menu options? e.g. Save Link? If so, how did you do it? – Aymon Fournier Aug 10 '10 at 17:17
-
Yeah... it's really unfortunate, but it's the only way I've been able to do it. I'll add some more details to my answer. – Neil Traft Aug 10 '10 at 18:28
-
The whole reason I decided to use a webView was because the website was checking referer and I could not spoof it with HttpClient. Is there any way to check the URL, and either open it with the web Browser, or create a context menu? – Aymon Fournier Aug 10 '10 at 19:00
-
EDIT I see that getExtra gets the URL. can I then send it to the browser from here if its not the type I want to handle with HttpClient? – Aymon Fournier Aug 10 '10 at 19:05
-
I don't know if you can create a menu on your own without having the Activity create it for you. But if you don't add any items to the menu, then it won't be shown, so in `onCreateContextMenu` you could look at the URL given by `hitResult.getExtra()` and decide at that point whether you want to create a menu item or launch the browser. – Neil Traft Aug 10 '10 at 19:19
-
This method seems to only work when hold-tapping images or links. Is there a way to open a menu even if you hold-tap text in a web page? – NoBugs Jul 18 '11 at 21:23
-
Hmm... it seems that to bring up a context menu for plain text you'd have to check for `HitTestResult.UNKNOWN_TYPE` ... but I don't know how you would then extract the text the user had clicked on. Sorry! – Neil Traft Jul 19 '11 at 04:03
-
This works great, though I found out it must be declared as
instead of – NoBugs Jul 23 '11 at 05:46in the layout xml, as described here: http://stackoverflow.com/questions/4731082/how-do-you-properly-write-and-use-a-view-subclass-in-android -
It's perfect, but when you long click on google search results links, A base64 string returned, not a URL. How to get URL from google search results? – Sajjad javadi Apr 27 '20 at 16:08
I would think you could use something like this:
WebView yourWebView;
yourWebView.setLongClickable(true);
yourWebView.setOnLongClickListener(...);
That should let you catch long clicks on the view. What you do after that... that's up to you!

- 14,737
- 1
- 21
- 29
-
1Can I see the standard Android menu? Can I pick and choose, and keep only Save Link? – Aymon Fournier Aug 10 '10 at 15:28
I'd enable Javascript in the webview. Then use onMouseDown() and onMouseUp() to determine the duration of the click.
You can create popup menus in Javascript too (not the standard menus, but your own).
Finally you can interact between Javascript and your Android/Java code.
Example of simple interaction between Javascript and an Android app.
http://code.google.com/p/apps-for-android/source/browse/trunk/Samples/WebViewDemo/assets/demo.html
Alternatively, you may want to launch real browser instead of using a WebView.
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://example.com"));
startActivity(intent);

- 1,779
- 12
- 19
-
Will I be able to see the standard android Menu using the Javascript method? – Aymon Fournier Aug 10 '10 at 15:28
-
Can I pick and choose, and keep only Save Link? Also, will this work when using a OvverideUrlLoading? – Aymon Fournier Aug 10 '10 at 15:29
-
I don't know a way to pop up standard browser menu (unless you do launch the actual browser) – LatinSuD Aug 12 '10 at 19:39
I just wanted to copy URL data on long click.
By taking reference from the accepted answer I wrote this.
registerForContextMenu(webView);
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
WebView webView = (WebView) v;
HitTestResult result = webView.getHitTestResult();
if (result != null) {
if (result.getType() == HitTestResult.SRC_ANCHOR_TYPE) {
String linkToCopy = result.getExtra();
copyToClipboard(linkToCopy, AppConstants.URL_TO_COPY);
}
}
}

- 2,841
- 3
- 24
- 43
Based on @peeyush answer with shorter code:
webView.setOnLongClickListener { view ->
val result = (view as WebView).hitTestResult
extra?.let { link ->
// do sth with link
}
true
}

- 4,986
- 2
- 29
- 52
I'm using the following code to detect longclicks on links:
webView.setLongClickable(true);
webView.setOnLongClickListener(view -> {
WebView.HitTestResult hitTestResult = ((WebView) view).getHitTestResult();
if (hitTestResult.getExtra() == null || !Patterns.WEB_URL.matcher(hitTestResult.getExtra()).matches()) {
return false;
}
String link = hitTestResult.getExtra();
// do whatever you want with the link
});

- 111
- 1
- 6