12

Webビューのロングクリックをキャッチしてコンテキストメニューを表示しようとしています。(以下のコードを参照)画像をロングクリックすると、常にimage-URLが追加として取得されます(IMAGE_TYPEでリンクされていない画像の場合、およびSRC_IMAGE_ANCHOR_TYPEでリンクされた画像の場合)。しかし、ハイパーリンクのある画像のLink-URL(image-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;
            }
        });
4

5 に答える 5

22

上記の解決策はどれもAndroid4.2.2では機能しませんでした。そこで、デフォルトのAndroidWebブラウザのソースコードを調べました。私はこの正確な問題の解決策を抽出しました-画像リンクからリンク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) ...
        }
    };
于 2013-07-26T12:49:27.780 に答える
9

これは古い問題ですが、最近この問題に遭遇しました。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
    }
}

ここにいくつかの情報を投稿しました。

于 2019-03-22T12:39:17.620 に答える
6

WebViewのソースコードを確認しましたが、SRC_IMAGE_ANCHOR_TYPEで取得できる追加データは画像URIのみのようです。しかし、ここで怒ってはいけません。私はあなたのために迅速で汚い回避策を持っています:

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

ローエンドのAndroid2.1デバイスとハイエンドのAndroid4.0デバイスでコードを試しましたが、どちらも魅力のように機能します。

よろしく

Ziteng Chen

于 2012-08-29T10:10:23.803 に答える
1

ZitengChenソリューションはAndroid4.0(APIレベル15)まで機能しますが、何らかの理由でKeyEventのダウンとアップがAPIレベル16以降(Android 4.1以降のJELLY_BEAN)では機能しません。WebViewのloadUrlは起動しません。そのため、dispatchKeyEventをdispatchTouchEventに置き換える必要がありました。コードは次のとおりです。

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

おそらく、dispatchTouchEventsを起動した直後にnullになる低速のデバイスでmUrlを取得するには、(AsyncTaskを使用して)待機する必要があります。

それが役に立てば幸い。

于 2013-06-30T08:00:41.407 に答える
-1

この関数を呼び出す代わりに、この関数を呼び出してmyWebView.requestFocusNodeHref(msg);みてくださいmyWebView.requestImageRef(msg);

于 2014-10-02T20:58:34.570 に答える