WebViewで画像リンクを長押ししたときにもリンク先URLを取得する方法
hitTestResultを使用するだけだと画像URLしか得られないので、ひと手間必要というお話
Created at

645 Words
⚠️

前提

AndroidのWebViewでは、次のようにして表示しているページのリンク部分や画像を長押ししたときの処理を任意に設定できる。

webView.setOnLongClickListner {
    val hitTestResult = webView.hitTestResult
    when (hitTestResult.type) {
        WebView.HitTestResult.SRC_ANCHOR_TYPE -> {
            // リンクテキストの場合
            val linkUrl: String? = hitTestResult.extra
        }

        WebView.HitTestResult.IMAGE_TYPE -> {
            // 画像の場合
            val imageUrl: String? = hitTestResult.extra
        }

        WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE -> {
            // 画像リンクの場合
            val imageUrl: String? = hitTestResult.extra
        }
    }
}

上記コードにおいて、変数linkUrlは「リンク先のURL」、imageUrlは「長押しした対象画像のURL」を指す。
ここでは値がnullableであることを明示するため、一応変数型を明記している。

「リンクテキストの場合」「画像の場合」はとくに問題なく自然な感じにURLが扱えるのだが、「画像リンクの場合」はhitTestResultから得られる情報だけではリンク先URLが得られない。

画像リンクのリンク先アドレスを取得する

そこで、次のようにしてフォーカスしているリンクの部分の情報を得ることができるので、これを使ってリンク先URLを取得する。

webView.setOnLongClickListner {
    val hitTestResult = webView.hitTestResult
    when (hitTestResult.type) {
        // 他省略

        WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE -> {
            // 画像リンクの場合
            val message = Handler().obtainMessage()
            webView.requestFocusNodeHref(message)

            val linkUrl: String? = message.data.getString("url")

            // hitTestResultから得ればいいが一応
            val imageUrl: String? = message.data.getString("src")
        }
    }
}

これでリンク先URL、画像URL両方が取得できた。

余談

ちなみに、上記コード中のmessage.dataからはここでは次の三つの情報が得られる。

// リンク先URL
message.data.getString("url")

// 画像URL(画像リンクの場合。リンクテキストではnullになる)
message.data.getString("src")

// リンク部分の文字列(リンクテキストの場合。画像リンクではnullになる)
message.data.getString("title")

参考

How to get link-URL in Android WebView with HitTestResult for a linked image (and not the image-URL) with Longclick - Stack Overflow

See Also