テレビでマルチタスク

Android 14(API レベル 34)では、マルチタスクを可能にするために、ピクチャー イン ピクチャー(PiP)API が強化されています。PiP のサポートは Android 8.0(API レベル 26)で導入されましたが、Android TV では広くサポートされておらず、Android 13 より前の Google TV ではまったくサポートされていませんでした。テレビのマルチタスクでは、PIP モードを使用して、2 つのアプリを画面上に共存させることができます。1 つは全画面で実行され、もう 1 つは PIP モードで実行されます。これらのモードのいずれかで実行されるアプリには、異なる要件があります。

デフォルトの動作では、PIP アプリがフルスクリーン アプリをオーバーレイします。これは、標準の Android ピクチャー イン ピクチャーの動作とほぼ同じです。

マルチタスクを統合する場合、アプリはテレビ向けアプリの品質に関するガイドラインに準拠して使用タイプを宣言する必要があります。

アプリを PiP モードで実行する

Android 14(API レベル 34)以降を搭載したテレビ デバイスの場合は、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 コンポーネントをオーバーレイすることがあります。これを軽減するために、アプリがオーバーレイすべきでない重要な UI コンポーネントを特定するために使用できる keep-clear 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> は、下記の表の関連する値を使用してこの属性を宣言する必要があります。

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

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

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

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