'Entering in PIP Mode with the application minimized (Android Studio)

My application makes a call to the server which may take a few seconds. The user can minimize the App before receiving the response from the server.

So what I am trying to do is that if the App is minimized when it receives the response from the server, it will go to PIP mode.

When I try to enter Pip mode with the application minimized I get this error:

java.lang.IllegalStateException: Activity must be resumed to enter picture-in-picture

The error occurs when this line is executed:

enterPictureInPictureMode();

Thanks.



Solution 1:[1]

Need to check whether the special permission Picture-in-Picture is given before entering the mode.

    AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
      if (manager != null) {
        int modeAllowed = manager.unsafeCheckOpNoThrow(OPSTR_PICTURE_IN_PICTURE, Process.myUid(),
            context.getPackageName());

        if (modeAllowed == AppOpsManager.MODE_ALLOWED) {
          // Enter picture-in-picture
        }
      }

Solution 2:[2]

If you are using rn-android-pip libary:

import android.app.AppOpsManager;
import android.content.Context;
import android.os.Process;

public void enterPictureInPictureMode() {
    if (isPipSupported) {
        AppOpsManager manager = (AppOpsManager) reactContext.getSystemService(Context.APP_OPS_SERVICE);
        if (manager != null) {
            int modeAllowed = manager.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, Process.myUid(),
                reactContext.getPackageName());

            if (modeAllowed == AppOpsManager.MODE_ALLOWED) {
                if (isCustomAspectRatioSupported) {
                    PictureInPictureParams params = new PictureInPictureParams.Builder()
                            .setAspectRatio(this.aspectRatio).build();
                    getCurrentActivity().enterPictureInPictureMode(params);
                } else {
                    getCurrentActivity().enterPictureInPictureMode();
                }
            }
        }
    }
}

Solution 3:[3]

According to the doc:

Also, specify that your activity handles layout configuration changes so that your activity doesn't relaunch when layout changes occur during PiP mode transitions.

Switching to PiP mode triggers configuration changes, and this causes the Activity to be recreated, says going through stopped -> destroyed -> created -> ...

And we can find how Activity decides whether it can enter PiP mode or not: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/Activity.java

final void performStop(boolean preserveWindow, String reason) {
    ...
    
    // Disallow entering picture-in-picture after the activity has been stopped
    mCanEnterPictureInPicture = false;
   ...
}

public boolean enterPictureInPictureMode(@NonNull PictureInPictureParams params) {
    ...
    if (!mCanEnterPictureInPicture) {
        throw new IllegalStateException("Activity must be resumed to enter"
                + " picture-in-picture");
    }
    ...
    mIsInPictureInPictureMode = ActivityClient.getInstance().enterPictureInPictureMode(
                mToken, params);
    return mIsInPictureInPictureMode;
}

So you may need to check you AndroidManifest again to ensure you have already properly handled configuration changes to avoid Activity recreation:

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Eric Liu
Solution 2 Eduardo Ramos
Solution 3 jxsun