Activity picture-in-picture PiP

1. Basic concepts

Starting with Android 8.0 (API level 26), Android allows launching activities in picture-in-picture (PiP) mode .

Picture-in-picture is a special type of multi-window mode most commonly used for video playback .
With this mode, users can watch videos in a small window pinned to a corner of the screen while navigating between apps or browsing content on the home screen.

Picture-in-picture utilizes the multi-window mode API provided in Android 7.0 to provide a fixed video overlay window.
To add picture-in-picture to your application, you need to register an activity that supports picture-in-picture , switch the activity to picture-in-picture mode
as needed , and ensure that when the activity is in picture-in-picture mode, the interface elements are hidden And the video can continue to play.

2. How users interact with the picture-in-picture window

Users can drag the picture-in-picture window to other locations. Starting with Android 12, users can also do the following:

(1) Tapping the window once reveals the full-screen toggle, close button, settings button, and custom actions provided by the app (such as playback controls).

(2) Double-tap the window to switch between the current picture-in-picture size and the maximum picture-in-picture size.
Drag a window to the left or right edge to hide it; click or drag the visible part of a hidden window to unhide it.

(3) Use the "Pinch to Zoom" gesture to adjust the size of the picture-in-picture window.

Your application controls when the current activity enters picture-in-picture mode. Here are some examples:

(1) An activity can enter picture-in-picture mode when the user taps the home button (in button navigation mode) or swipes up to the home screen (in gesture navigation mode). (This is how Google Maps continues to display directions while the user is running other activities at the same time.)

(2) Your app can switch a video to picture-in-picture mode when the user returns from a video to browse other content.

Your app can switch the video to picture-in-picture mode when the user finishes watching an episode. The Home screen will show promotional or synopsis information about the next episode of the show.

Your app can provide a way for users to queue other content for playback while watching a video. When the main screen displays content selection activity, the video will continue to play in picture-in-picture mode.

3. Declare support for picture-in-picture

By default , the system does not automatically provide picture-in-picture support for apps. If you want to support picture-in-picture in your application, you can register the video activity in the manifest by setting android:supportsPictureInPicture to true. Also, specify your activity to handle layout configuration changes. This way, your activity wo n't restart if there is a layout change during the picture-in-picture mode transition.

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

4. Switch your activity to picture-in-picture mode

To enter picture-in-picture mode, the activity must be called enterPictureInPictureMode(). For example, the following code switches the activity to picture-in-picture mode when the user taps a dedicated button in the app UI:

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

You may need to add logic to switch the activity into picture-in-picture mode instead of going into the background. For example, if the user presses the Home or Recents
button while navigating on Google Maps , the app switches to picture-in-picture mode. You can replace onUserLeaveHint by

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

4.1 Made the transition to picture-in-picture mode smoother with gesture navigation

Starting with Android 12, you can use setAutoEnterEnabledthe logo transition to picture-in-picture mode more smoothly when swiping up to go to the home screen in gesture navigation mode.

To implement this functionality, do the following:

(1). Use setAutoEnterEnabledthe structure PictureInPictureParams.Builder, as follows:

setPictureInPictureParams(new PictureInPictureParams.Builder()
    .setAspectRatio(aspectRatio)
    .setSourceRectHint(sourceRectHint)
    .setAutoEnterEnabled(true)
    .build());

Note : setAutoEnterEnabledWhen , there is no need onUserLeaveHintto explicitly call theenterPictureInPictureMode

(2). Call setPictureInPictureParams as early as possible with the latest PictureInPictureParams. Apps should not wait for the onUserLeaveHint callback (as they do in Android 11).

For example, an app might want to call setPictureInPictureParams on the first play, and on any subsequent play (if the aspect ratio changes).

(3). Call setAutoEnterEnabled(false) as needed. For example, it might not be optimal for a video app to enter picture-in-picture mode if playback is currently paused.

5 Handling interface elements in picture-in-picture mode

When the activity enters or exits the picture-in-picture mode,
the system calls Activity.onPictureInPictureModeChanged() or Fragment.onPictureInPictureModeChanged().
You should override these callbacks to repaint the activity's UI elements.
Note that in picture-in-picture mode, your activity is displayed in a small window.
In picture-in-picture mode, the user cannot interact with the app's UI elements , and it may be difficult to see details of small UI elements.
A video playback activity with a minimal interface provides the best user experience.

If your app needs to provide custom actions for picture-in-picture, see Adding Controls in this document.
Remove other UI elements before the activity enters picture-in-picture mode, and restore them when the activity becomes fullscreen again:

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.
    }
}

5.1 Support for smoother animation when exiting picture-in-picture mode

Starting with Android 12, the SourceRectHint flag is now repurposed for smoother animation when exiting picture-in-picture mode. On exit, the system animates
using the currently available sourceRectHint , whether it is the original Rect used to enter picture-in-picture mode, or an updated Rect provided by the app.

To implement this feature, please update your application as follows:
(1) Continue to use sourceRectHint and aspectRatio to construct PictureInPictureParams to achieve smooth entry animation.
(2) If necessary, update sourceRectHint before the system starts the exit transition.
When the system is about to exit picture-in-picture mode, the activity's view hierarchy is laid out in its target configuration (such as full screen).
An app can attach a layout change listener to its root view or a target view (such as a video player view) to detect the event and update the sourceRectHint before the animation begins.

// Listener is called immediately after the user exits PiP but before animating.
playerView.addOnLayoutChangeListener {
    
     _, left, top, right, bottom,
                     oldLeft, oldTop, oldRight, oldBottom ->
    if (left != oldLeft || right != oldRight || top != oldTop
            || bottom != oldBottom) {
    
    
       // The playerView's bounds changed, update the source hint rect to
       // reflect its new bounds.
       val sourceRectHint = Rect()
       playerView.getGlobalVisibleRect(sourceRectHint)
       setPictureInPictureParams(
           PictureInPictureParams.Builder()
               .setSourceRectHint(sourceRectHint)
               .build()
       )
    }
}

5.2 Add controls

A picture-in-picture window can display controls when the user opens the window menu (by tapping the window on a mobile device or selecting the menu with a TV remote) .

If the app has an active media session, the window displays **Play, Pause, Forward, and Back controls**.


You can also explicitly specify custom actions by building PictureInPictureParams (using PictureInPictureParams.Builder.setActions()) before entering picture-in-picture mode ,
and using enterPictureInPictureMode(android.app.PictureInPictureParams) or setPictureInPictureParams(android.app.PictureInPictureParams)
in These parameters are passed when entering picture-in-picture mode.
Note that if you try to add more controls than getMaxNumPictureInPictureActions(), only the upper limit will be added.

5.3 Disable seamless resizing for non-video content

Android 12 adds the setSeamlessResizeEnabled flag, which provides a smoother crossfade animation when resizing non-video content in a picture-in-picture window.
Previously, resizing non-video content in a picture-in-picture window would produce annoying visual artifacts.

For backward compatibility, the setSeamlessResizeEnabled flag is set to true by default. For video content, leave it set to true; for non-video content, change it to false.

To disable seamless resizing for non-video content, write the following code:

setPictureInPictureParams(new PictureInPictureParams.Builder()
          .setSeamlessResizeEnabled(false)
          .build());

6. Continue playing video in picture-in-picture mode

When your activity switches to picture-in-picture mode, the system puts the activity in a paused state and calls the activity's onPause() method.
When the activity is paused in picture-in-picture mode, video playback should not be paused, but should continue to play.

In Android 7.0 and higher, you should pause video playback when the system calls your activity's onStop() and resume video playback when
the system calls your activity's onStart() .
This way, you don't need to check in onPause() if the app is in picture-in-picture mode, and just keep playing the video.

If you must pause playback in your onPause() implementation,
check if you are in picture-in-picture mode by calling isInPictureInPictureMode() and handle playback accordingly, for example:

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.
    }
}

When your activity switches back from picture-in-picture mode to full-screen mode, the system resumes your activity and calls the onResume() method.

6.1 Using a single playback activity in picture-in-picture mode

In your application, the following situation may arise:
There is a video playback activity in picture-in-picture mode, and the user selects a new video while browsing content on the home screen.
Instead of starting a new activity that might confuse the user, the new video should be played in full-screen mode within the existing playback activity .

To ensure that a single activity is used for video playback requests and to enter and exit picture-in-picture mode as needed,
set the activity's android:launchMode to singleTask in the manifest:

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

In your activity, in onNewIntent() and handle the new video, stopping any existing video from playing as needed.

6 best practices

Low RAM devices may not be able to use picture-in-picture mode. Before your app uses picture-in-picture,
be sure to check to make sure picture-in-picture is available by calling hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE).

Picture-in-picture is intended for activities that play full-screen video.
When switching an activity to picture-in-picture mode, avoid displaying anything other than video content.
Track when your activity enters picture-in-picture mode and hide UI elements, as described in Handling UI Elements in Picture-in-Picture Mode.

When the activity enters the picture-in-picture mode, it will not get the input focus by default . To receive input events in picture-in-picture mode , use MediaSession.setCallback() . For more information on how to use setCallback(), see Displaying the Listener card.

When your app is in picture-in-picture mode, video playback in the picture-in-picture window may cause audio interference
in other apps (for example, music player apps or voice search apps) . To avoid this problem, request audio focus when the video starts playing , and handle audio focus change notifications, as described in Managing Audio Focus. If you receive an audio focus loss notification while in picture-in-picture mode, pause or stop video playback.


When your application is about to enter picture-in-picture mode,
please note that only the top-level activity will enter picture-in-picture mode.
In some cases (such as on a multi-window device), the system may display the underlying activity
at this point, and you may see the underlying activity again next to the picture-in-picture activity.
You should handle this situation accordingly, including the following activities getting onResume() or onPause() callbacks.
It is also possible for the user to interact with the activity. For example, if your video list activity is showing and
the video playback activity is in picture-in-picture mode, the user might select a new video from the list, and the picture-in-picture activity should update accordingly.

at last

If you want to become an architect or want to break through the 20-30K salary range, then don't be limited to coding and business, but you must be able to select models, expand, and improve programming thinking. In addition, a good career plan is also very important, and the habit of learning is very important, but the most important thing is to be able to persevere. Any plan that cannot be implemented consistently is empty talk.

If you have no direction, here I would like to share with you a set of "Advanced Notes on the Eight Major Modules of Android" written by the senior architect of Ali, to help you organize the messy, scattered and fragmented knowledge systematically, so that you can systematically and efficiently Master the various knowledge points of Android development.
insert image description here
Compared with the fragmented content we usually read, the knowledge points of this note are more systematic, easier to understand and remember, and are arranged strictly according to the knowledge system.

Full set of video materials:

1. Interview collection

insert image description here
2. Source code analysis collection
insert image description here

3. The collection of open source frameworks
insert image description here
welcomes everyone to support with one click and three links. If you need the information in the article, directly scan the CSDN official certification WeChat card at the end of the article to get it for free↓↓↓

Guess you like

Origin blog.csdn.net/datian1234/article/details/130373717
pip