Android 14(API レベル 34)では、マルチタスクを可能にするために、ピクチャー イン ピクチャー(PIP)API の一部機能が強化されました。PIP のサポートは Android 8.0(API レベル 26)で導入されましたが、Android TV では幅広くサポートされておらず、Android 13 より前の Google TV ではまったくサポートされていませんでした。TV のマルチタスクでは、PIP モードを使用して、2 つの別々のアプリを画面上で同時に共存できます。1 つは全画面表示で実行され、もう 1 つは PIP モードで実行されます。これらのモードのいずれかで実行されるアプリには、それぞれ異なる要件があります。
デフォルトの動作では、PIP アプリが全画面表示アプリにオーバーレイされます。これは、標準の Android ピクチャー イン ピクチャーの動作とほぼ同じです。
マルチタスクを統合する際、アプリは TV アプリの品質に関するガイドラインに沿って使用タイプを宣言する必要があります。
PiP モードでアプリを実行する
Android 14(API レベル 34)以降を搭載しているテレビ デバイスでは、enterPictureInPictureMode()
を呼び出して PiP モードでアプリを実行します。以前のバージョンの Android を搭載した TV デバイスは、PIP モードをサポートしていません。
PIP モードに入るボタンのロジックを実装する方法の例を次に示します。
Kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) pictureInPictureButton.visibility = if (requireActivity().packageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { pictureInPictureButton.setOnClickListener { val aspectRatio = Rational(view.width, view.height) val params = PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .build() val result = requireActivity().enterPictureInPictureMode(params) } View.VISIBLE } else { View.GONE } }
Java
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (requireActivity().getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { pictureInPictureButton.setVisibility(View.VISIBLE); pictureInPictureButton.setOnClickListener(v -> { Rational aspectRatio = new Rational(view.getWidth(), view.getHeight()); PictureInPictureParams params = new PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setTitle("My Streaming App") .setSubtitle("My On-Demand Content") .build(); Boolean result = requireActivity().enterPictureInPictureMode(params); }); } else { pictureInPictureButton.setVisibility(View.GONE); } }
このアクションは、デバイスにシステム機能 FEATURE_PICTURE_IN_PICTURE
がある場合にのみ追加されます。また、アクションがトリガーされると、PIP モードのアスペクト比が再生中の動画のアスペクト比と一致するように設定されます。
この PIP が一般的に何に使用されているかについての情報をユーザーに提供するために、タイトルとサブタイトルを必ず追加してください。
PIP モードで実行中のアプリと共存する
アプリが全画面表示アプリとして実行されている場合、PIP モードで実行されている他のアプリに対応する必要がある場合があります。
Keep-clear API
場合によっては、PIP アプリが全画面表示アプリ内の重要な UI コンポーネントをオーバーレイすることがあります。これを軽減するため、アプリがオーバーレイすべきでない重要な UI コンポーネントを特定するために使用できるクリア領域 API があります。システムは、PIP ウィンドウの位置を変更することで、これらのコンポーネントを覆わないようにリクエストに従おうとします。
ビューをオーバーレイしないように指定するには、次の例のように XML レイアウトで preferKeepClear
を使用します。
<TextView
android:id="@+id/important_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:preferKeepClear="true"
android:text="@string/app_name"/>
この操作は、setPreferKeepClear()
を使用してプログラムで行うこともできます。
Kotlin
private lateinit var binding: MyLayoutBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) binding.importantText.isPreferKeepClear = true }
Java
private MyLayoutBinding binding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); binding.importantText.setPreferKeepClear(true); }
View
全体をクリアする必要はなく、一部のみをクリアすればよい場合もあります。setPreferKeepClearRects()
を使用すると、オーバーレイしない View
の領域を指定できます。Flutter、Jetpack Compose、WebView など、View
をネイティブに使用しない UI には、領域をクリアに保つ必要があるサブセクションが含まれている場合があります。このような場合は、この API を使用できます。
使用タイプ
アプリは、ピクチャー イン ピクチャー モードの主な使用タイプに対応する com.google.android.tv.pip.category
のメタデータ値属性を宣言する必要があります。android:supportsPictureInPicture="true"
を設定している <activity>
は、以下の表の関連する値でこの属性を宣言する必要があります。
これらのカテゴリに該当しない使用タイプ(特にメディア コンテンツの再生)は、TV のピクチャー イン ピクチャー モードでは許可されません。
値 | 説明 |
---|---|
「communication 」 |
ビデオ通話や音声通話などのコミュニケーション ユースケース。 |
「smartHome 」 |
スマートホームの統合(接続されたドアホンやベビーモニターなど)。 |
「health 」 |
フィットネス トラッキングや健康状態のモニタリングなどの健康に関するユースケース。 |
「ticker 」 |
スポーツのライブ スコアやニュース、株価のティッカーなどのティッカーのユースケース。 |
複数の値は縦棒(|
)で区切ります。次に例を示します。
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />