简体   繁体   中英

Get href value from anchor tag in Android WebView when link is clicked

I am loading a webpage in WebView. There is a link in the webpage, which on desktop will download the file, but in the app the link should display a Toast saying the link is disabled for the app.

I am not sure how to get the value from href of the anchor tag, when the link is clicked.

<a class="btn btn-primary" download="http://xx.xxx.com/wp-content/uploads/2015/11/abc-27-15.mp3" href="http://xx.xxx.com/wp-content/uploads/2015/11/abc-27-15.mp3">
<i class="fa fa-download"></i> Download Audio</a>

Can someone share an idea or any sample code on how to do this.

EDIT:1

Here is what I am doing currently:

private static final String URL = "http://xx.xxx.com/wp-content/uploads/";

webView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                if (event.getAction() == MotionEvent.ACTION_DOWN) {

                    WebView.HitTestResult hr = ((WebView) v).getHitTestResult();
                    String extra = hr.getExtra();

                    if (extra != null && extra.startsWith(URL) && extra.endsWith(".mp3")) {
                        Log.d("WebviewActivity", "Extra: " + extra);
                        Log.d("WebviewActivity", "Contains URL");

                        return true;
                    } 
                }

                return false;
            }
        });

The problem with this approach is: When i click on the link, i get the url in extra. It works fine till here. But, from next time, no matter where i click on the webview, the same extra is being returned. So even if i click on an image after i click on the url, i get the same url in the extra. Not sure if i doing anything wrong. Or is this the correct approach.

Please let me know if you need any details.

EDIT:2

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) {
                Log.d(TAG, "URL: "+url);
            }
        }
    };



        webView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                if (event.getAction() == MotionEvent.ACTION_DOWN) {

                    WebView.HitTestResult hr = ((WebView) v).getHitTestResult();


                    if (hr.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) {

                        Message msg = mHandler.obtainMessage();
                        webView.requestFocusNodeHref(msg);
                    }


                }

                return false;
            }
        });



        webView.loadUrl(mUrl);

    }

Now, i get the URL that is clicked in the last action_down event. How to get the current URL?

EDIT 3 (Attempt with webviewclient:

 private class MyWebViewClient extends WebViewClient {

        private static final String URL = "xx.xxx.com/wp-content/uploads/";

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);

            if (!isFinishing())
                mProgressDialog.show();
        }

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

        @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);

            Toast.makeText(WebviewActivity.this,
                    "Please check your internet " + "connection and try again",
                    Toast.LENGTH_SHORT).show();
        }


        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {

            Log.d("xxx", "Url: " + url);

            if(url.contains(URL)) {
                Log.d("xxx", "Url Contains: " + URL);
                return true;
            }

            return false;
        }

    }


mMyWebViewClient = new MyWebViewClient();
        webView.setWebViewClient(mMyWebViewClient);

Output in logcat when the link is clicked:

03-01 15:38:19.402 19626-19626/com.xx.xxx D/cr_Ime: [ImeAdapter.java:553] focusedNodeChanged: isEditable [false]
03-01 15:38:19.428 19626-19626/com.xx.xxx D/cr_Ime: [ImeAdapter.java:253] updateKeyboardVisibility: type [0->0], flags [0], show [true], 
03-01 15:38:19.428 19626-19626/com.xx.xxx D/cr_Ime: [ImeAdapter.java:326] hideKeyboard
03-01 15:38:19.429 19626-19626/com.xx.xxx D/cr_Ime: [InputMethodManagerWrapper.java:56] isActive: true
03-01 15:38:19.429 19626-19626/com.xx.xxx D/cr_Ime: [InputMethodManagerWrapper.java:65] hideSoftInputFromWindow

Because you are using a WebView and the link is not Java script this is very easy to achieve with a WebViewClient which you can use to monitor your WebView

myWebView.setWebViewClient( new WebViewClient() {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // check something unique to the urls you want to block
        if (url.contains("xx.xxx.com")) {
            Toast.make... //trigger the toast
            return true; //with return true, the webview wont try rendering the url
        }
        return false; //let other links work normally
    }

} );

It's possible that because your URL ends in .mp3 the file is being treated as a resource. You should also override the shouldInterceptRequest method of the WebViewClient to check this.

@Override
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { 
    String url = request.getUrl().toString();
    Log.d("XXX", "Url from API21 shouldInterceptRequest : " + url);
    if (url.contains(URL)) { 
        return new WebResourceResponse("text/html", "UTF-8", "<html><body>No downloading from app</body></html>");
    } else {
        return null;
    }
}

public WebResourceResponse shouldInterceptRequest (WebView view, String url) {
    Log.d("XXX", "Url from shouldInterceptRequest : " + url);
    if (url.contains(URL)) { 
        return new WebResourceResponse("text/html", "UTF-8", "<html><body>No downloading from app</body></html>");
    } else {
        return null;
    }
}

Most of the work can be done at the web page side itself. You have to write java script to identify which device is accessing the page (mobile, desktop etc) if its mobile then use java script binding technique to call the native android code to show Toast message.

http://developer.android.com/guide/webapps/webview.html

WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");

WebAppInterface.java

public class WebAppInterface {
    Context mContext;

    /** Instantiate the interface and set the context */
    WebAppInterface(Context c) {
        mContext = c;
    }

    /** Show a toast from the web page */
    @JavascriptInterface
    public void showToast(String toast) {
         Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }
}

YourHTML Page (this sample got a button click)

<input type="button" value="Say hello" onClick="showAndroidToast('Hello  
             Android!')" />

    <script type="text/javascript">
    function showAndroidToast(toast) {
         Android.showToast(toast);
    }
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM