テレビでマルチタスク

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)以降を搭載している TV デバイスの場合は、enterPictureInPictureMode() を呼び出して PIP モードでアプリを実行します。以前のバージョンの Android を搭載したテレビデバイスは 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 コンポーネントを全画面アプリ内にオーバーレイすることがあります。これを軽減するために、アプリは Keep-clear API を使用して、オーバーレイすべきではない重要な UI コンポーネントを識別できます。システムはリクエストを尊重し、PIP ウィンドウの位置を変更することで、これらのコンポーネントがカバーされないようにしようとします。

Keep-Clear

ビューをオーバーレイしないように指定するには、次の例のように 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> は、以下の表の関連する値を使用して、この属性を宣言する必要があります。

これらのカテゴリに当てはまらない使用タイプ(特にメディア コンテンツの再生)は、テレビのピクチャー イン ピクチャー モードでは許可されません。

説明
communication ビデオ通話や音声通話などの通信のユースケース。
smartHome スマートホームとの統合(コネクテッド ドアホンやベビーモニターなど)。
health フィットネス トラッキングや健康管理など、健康に関するユースケース。
ticker スポーツのライブスコアや、ニュースや株価のティッカーなどのティッカーのユースケース。

複数の値は縦棒(|)で区切ります。例:

<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />