Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

ピクチャー イン ピクチャーのサポート

Android 8.0(API レベル 26)では、アクティビティをピクチャー イン ピクチャー(PIP)モードで起動できます。PIP とは、特別なタイプのマルチウィンドウ モードで、主に動画の再生に使用します。 ユーザーは、アプリ間を移動したり、メイン画面でコンテンツをブラウジングしたりしながら、画面の隅に固定された小さなウィンドウで動画を見続けることができます。

PIP では、Android 7.0 で使用可能なマルチウィンドウ API を利用して、固定の動画オーバーレイ ウィンドウを実現しています。アプリで PIP を使用するには、PIP をサポートするアクティビティを登録し、必要に応じてアクティビティを PIP モードに切り替える必要があります。そして、アクティビティが PIP モードのときには、UI 要素を非表示にして動画の再生を継続するようにします。

PIP ウィンドウは、画面の最上レイヤの、システムにより選択された隅の部分に表示されます。別の位置にドラッグすることもできます。ウィンドウをタップすると、フルスクリーン切り替え(ウィンドウ中央)と閉じるボタン(右上隅の「X」)の 2 つの特別なコントロールが表示されます。

現在のアクティビティが PIP モードに入るタイミングは、アプリで制御します。以下に、例をいくつか示します。

  • ユーザーがホームボタンまたは「最近使ったアプリ」ボタンをタップして別のアプリを選択したとき、アクティビティを PIP モードに切り替えます(Google マップでは、ユーザーが別のアクティビティを実行している間、この方法でルートを表示し続けます)。
  • ユーザーが動画から他のコンテンツのブラウジングに移動したとき、動画を PIP モードに切り替えます。
  • ユーザーがコンテンツの 1 エピソードの最後を見ている間、動画を PIP モードに切り替えます。メイン画面には、シリーズの次のエピソードに関するプロモーション情報や概要情報を表示します。
  • 動画再生中に、ユーザーが他のコンテンツをキューに追加できるようにします。動画は PIP モードで再生し続け、メイン画面にはコンテンツ選択のアクティビティを表示します。

ピクチャー イン ピクチャーのサポートの宣言

デフォルトでは、システムはアプリによる PIP の使用をサポートしません。 アプリで PIP をサポートするには、android:supportsPictureInPicture および android:resizeableActivitytrue に設定して、動画アクティビティをマニフェストに登録する必要があります。また、アクティビティでレイアウト設定の変更を処理するように指定し、PIP モードへの移行中にレイアウト変更が発生した場合でもアクティビティが再起動しないようにします。

    <activity android:name="VideoActivity"
        android:resizeableActivity="true"
        android:supportsPictureInPicture="true"
        android:configChanges=
            "screenSize|smallestScreenSize|screenLayout|orientation"
        ...
    

アクティビティのピクチャー イン ピクチャーへの切り替え

ピクチャー イン ピクチャー モードに入るには、アクティビティから enterPictureInPictureMode() を呼び出す必要があります。以下のコード例では、ユーザーがアプリの UI の専用ボタンをクリックすると、アクティビティが PIP モードに切り替わります。

Kotlin

    override fun onActionClicked(action: Action) {
        if (action.id.toInt() == R.id.lb_control_picture_in_picture) {
            activity?.enterPictureInPictureMode()
            return
        }
    }
    

Java

    @Override
    public void onActionClicked(Action action) {
        if (action.getId() == R.id.lb_control_picture_in_picture) {
            getActivity().enterPictureInPictureMode();
            return;
        }
        ...
    }
    

アクティビティをバックグラウンドに入れる代わりに、PIP モードに切り替えるロジックを含めることもできます。たとえば Google マップは、ユーザーがホームボタンまたは「最近使ったアプリ」ボタンを押してアプリを移動すると、PIP モードに切り替わります。この状況は、以下のように onUserLeaveHint() をオーバーライドすることでキャッチできます。

Kotlin

    override fun onUserLeaveHint() {
        if (iWantToBeInPipModeNow()) {
            enterPictureInPictureMode()
        }
    }
    

Java

    @Override
    public void onUserLeaveHint () {
        if (iWantToBeInPipModeNow()) {
            enterPictureInPictureMode();
        }
    }
    

ピクチャー イン ピクチャー時の UI の処理

アクティビティがピクチャー イン ピクチャー モードを開始または終了すると、システムから Activity.onPictureInPictureModeChanged() または Fragment.onPictureInPictureModeChanged() が呼び出されます。

アプリでは、これらのコールバックをオーバーライドして、アクティビティの UI 要素を再描画する必要があります。PIP モードでは、アクティビティを表示するウィンドウが小さいことに留意してください。ユーザーが UI 要素を操作できなかったり、UI 要素の詳細が小さすぎて見えなかったりする可能性があります。動画再生のアクティビティでは、UI の数を最小限にすることがユーザー エクスペリエンスの向上につながります。表示するのは動画再生コントロールのみにすべきです。他の UI 要素は、アクティビティを PIP にする前に削除し、フルスクリーンに戻すときに復元するようにします。

Kotlin

    override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean,
                                               newConfig: Configuration) {
        if (isInPictureInPictureMode) {
            // Hide the full-screen UI (controls, etc.) while in picture-in-picture mode.
        } else {
            // Restore the full-screen UI.
        }
    }
    

Java

    @Override
    public void onPictureInPictureModeChanged (boolean isInPictureInPictureMode, Configuration newConfig) {
        if (isInPictureInPictureMode) {
            // Hide the full-screen UI (controls, etc.) while in picture-in-picture mode.
        } else {
            // Restore the full-screen UI.
            ...
        }
    }
    

コントロールの追加

PIP ウィンドウでは、ユーザーが(モバイル デバイスでウィンドウをタップするか、テレビリモコンでメニューを選択することにより)ウィンドウのメニューを開いたときに、コントロールを表示できます。

アプリにアクティブなメディア セッションがある場合は、再生、一時停止、次へ、前へのコントロールが表示されます。

また、あらかじめ PictureInPictureParams.Builder.setActions()PictureInPictureParams を設定してカスタム操作を明示的に指定しておき、PIP モードに入るときに enterPictureInPictureMode(android.app.PictureInPictureParams) または setPictureInPictureParams(android.app.PictureInPictureParams) を使用してそのパラメータを渡すこともできます。 ここで注意が必要なのは、最大数 getMaxNumPictureInPictureActions() より多くの操作を指定しても、実際に渡されるのはこの数までという点です。

ピクチャー イン ピクチャー時の動画再生の継続

アクティビティが PIP に切り替わる際、システムによってアクティビティは一時停止状態になり、アクティビティの onPause() メソッドが呼び出されます。ただ、動画の再生は一時停止すべきではなく、PIP モードでアクティビティが一時停止した場合は、再生を継続する必要があります。

Android 7.0 以降では、システムによってアクティビティの onStop()onStart() が呼び出された際に、アプリで動画再生の一時停止や再開を行うようにします。これにより、アプリが PIP モードで onPause() になっているかを確認したり、明示的に再生を継続したりする必要がなくなります。

onPause() の実装で再生を一時停止する必要がある場合は、isInPictureInPictureMode() を呼び出して PIP モードかどうかを確認し、再生を適切に処理します。以下に例を示します。

Kotlin

    override fun onPause() {
        super.onPause()
        // If called while in PIP mode, do not pause playback
        if (isInPictureInPictureMode) {
            // Continue playback
        } else {
            // Use existing playback logic for paused Activity behavior.
        }
    }
    

Java

    @Override
    public void onPause() {
        // If called while in PIP mode, do not pause playback
        if (isInPictureInPictureMode()) {
            // Continue playback
            ...
        } else {
            // Use existing playback logic for paused Activity behavior.
            ...
        }
    }
    

アクティビティが PIP モードからフルスクリーン モードに戻ると、システムによってアクティビティが再開され、onResume() が呼び出されます。

ピクチャー イン ピクチャーに単一の再生アクティビティを使用する

動画再生アクティビティが PIP モードのときに、ユーザーがメイン画面でコンテンツをブラウジングして新しい動画を選択する可能性があります。そのような場合、新しい動画は既存の再生アクティビティを全画面表示モードにして再生するようにします。新しいアクティビティを起動すると、ユーザーを混乱させる可能性があるためです。

動画再生のリクエストに対して単一のアクティビティが使用されるようにし、必要に応じて PIP モードと全画面表示モードを切り替えられるようにするには、次のようにマニフェストでアクティビティの android:launchModesingleTask に設定します。

    <activity android:name="VideoActivity"
        ...
        android:supportsPictureInPicture="true"
        android:launchMode="singleTask"
        ...
    

アクティビティでは、onNewIntent() をオーバーライドして新しい動画を処理し、必要に応じて既存の動画再生を停止します。

ベスト プラクティス

RAM が少ないデバイスでは、PIP が無効になっている場合があります。アプリで PIP を使用する前に、hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) を呼び出して PIP が使用可能であることを確認してください。

PIP は、フルスクリーン動画を再生するアクティビティを対象としています。アクティビティを PIP モードに切り替えるときは、動画コンテンツ以外を表示しないようにしてください。 ピクチャー イン ピクチャー時の UI の処理で説明されているとおり、アクティビティが PIP モードに入るタイミングをトラッキングし、UI 要素を非表示にしてください。

PIP ウィンドウは画面の隅にフローティング ウィンドウとして表示されるため、メイン画面の PIP ウィンドウで隠される可能性のある領域には、重要な情報を表示しないでください。

アクティビティが PIP モードのときは、デフォルトでは入力フォーカスが取得されません。PIP モードで入力イベントを受信するには、MediaSession.setCallback() を使用します。setCallback() の使用方法の詳細については、「再生しています」カードを表示するをご覧ください。

アプリが PIP モードのとき、PIP ウィンドウでの動画再生によって、別のアプリ(音楽プレーヤー アプリや音声検索アプリなど)が音声干渉を受ける可能性があります。これを回避するには、動画の再生を開始するときに音声フォーカスをリクエストし、音声フォーカスの管理の説明にあるとおり音声フォーカス変更通知を処理します。PIP モードのときに、音声フォーカスを失ったという通知を受け取った場合は、動画再生を一時停止または停止してください。

他のサンプルコード

Android で作成されたサンプルアプリをダウンロードするには、Android PictureInPicture サンプルをご覧ください。 Kotlin で記述されたサンプルアプリをダウンロードするには、Android PictureInPicture サンプル(Kotlin)をご覧ください。