はじめに
こんにちは、Androidエンジニアの菅沼です。
ミラティブでは MediaProjection API を使用してリアルタイムに画面をキャプチャして配信を実現しています。
この MediaProjection API のスクリーンキャプチャの許可を求めるダイアログの仕様が 2024年3月にリリースされた Pixelシリーズ向けの Android 14 FeatureDrop (Android 14 QPR2) 以降から仕様変更がありました。
つまり Android 15 以降のみではなく Android 14 の途中のバージョンでも変化したという点に注意です。
公式のソースはこちらになります
android-developers.googleblog.com
今回はこちらの変更点について紹介したいと思います。
異なる点
以下はスクリーンキャプチャを開始する際の Android 14 と Android 14 QPR2 以降(Android 15 も同様)のスクリーンショットの比較です
通常のAndroid 14 | Android 14 QPR2以降 |
---|---|
Android 14 QPR2以降では配信先を選択できるようになり、デフォルトが「1つのアプリ」に変化しています。 「1つのアプリ」をタップすると以下のようにこれまでのデフォルトだった「画面全体」が表示されます。
以下が検証に使用したコードになります。
@Preview @Composable private fun RunScreenCaptureIntent() { val context = LocalContext.current val mediaProjectionManager = context.getSystemService(MediaProjectionManager::class.java) val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { _ -> } Button( onClick = { val intent = mediaProjectionManager.createScreenCaptureIntent() launcher.launch(intent) }) { Text(text = "Launch ScreenCaptureIntent!") } }
「1つのアプリ」を選択した状態でミラティブの配信を行うと、どのような結果になるか?
「1つのアプリ」を選択し Google カレンダーを選択後、配信すると以下のようになります。
配信側 | 視聴側 |
---|---|
その名の通り「1つのアプリ」のみの配信となるので、配信側ではエモモを表示しているにもかかわらず Google カレンダーが表示されてしまいます。
配信者が途中でミラティブの画面を表示したり他のアプリに切り替えて表示することはできません。
ミラティブでの対応
ミラティブではユーザーが誤って「1つのアプリ」を選択しないようにするため、デフォルトを「画面全体」に変更し、「1つのアプリ」を無効化する対応を行いました。
上記のコードにそのような対応を行うと以下のようになります。
@Preview @Composable private fun RunScreenCaptureIntent2() { val context = LocalContext.current val mediaProjectionManager = context.getSystemService(MediaProjectionManager::class.java) val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { _ -> } Button( onClick = { // 変更点はこの分岐です val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { mediaProjectionManager.createScreenCaptureIntent(MediaProjectionConfig.createConfigForDefaultDisplay()) } else { mediaProjectionManager.createScreenCaptureIntent() } launcher.launch(intent) }) { Text(text = "Launch ScreenCaptureIntent!") } }
実行直後 | 選択肢をタップしたとき |
---|---|
今度は「画面全体」がデフォルトになり、「1つのアプリ」が無効化されています。
変更内容は単純で API Level 34 以上だったら createScreenCaptureIntent にMediaProjectionConfig.createConfigForDefaultDisplay の結果を渡すようにしただけです。
まとめ
Android 14 QPR2 での Media Projection API の変更を紹介させていただきました。
メジャーバージョン以外でのUI変更で、気がつきにくい内容なので Media Projection API を使用するアプリを作成する際はご注意ください。
We are hiring!
ミラティブでは一緒に開発してくれるエンジニアを募集しています!