在Android WebView中点击链接时获取锚点标签的href值

12

我正在WebView中加载一个网页。网页中有一个链接,桌面端会下载文件,但在应用程序中,该链接应该显示一个Toast提示该链接已被禁用。

我不确定如何在链接被点击时获取锚标签的href值。

<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>

有人可以分享一些想法或任何示例代码,以解决此问题。

编辑:1

这是我目前正在做的事情:

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;
            }
        });
这种方法存在的问题是:当我点击链接时,会得到额外的网址。这个过程一直正常运行。但是,从下一次开始,在 webview 上无论我在哪里点击,都会返回相同的额外内容。所以,即使我在点击链接后点击图像,我也会在额外内容中得到相同的链接。不确定我是否做错了什么,或者这是否是正确的方法。
如果需要任何详细信息,请告诉我。
编辑: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);

    }

现在,我获得了上一个action_down事件中被点击的URL。如何获取当前URL?

编辑3(尝试使用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);

当链接被点击时,在logcat中输出:

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

这个答案 https://dev59.com/vWct5IYBdhLWcg3wV7-k#55299801 可能会有所帮助。 - Sp4Rx
2个回答

7
由于您正在使用 WebView,且链接不是 JavaScript,因此可以通过使用 WebViewClient 来轻松实现此功能,您可以使用它来监视您的 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
    }

} );

由于你的URL以 .mp3 结尾,有可能会将文件视为资源。你需要覆盖 WebViewClient 的 shouldInterceptRequest 方法来进行检查。

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

抱歉回复晚了。我一开始就尝试了这种方法。但是,当我点击链接时,shouldOverrideUrlLoading没有被调用。唯一能获取到URL的时间是当我在WebView上使用onTouchListener,就像我在问题的代码示例中提到的那样。 - Vamsi Challa
如果WebView客户端已正确设置在WebView上,则获取URL始终会导致调用该方法。如果是表单提交,情况就不同了,但您说过是锚链接。您是否同时使用了触摸监听器?因为当您取消事件时,这当然不起作用。 - Nick Cardoso
我更新了包含 WebViewClient 的问题,请看一下。我没有同时使用两者。首先,我尝试使用 WebViewClient,但是无法从 shouldOverrideUrlLoading 中获取 URL。因此,我正在尝试使用 onTouchListener。 - Vamsi Challa
私有静态最终字符串URL =“http://xx.xxx.com/wp-content/uploads/”; 我正在shouldOverrideUrlLoading中记录它。 @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; } - Vamsi Challa
不确定发生了什么,但是我得去处理其他事情了。感谢您的帮助。作为我的感激之情,我将授予您赏金奖励。 - Vamsi Challa
显示剩余5条评论

0
大部分的工作可以在网页端完成。您需要编写JavaScript来识别访问页面的设备(移动设备、桌面设备等),如果是移动设备,则使用JavaScript绑定技术调用本机Android代码以显示Toast消息。

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

你的HTML页面(此示例有一个按钮点击)

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接