今回はリンク先のページ情報(タイトル、詳細、サムネイル)を取得する話。
はじめに
musicLineではコミュニティでユーザー同士が会話するためのチャット機能があります。以前までそのチャットにYouTubeのURLを載せるとアプリ内で動画を再生できるように実装していましたが、そのライブラリのサポートが終了して機能しなくなりました。
今後はWeb技術のiFrame
を使うことでYouTubeの埋め込みを実現する方法もあるようですが、これを機会にURLをコメントに送信したときの挙動を再検討しました。
そもそも今まではYouTube以外のURLを送っても、リンク先ページの情報がわからなく、URLテキストのみを表示する仕様になってました。
しかし、この仕様ではリンク先のページに飛ばないと内容がわからなく、会話の中でリンク先を送ることに躊躇してしまうことがあると思います。
そこでYouTubeに限らずURLをコメントで送ることで、リンク先ページの情報を取得して、表示できるように改良しました。
ページ情報の取得
OGP (Open Graph Protcol)
WebページはHTMLで書かれていますが、特にリンクをシェアした時に使用してほしい文書や画像はOGP (Open Graph Protcol)に基づいて設定されます。
具体的には、Webから以下のようなHTMLドキュメントを取得するので、og
メタタグの要素を確認すると情報を取得できます。
<!DOCTYPE html> <html lang="ja"> <head> <meta property="og:title" content="タイトル" /> <meta property="og:image" content="画像のURL" /> <meta property="og:description" content="ページの説明" /> ... </head> <body> ... </body> </html>
プロパティ | 内容 |
---|---|
og:title | タイトル |
og:image | 画像のURL |
og:description | ページの説明 |
実装
下記のページを元にAndroid+Kotlinでリンク先のページ情報を取得するように実装しました。
基本的にはJsoupライブラリでHTMLのURLを指定するだけで、要素の内容を取得できます。
val doc = Jsoup.connect(url).get() val headEls = doc.head().children() for (v in headEls) { val prop = v.attr("property") val content = v.attr("content") println("プロパティ:$prop、内容:$content") }
ただ、メインスレッドでJsoup.connect(url)
にてWebからHTMLをダウンロードすると例外が発生するため、ダウンロードする際はサブスレッドで行います。
ViewModelで処理を行っている場合は、viewModelScope
を使用するといいでしょう。
viewModelScope.launch(Dispatchers.Main) { // サブスレッドでHTMLを取得 val doc = withContext(Dispatchers.IO) { try { Jsoup.connect(url).get() } catch (e: IOException) { e.printStackTrace() null } } ... }
全コードを表示
viewModelScope.launch(Dispatchers.Main) { // サブスレッドでHTMLを取得 val doc = withContext(Dispatchers.IO) { try { Jsoup.connect(url).get() } catch (e: IOException) { e.printStackTrace() null } } doc?.let { val headEls = it.head().children() for (v in headEls) { val prop = v.attr("property") val content = v.attr("content") when (prop) { "og:title" -> { // Webページのタイトル } "og:description" -> { // Webページの説明 } "og:image" -> { // WebページのサムネイルURL } } } } }
おわりに
今回の実装でリンク先のイメージや詳細がわかるようになりました。
ちなみにYouTubeやニコニコのURLは検出して、再生マークを付けてます。
YouTubeのアプリ内再生は非対応となりましたが、タップでYouTubeに飛べるため、アプリ内で再生しなくても良いかと思います。