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 モードで実行されている他のアプリに対応する必要がある場合があります。
クリア領域 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を宣言する必要があります。<activity>
を設定した
android:supportsPictureInPicture="true"
は、次の表の関連する値を使用してこの属性を宣言する必要があります。
これらのカテゴリに該当しない使用タイプ(特にメディア コンテンツの再生)は、TV のピクチャー イン ピクチャー モードでは許可されません。
| 値 | 説明 |
|---|---|
「communication」 |
ビデオ通話や音声通話などの通信ユースケース。 |
「smartHome」 |
接続されたドアベルやベビーモニターなどのスマートホーム統合。 |
「health」 |
フィットネス トラッキングや健康状態のモニタリングなどの健康に関するユースケース。 |
「ticker」 |
スポーツのライブスコアやニュース、株価ティッカーなどのティッカー ユースケース。 |
複数の値は縦棒(|)で区切ります。次に例を示します。
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />