AndroidManifest.xml ファイルのアクティビティ タグで、次の操作を行います。
supportsPictureInPictureを追加してtrueに設定し、アプリでピクチャー イン ピクチャー(PiP)を使用することを宣言します。configChangesを追加してorientation|screenLayout|screenSize|smallestScreenSizeに設定し、アクティビティがレイアウト構成の変更を処理することを指定します。これにより、PIP モードへの遷移中にレイアウト変更が発生した場合でもアクティビティが再起動されなくなります。
<activity
android:name=".SnippetsActivity"
android:exported="true"
android:supportsPictureInPicture="true"
android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
android:theme="@style/Theme.Snippets">
Compose コードで、次の操作を行います。
- この拡張機能を
Contextに追加します。このガイドでは、この拡張機能をアクティビティにアクセスするために何度も使用します。internal fun Context.findActivity(): ComponentActivity { var context = this while (context is ContextWrapper) { if (context is ComponentActivity) return context context = context.baseContext } throw IllegalStateException("Picture in picture should be called in the context of an Activity") }
Android 12 より前の休暇アプリに PIP を追加
Android 12 より前のバージョンで PIP を追加するには、addOnUserLeaveHintProvider を使用します。Android 12 より前のバージョンで PiP を追加する手順は次のとおりです。
- このコードが O から R までのバージョンでのみアクセスされるように、バージョンゲートを追加します。
- キーとして
Contextを使用してDisposableEffectを使用します。 DisposableEffect内で、ラムダを使用してonUserLeaveHintProviderがトリガーされたときの動作を定義します。ラムダで、findActivity()に対してenterPictureInPictureMode()を呼び出し、PictureInPictureParams.Builder().build()を渡します。findActivity()を使用してaddOnUserLeaveHintListenerを追加し、ラムダを渡します。onDisposeで、findActivity()を使用してremoveOnUserLeaveHintListenerを追加し、ラムダを渡します。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.S ) { val context = LocalContext.current DisposableEffect(context) { val onUserLeaveBehavior = Runnable { context.findActivity() .enterPictureInPictureMode(PictureInPictureParams.Builder().build()) } context.findActivity().addOnUserLeaveHintListener( onUserLeaveBehavior ) onDispose { context.findActivity().removeOnUserLeaveHintListener( onUserLeaveBehavior ) } } } else { Log.i("PiP info", "API does not support PiP") }
Android 12 以降の休暇アプリに PiP を追加
Android 12 以降では、PictureInPictureParams.Builder は、アプリの動画プレーヤーに渡される修飾子を通じて追加されます。
modifierを作成し、そのonGloballyPositionedを呼び出します。レイアウト座標は後の手順で使用します。PictureInPictureParams.Builder()の変数を作成します。- SDK が S 以降かどうかを確認する
ifステートメントを追加します。その場合は、setAutoEnterEnabledをビルダーに追加し、trueに設定して、スワイプ時に PiP モードに移行します。これにより、enterPictureInPictureModeを経由するよりもスムーズなアニメーションが実現します。 findActivity()を使用してsetPictureInPictureParams()を呼び出します。builderでbuild()を呼び出し、渡します。
val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(true) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
setAspectRatio を使用して PIP ウィンドウのアスペクト比を設定する
PiP ウィンドウのアスペクト比を設定するには、特定のアスペクト比を選択するか、プレーヤーの動画サイズの幅と高さを使用します。Media3 プレーヤーを使用している場合は、アスペクト比を設定する前に、プレーヤーが null ではなく、プレーヤーの動画サイズが VideoSize.UNKNOWN と等しくないことを確認します。
val context = LocalContext.current val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) { val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect() builder.setSourceRectHint(sourceRect) builder.setAspectRatio( Rational(player.videoSize.width, player.videoSize.height) ) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(shouldEnterPipMode) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
カスタム プレーヤーを使用している場合は、プレーヤー固有の構文を使用して、プレーヤーの高さと幅のアスペクト比を設定します。初期化中にプレーヤーのサイズが変更され、アスペクト比の有効な範囲外になった場合、アプリがクラッシュすることに注意してください。media3 プレーヤーの場合と同様に、アスペクト比を計算できるタイミングに関するチェックを追加する必要がある場合があります。