Enable longClick in WebView

22,897

Solution 1

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();
}

Solution 2

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!

Solution 3

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);
        }
    }
}

Solution 4

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

http://code.google.com/p/apps-for-android/source/browse/trunk/Samples/WebViewDemo/src/com/google/android/webviewdemo/WebViewDemo.java


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);
Share:
22,897
Aymon Fournier
Author by

Aymon Fournier

I am an ENTP

Updated on April 26, 2021

Comments

  • Aymon Fournier
    Aymon Fournier about 3 years

    In the browser, you can longClick on URLs. In my WebView, you cannot. How can I make it so you can?