テレビでのマルチタスク

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 ウィンドウの位置を変更することで、これらのコンポーネントを覆わないようにリクエストに従おうとします。

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> は、以下の表の関連する値でこの属性を宣言する必要があります。

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

説明
communication ビデオ通話や音声通話などのコミュニケーション ユースケース。
smartHome スマートホームの統合(接続されたドアホンやベビーモニターなど)。
health フィットネス トラッキングや健康状態のモニタリングなどの健康に関するユースケース。
ticker スポーツのライブ スコアやニュース、株価のティッカーなどのティッカーのユースケース。

複数の値は縦棒(|)で区切ります。次に例を示します。

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