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: () -> Unit = { 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
ステートメントを追加します。スワイプ操作で PiP モードに入るようにするには、ビルダーにsetAutoEnterEnabled
を追加してtrue
に設定します。これにより、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
][6] と等しくないことを確認します。
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 プレーヤーの場合と同様に、アスペクト比を計算できるタイミングのチェックを追加する必要があります。