6

I've followed the Android picture-in-picture documentation. That is to say, my PiP activity is marked android:launchMode="singleTask", android:resizeableActivity="true", and android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" in the manifest.

Picture-in-picture seems to work great. However, I have noticed a case where I am experiencing undesirable behavior.

When my app receives a push, I create a PendingIntent with an Intent for MyActivity (different Activity than the PiP Activity). However, when I tap on the notification and the Intent is used, MyActivity is launching inside the PiP window!

I've tried adding android:launchMode="singleTask" to MyActivity in the manifest. I've also tried adding that flag programmatically to the Intent before using it with PendingIntent.getActivity(). This does not seem to fix the issue.

Can anyone tell me how to prevent this?

aminography
  • 21,986
  • 13
  • 70
  • 74
Andrew
  • 20,756
  • 32
  • 99
  • 177
  • First guess, could You after clickicking on notification open headless (layout-less) activity which will run another activity? – deadfish Jan 07 '19 at 14:57

4 Answers4

13

To address this issue, we should set a unique taskAffinity for the PiP Activity in manifest. It indicates the task which the activity is belonged to. Setting a unique value for it separates the task of PiP Activity from your MainActivity.

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


---------------------- Before ---------------------------------------------- After ------------------------

enter image description here enter image description here

aminography
  • 21,986
  • 13
  • 70
  • 74
  • 1
    That works! However, it does present a new issue. When launching `MyPipActivity`, the animation is completely different and undesirable. – Andrew Jan 08 '19 at 14:45
  • 1
    This problem happens for all non-root task activities. Also when the activity set `singleInstance`. However, I have not found a solution for it until now. Maybe it is better to override all activity transitions ourself using [something like this](https://stackoverflow.com/a/8319701/1631967). – aminography Jan 09 '19 at 05:11
  • Thanks for your response. I've explored that solution previously. My problem is I cannot reference system animations directly (i.e.: android.R.anim.xyz). I could copy the contents of those Android animation files and use my own custom animations, but that breaks as soon as some device OEM changes the Activity switching animations (which many seem to do). – Andrew Jan 09 '19 at 19:06
  • You're welcome dude. I'll be very glad if I know how you fix this issue. I had the same problem with singleInstance mode. – aminography Jan 09 '19 at 19:31
  • If I figure out a solution, I'll let you know. Thanks for the help! – Andrew Jan 09 '19 at 19:39
  • The only issue with this solution is that (in normal cases ignoring notifications) as soon as we move the app to the background using the Home button and then maximizing the PiP window there is no back stack and pressing the back button will lead to closing the app. – Mohsen Mirhoseini Aug 24 '23 at 15:46
2

First of all, as you can see in google sample codes, it does not need to make the launch mode of PIP Activity singleTask. However, you need to move the launcher task to front which is not in PIP mode, in order to disabling PIP state.

By calling bellow snippet in the onCreate() method of the target Activity which is called from notifications, you can achieve this.

public static void moveLauncherTaskToFront(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    assert activityManager != null;
    final List<ActivityManager.AppTask> appTasks = activityManager.getAppTasks();
    for (ActivityManager.AppTask task : appTasks) {
        final Intent baseIntent = task.getTaskInfo().baseIntent;
        final Set<String> categories = baseIntent.getCategories();
        if (categories != null && categories.contains(Intent.CATEGORY_LAUNCHER)) {
            task.moveToFront();
            return;
        }
    }
}

---------------------- Before ---------------------------------------------- After ------------------------

enter image description here enter image description here

aminography
  • 21,986
  • 13
  • 70
  • 74
  • If I understand correctly, this is taking the PiP Activity and "maximizing" it. My situation involves launching an Activity that is NOT the PiP Activity. So, if `MyPipActivity` is running in a PiP window, and I have a `PendingIntent` for a notification to launch `MainActivity`, I want `MainActivity` to launch full screen (ideally with the PiP window running `MyPipActivity` still active) in its own task. Right now, clicking the notification is launching `MainActivity` in the PiP window. – Andrew Jan 07 '19 at 19:57
0

I've also met this problem, and you can try to add "android:excludeFromRecents="true" in your MyPipActivity manifest

Milan Pansuriya
  • 2,521
  • 1
  • 19
  • 33
-1

add android:supportsPictureInPicture="false" to MyActivity in the manifest. It should fix your problem

  • Thanks for the reply. I've added `android:supportsPictureInPicture="false"` to all Activitys (except my PiP Activity) and the problem is still occurring. – Andrew Jan 04 '19 at 14:32