David Cruz

Android: Introduction to Picture In Picture mode, that amazing overshadowed feature.

(Source: https://9to5google.com/wp-content/uploads/sites/4/2017/05/android-o-dev-preview-picture-in-picture.jpg?quality=82&strip=all)

With the release of Android Oreo (API 26) it include one feature, on my understanding, overshadowed with all that limitations, new permissions, etc…
Of course, as the title indicates, the feature I am referring to is Picture In picture.

If you are using any kind of MediaPlayer, ExoPlayer or Media resource or video, audio, video-call, etc…
I am sure you would like to know more about picture in picture. This feature will allow your users to continue watching whatever they are streaming on from the Player to a “Floating window”.

This feature is used on many apps included Youtube.
As a user, I am sure, sometimes, you just want to reply a message while the video you are watching do not stop, as will make it, in the majority of cases, lose your current progres.

Anyway, anyhow, here is how to implement a basic picture in picture mode in to your Player.

I know, you might think this it will require a lot of code just to have a “floating window”, but in fact, picture in picture it works out of the box!. If you have 15 minutes, follow this simple 5 steps and you will have it implemented in no time.

source: https://media1.tenor.com/images/e2771e999a5dbe25e6337c055e05a198/tenor.gif?itemid=8803801

DISCLAIMER: THIS FEATURE ONLY WORKS ON ANDROID OREO AND ABOVE (SDK ≥ 26). do not try to use it on any SDK below as it will crash.

First Step:

You will need to add few few things in to your AndroidManifest.xml file in order to enable and support picture in picture mode. Add this lines into the activity where is running your player (in my case is MainActivity).

// Lines to Add
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
// Old Code
<activity
android:name=".MainActivity"
android:screenOrientation="landscape">
/* */
</activity>
// New Code
<activity
android:name=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:screenOrientation="landscape">
/* */
</activity

Second Step:

Let’s create the parameters we will need for our Picture In Picture mode.
Create the following function in to your activity.

@TargetApi(Build.VERSION_CODES.O)
private fun updatePic2PicParams() = PictureInPictureParams.Builder()
.setActions(emptyList())
.build()

Third Step:

Ok, our activity is ready to support picture in picture. Let’s implement it.
in our Activity, in onCreate, we need to set the function setPictureInPictureParams(params: PictureInPictureParams).
Please notice setPictureInPictureParams is an Activity Function.

In my case, what I did is check if the player is playing and if it has Picture In Picture support.

// MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Include this line
initObservers()
}
// Create this private method
private fun initObservers() {
if (isPlaying && hasPipSupport()) {
setPictureInPictureParams(updatePic2PicParams())
}
}
// BooleanExt.kt:
// Create this extensions functions to check if the device is SDK Oreo or above and if has Picture 2 picture support
fun Context.isOreoOrAbove(): Boolean {
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O
}

fun Context.hasPipSupport(): Boolean {
return this.isOreoOrAbove() && packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
}

Fourth Step:

Override the Activity function onUserLeaveHint() including the following code, please notice enterPictureinPictureMode(params: PictureInPictureParams) is and activity function:

override fun onUserLeaveHint() {
super.onUserLeaveHint()
if (hasPipSupport() && isPlaying) {
enterPictureInPictureMode(updatePic2PicParams())
}
}

Fifth Step:

As a bonus you can hide all your player controls while you are in Picture In Picture Mode and show them again when you come back the the player on fulls screen by overriding the Activity function onPictureInPictureMode as the following:

override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration?) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)

// add this line to your PlayerView
binding.playerView.useController = !isInPictureInPictureMode
}

And that is all to make your player as Picture In Picture mode (Floating window) while your users are doing something else.

And that is pretty much all!, I hope this Quick introduction help you all to use this amazing feature into your apps. If you would like to see a quick demo of a Picture In Picture Mode implementation please check this link to my repo:
https://github.com/DavidCruzUK/Android-Picture2Picture

I you looking to learn more about Pincture-In-Picture, you can check my course on my website:
https://www.davthecoder.com/implement-picture-in-picture-for-android

Happy coding!,
David Cruz

Contact me: https://www.davidcruz.co.uk/contact
Medium Blog: https://davthecoder.medium.com/
Twitch: https://www.twitch.tv/davthecoder
GitHub: https://github.com/DavidCruzUK
Instagram: https://www.instagram.com/davthecoder
Twitter: https://twitter.com/davthecoder
Youtube: https://youtube.com/c/DavidCruzAnaya
Support me on Patreon! https://www.patreon.com/davthecoder

Android Lead, Kotlin developer & Blogger