How to use Android Picture-in-Picture mode with OpenTok

Android Picture in Picture with opentok webrtc video call

Picture this: you are outside in a park and attending a meeting using your Android phone with a cool OpenTok-based application, but suddenly you need to check some information from a different app on your phone. Currently, your only option would be to put the original app in the background, and stop seeing the rest of the people in the meeting while you check that information.

Well we have good news! Starting from Android O, there is an alternative. In the latest version of Android, Google added the possibility to put an Activity in “Picture-in-Picture” (PiP) mode: that means that you will be able to continue seeing the video of a OpenTok session while you are doing other things with your phone. In fact, this was already available in Android M, but it was only available on Android TV. Now, with Android O, it is available in phones too.

In this blog post we will see how you can add this feature to your application using the OpenTok SDK.

Preparing your Application to support Android Picture-in-Picture

In order to have PiP, you can use the same SDK you are already using – no changes are required from OpenTok side.

When in PiP mode, your activity will be shown on top of everything else, and in a small window, so you should plan to remove all UI elements and display just the video of the OpenTok session.

You don’t need to put anything to exit from PiP and back to fullscreen mode. Android will deal with that, adding some controls that will appear when the user touches the PiP Window.

In order to support PiP, you need to add it explicitly to the activity you want to be displayed in PiP mode, as you would have guessed, the PiP mode is set per-activity. Usually in an OpenTok application, the activity you want to add PiP support is the one which is dealing with the session video stream.

You need to add three things in your activity entry in the manifest file:

  android:resizeableActivity="true"

  android:supportsPictureInPicture="true"

  android:configChanges=

        "screenSize|smallestScreenSize|screenLayout|orientation"

Besides the supportsPictureInPicture, it is important to add the resizableActivity attribute and the configChanges, so your activity won’t be recreated every time it enters or exits PiP mode.

Entering Picture-In-Picture mode

Once you have declared that your activity is ready to be displayed in PiP mode, you just need to have some UI element or Event that will trigger this mode in the Activity. Fortunately, this is quite simple: the Activity class has a method called enterPictureInPictureMode() that, without any surprise, will put the activity in Picture-in-Picture mode.

If you try to call that method, you will see that it is deprecated. This is because it was there in Android TV and now the recommended way is to build some parameters that will customize the PiP experience.

The parameters are controlled by building an instance of PictureInPictureParams class. That class will allow you to set, for example, the aspect ratio of the PiP window where your activity will be displayed. If your phone is in portrait mode, you will want to set an aspect ratio similar to the phone screen aspect ratio:

PictureInPictureParams params = new PictureInPictureParams.Builder()

       .setAspectRatio(new Rational(9,16))

       .build();

Using this class you can also tweak the controls that will be shown while in PiP. See the documentation for more details

To be in PiP or not to be

Android Picture-in-Picture with OpenTok live video call

The last thing that we need to do to have a cool video chat application that will allow you to see the other peer while browsing your Twitter timeline is to adapt the user interface for these different modes.

Like the rest of the things we’ve done, this is also pretty easy. You need to @Override a method that will be called when the mode is changed: that method is void onPictureInPictureModeChanged(boolean is InPictureInPictureMode, Configuration newConfig).

When the activity is entering PiP mode, that method will be invoked, and there is where you will do things like hiding the action bar, hiding the publisher view or hiding any button that is not useful in PiP. Take into account that the size of the PiP window is quite small, so you probably only want to have the subscriber or subscribers video on it.

For example this is the code we use in the sample code that illustrates this blogpost:

@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, 
Configuration newConfig) {
   super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
   if (isInPictureInPictureMode) {
       findViewById(R.id.button).setVisibility(View.GONE);
       mPublisherViewContainer.setVisibility(View.GONE);
       publisher.getView().setVisibility(View.GONE);
       getActionBar().hide();
   } else {
       findViewById(R.id.button).setVisibility(View.VISIBLE);
       mPublisherViewContainer.setVisibility(View.VISIBLE);
       publisher.getView().setVisibility(View.VISIBLE);
       if (publisher.getView() instanceof GLSurfaceView) {
           ((GLSurfaceView)publisher.getView()).setZOrderOnTop(true);
       }
       getActionBar().show();
   }
}

See that we hide the action bar (be careful about using AppCompatActivity and getSupportActionBar) and the publisher container.

Apart from the UI elements themselves, OpenTok SDK offers a method to pause a session when the activity is paused, however when PiP is in play, you probably don’t want to pause a session. When you call session.onPause, you unsubscribe from the video stream from your subscribers, but in PiP mode you still want to see the video of your peers.

Activity has a handy isInPictureInPictureMode method that will tell you if the activity is in that mode or not, so your new onPause/onResume method will now look something like this:

@Override

protected void onPause() {
   super.onPause();
   if (!isInPictureInPictureMode()) {
       if (session != null) {
           session.onPause();
       }
   }
}
@Override
protected void onResume() {
   super.onResume();
   if (!isInPictureInPictureMode()) {
       if (session != null) {
           session.onResume();
       }
   }
}

Time to get building

At this point, you should be able to add this cool feature to your app. Android handles most of the process and requires few changes from your side so this is a win/win situation.

We have built a simple sample code that illustrates the process of adding Picture-in-Picture to an OpenTok-based Android application.

You can start building for free on the OpenTok platform by signing up for an account here, and if you’re looking for more information on building with live video, why not check out our posts on building social video apps (Part 1 and Part 2)? You might also find our post about using OpenTok with Kotlin for Android useful.