startActivityでYouTube動画を再生

投稿日:  更新日:

アプリケーションコンポーネントの連携は、容易にアプリの機能を拡充できる、優れた仕組みです。

このコンポーネントの連携でYouTube動画を再生する場合、インテントの解決に癖があり、少々難解です。

ですので、後々、困らないように、ここへまとめます。

※環境:Android Studio Meerkat | 2024.3.1 Patch 1
    Kotlin 2.0.0

スポンサーリンク

動画の再生アプリ

YouTube動画を再生するアプリは2つあります。

YouTube動画の再生アプリ

どちらも、YouTubeサーバーへHTTPプロトコルを使ってアクセスすることに、変わりはありません。また、両者はアンドロイド端末にプリインストールされています。

※YouTubeはGoogleが開発元です。
※Web Browserの一つのChromeはGoogleが開発元です。

スポンサーリンク

コンポーネントの連携

開発しているアプリへYouTube動画を再生する機能を組み込みたい場合は、コンポーネントの連携を使って、インストール済みのアプリ(前章で上げた2つのアプリ)」へ動画の再生を依頼してしまう方法が得策です。
※コンポーネントの連携については「アプリケーションコンポーネント(App component)」を参照

アプリにYouTube動画を再生する機能を組み込み

暗黙的な呼び出しを用いれば、依頼先のアプリ(パッケージ名やコンポーネント名)を知らなくても、動画の再生に適したアプリを選ぶことが可能です。

startActivityはコンポーネントの連携で、依頼先のアプリ(コンポーネント)を呼び出すために使われます。

スポンサーリンク

動画の再生プログラム

startActivityでYouTube動画を再生するプログラムは、次のようになります。

解説は後述します。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />

    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" android:host="www.youtube.com" />
        </intent>
    </queries>

    <application>
	   ...
	</application>
</manifest>
    fun playVideo(uri: Uri) {
        val _intent = Intent(Intent.ACTION_VIEW).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK
            data = uri
        }
        if(_intent.resolveActivity(packageManager) != null) {
            startActivity(_intent)
        }
        else {
            /* コンポーネントが見つからなかった時の処理 */
        }
    }
                            val _url = "https://www.youtube.com/watch?v=sYGKUtM2ga8"
                            val _uri = Uri.parse(_url)
                            playVideo(_uri)
スポンサーリンク

解説1:パッケージの公開設定(API≧30)

API≧30よりパッケージの公開設定(Package Visibility)が必要になりました。

パッケージの公開設定とは

「パッケージの公開設定」とは、このアプリへ公開(利用可能)を許可するコンポーネントのフィルタです。

ホワイトリスト形式なので、設定がなければ全てを非公開にし、設定に一致したものを公開します。

API≧30API<30
インテントの解決(API≧30、パッケージの公開設定あり)
インテントの解決(API<30、パッケージの公開設定なし)

このパッケージの公開設定を設ける意義について、ドキュメントは以下のように述べています。
※意義については「Android でのパッケージの公開設定のフィルタリング」を参照

  • (1)必要のない(機密)情報へアクセスしてしまう可能性を最小限に抑える
  • (2)インストール済みアプリの一覧を隠蔽する
  •  ※アプリの一覧は「ユーザーの個人情報および機密情報」とみなされている

ただし、コンポーネントを使う側(依頼する側)の設定であるため、アプリのユーザに対して「アプリのプライバシーとセキュリティの状態」をアピールする(評価してもらう)程度の役割だと思います。

ちなみに、API<30においては、すべてのコンポーネントが公開になります。

スポンサーリンク

YouTube動画を再生する公開設定

公開設定はマニフェストファイル(AndroidManifest.xml)へ<queries>~</queries>で記述します。
※公開設定の書き方は「パッケージの公開設定の必要性を宣言する」を参照

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />

    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" android:host="www.youtube.com" />
        </intent>
    </queries>

    <application>
	   ...
	</application>
</manifest>

YouTube動画を再生する場合は「android:host=”www.youtube.com”」を必ず記述して下さい。無いと、目的のコンポーネントが公開されません。

また、ネットアクセスするので、「android.permission.INTERNET」が必要です。

スポンサーリンク

解説2:コンポーネントの有無を確認

インテントの解決で目的のコンポーネントが見つからなかった場合、そのままstartActivityを実行すると、Exceptionを発行して、アプリが停止してしまいます。

ですので、startActivityを実行する前にresolveActivityを使って、目的のコンポーネントの有無を確認します。

    fun playVideo(uri: Uri) {
        val _intent = Intent(Intent.ACTION_VIEW).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK
            data = uri
        }
        if(_intent.resolveActivity(packageManager) != null) {
            startActivity(_intent)
        }
        else {
            /* コンポーネントが見つからなかった時の処理 */
        }
    }
スポンサーリンク

解説3:YouTube動画を再生するアプリのUri

Intent#dataへ設定するUriが、インテントの解決における「YouTube動画を再生するアプリの条件」になります。

Uriは「https://www.youtube.com/watch?v=ビデオのID」を指定します。

                            val _url = "https://www.youtube.com/watch?v=sYGKUtM2ga8"
                            val _uri = Uri.parse(_url)
                            playVideo(_uri)

このUriは、表のようにWeb BrowserとYouTubeアプリにマッチしますが、アプリチューザーは開かれません。YouTubeアプリが優先されます。つまり、インテントの解決でYouTubeアプリが選択されます。

UriWebBrowse
(Chrome)
YouTubeアプリ
https://www.youtube.com/watch?v=ビデオのID○(優先)
vnd.youtube:ビデオのID×
○:インテントの解決で選択される
×:インテントの解決で選択されない

ちなみに、YouTubeアプリが無い(アンインストールした、無効にした)Android端末は、インテントの解決でWeb Browserが選択されます。

スポンサーリンク

Appendix:YouTubeアプリを指定するUri

YouTubeアプリを指定するUri(「vnd.youtube:ビデオのID」)があります。

このUriを使っても、YouTube動画を再生することが可能です。

                            val _url = "https://www.youtube.com/watch?v=sYGKUtM2ga8"
                            val _uri = Uri.parse(_url)
                            playVideo(Uri.parse("vnd.youtube:" + _uri.getQueryParameter("v")))

ただし、「YouTubeアプリが無ければ、Web Browserで再生する」という、第2の選択肢は無くなります。

スポンサーリンク

関連記事:

アプリを構成する最上位の構成要素がアプリケーションコンポーネント(App component)です。 アプリケーションコンポーネントの概要をまとめます。 ...
「インテントの解決」はシステム内でアプリケーションコンポーネントを選択する処理のことです。 この選択する処理の流れが複雑で、ちょっと癖がありあます。 ここでは「インテントの解決」の処理の流れについてまとめます。 ...
アプリを構成する最上位の構成要素がアプリケーションコンポーネント(App component)です。 Activityはアプリケーションコンポーネントの1つです。アプリケーションの画面と処理を構築します。 Activityについてまとめます。 ...
アプリを構成する最上位の構成要素がアプリケーションコンポーネント(App component)です。 Content Providerはアプリケーションコンポーネントの1つです。アプリケーションが管理するデータを公開(共有)します。 Content Providerについてまとめます。 ...
スポンサーリンク