【问题标题】:How to get link-URL in Android WebView with HitTestResult for a linked image (and not the image-URL) with Longclick如何在 Android WebView 中使用 HitTestResult 获取链接 URL,用于使用 Longclick 链接图像(而不是图像 URL)
【发布时间】:2012-08-23 11:30:07
【问题描述】:

我尝试捕捉 webview 长按以显示上下文菜单。 (见下面的代码) 长按图像时,我总是获得额外的图像 URL(对于带有 IMAGE_TYPE 的未链接图像和带有 SRC_IMAGE_ANCHOR_TYPE 的链接图像)。 但是如何获取带有超链接的图像的链接 URL(而不是图像 URL)?

最好, 塞巴斯蒂安

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

【问题讨论】:

    标签: android image url webview webviewclient


    【解决方案1】:

    以上解决方案均不适用于 Android 4.2.2。所以我查看了默认 android web 浏览器的源代码。我为这个确切的问题提取了解决方案 - 从图像链接中获取链接 URL。

    来源: https://github.com/android/platform_packages_apps_browser/blob/master/src/com/android/browser/Controller.java

    提取的解决方案:

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

    获取 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) ...
            }
        };
    

    【讨论】:

    • 仅供参考,对于尝试此方法的 Android 4.4+ 用户,存在一个错误,即图像锚点的 HitTestResult 错误地返回 link-url = image-src。该错误在stackoverflow.com/q/20244661/1303595 中描述并在code.google.com/p/chromium/issues/detail?id=323989 中解决。
    • 这对我来说非常有效,唯一的问题是处理程序似乎每次都在链接后面,意思是,我选择一个,它将显示上一个链接。显示的第一个为空。
    【解决方案2】:

    我知道这是一个老问题,但我最近遇到了这个问题。根据Perry_ml 的回答,我使用下面的 Kotlin 代码来解决它:

    webView.setOnLongClickListener {
        val result = webView.hitTestResult
        if (result.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
            val handler = Handler()
            val message = handler.obtainMessage()
    
            webView.requestFocusNodeHref(message)
            val url = message.data.getString("url")
    
            // Do something with url, return true as touch has been handled
            true
        } else {
            false
        }
    }
    

    我发布了一些关于它的信息here

    【讨论】:

    • 感谢这个很棒的解决方案。如果type 不是SRC_IMAGE_ANCHOR_TYPE,请尝试签入hr.getExtra()
    • 在找到您的帖子(以及您的其他信息)之前,我在这个 fakakta“问题”上浪费了半天时间。非常感谢!
    【解决方案3】:

    我检查了 WebView 的源代码,似乎图像 uri 是您可以获得的 SRC_IMAGE_ANCHOR_TYPE 的唯一额外数据。但不要在这里生气,我有一个快速而肮脏的解决方法:

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

    我在低端 Android 2.1 设备和高端 Android 4.0 设备上尝试了该代码,两者都像魅力一样工作。

    问候

    陈子腾

    【讨论】:

      【解决方案4】:

      Ziteng Chen 解决方案适用于 Android 4.0(API 级别 15),但由于某种原因,KeyEvent down & up 在 API LEVEL 16+(Android 4.1+ JELLY_BEAN)中不起作用。它不会触发 WebView 的 loadUrl。所以我不得不用dispatchTouchEvent替换dispatchKeyEvent。代码如下:

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

      您可能必须等待(使用 AsyncTask)才能在较慢的设备中获取 mUrl,在触发 dispatchTouchEvents 后它立即为空

      希望对你有帮助。

      【讨论】:

        【解决方案5】:

        不要调用这个函数myWebView.requestFocusNodeHref(msg);,而是尝试调用这个函数myWebView.requestImageRef(msg);

        【讨论】:

          猜你喜欢
          • 2014-02-04
          • 2012-05-05
          • 2015-03-28
          • 2021-04-13
          • 2021-12-05
          • 2011-09-18
          • 1970-01-01
          • 1970-01-01
          • 2015-12-03
          相关资源
          最近更新 更多