アプリケーションコンポーネントの連携は、容易にアプリの機能を拡充できる、優れた仕組みです。
このコンポーネントの連携でYouTube動画を再生する場合、インテントの解決に癖があり、少々難解です。
ですので、後々、困らないように、ここへまとめます。
※環境:Android Studio Meerkat | 2024.3.1 Patch 1
Kotlin 2.0.0
目次
動画の再生アプリ
YouTube動画を再生するアプリは2つあります。
どちらも、YouTubeサーバーへHTTPプロトコルを使ってアクセスすることに、変わりはありません。また、両者はアンドロイド端末にプリインストールされています。
※YouTubeはGoogleが開発元です。
※Web Browserの一つのChromeはGoogleが開発元です。
コンポーネントの連携
開発しているアプリへYouTube動画を再生する機能を組み込みたい場合は、コンポーネントの連携を使って、インストール済みのアプリ(前章で上げた2つのアプリ)」へ動画の再生を依頼してしまう方法が得策です。
※コンポーネントの連携については「アプリケーションコンポーネント(App component)」を参照
暗黙的な呼び出しを用いれば、依頼先のアプリ(パッケージ名やコンポーネント名)を知らなくても、動画の再生に適したアプリを選ぶことが可能です。
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)が必要になりました。
パッケージの公開設定とは
「パッケージの公開設定」とは、このアプリへ公開(利用可能)を許可するコンポーネントのフィルタです。
ホワイトリスト形式なので、設定がなければ全てを非公開にし、設定に一致したものを公開します。


このパッケージの公開設定を設ける意義について、ドキュメントは以下のように述べています。
※意義については「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アプリが選択されます。
Uri | WebBrowse (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の選択肢は無くなります。
関連記事: