4

Is there any way to find out if screen is split if I have no access to Activity? (Structurally I can't call isInMultiWindowMode method.

I see that default Activity#isInMultiWindowMode() implementation is:

public boolean isInMultiWindowMode() {
    try {
        return ActivityManagerNative.getDefault().isInMultiWindowMode(mToken);
    } catch (RemoteException e) {
    }
    return false;
}

Is there any workaround ?

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
  • Where do you want to check? Inside fragment? – Jai Sep 29 '16 at 07:57
  • Wherever you will go , when specific app would go into multiwindowmode you will have access to one of the activity which will be on top stack – Jai Sep 29 '16 at 07:58
  • @Jai through hierarchy due to encapsulation of screen logic I have no access to Activity – Andrii Abramov Sep 29 '16 at 08:01
  • You could also use listener onMultiWindowChanged inside your activity but I'm not sure about how could you update your child class, If you could tell me about relation and hierarchy, I could help you with that – Jai Sep 29 '16 at 08:17
  • 1
    @Jai I found quite a risky solution. I have access to method `getContext()` which returns a `Context` class. And after casting it to `Activity` can access this method. Thank you – Andrii Abramov Sep 29 '16 at 08:22

2 Answers2

4

I think the only way to do this without an Activity is by using an AccessibilityService that has the permissions to get the list of windows currently displayed and check if there's a window whose type is AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER.

For example, you could have the following method to do so:

private boolean inSplitScreenMode(List<AccessibilityWindowInfo> windows) {
    for (AccessibilityWindowInfo window : windows) {
        if (window.getType() == AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER) {
            return true;
        }
    }
    return false;
}

check this method when receiving window state changed accessibility events

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if ((event.getEventType() & AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) != 0) {
        if (inSplitScreenMode(getWindows()) {
            Log.d(TAG, "Split screen mode detected");
        } else {
            Log.d(TAG, "No split screen");
        }
    }
}
Alex Ionescu
  • 413
  • 6
  • 20
  • hey @alex this is exactly what I was looking for, to detect when the device goes in split screen mode. But unfortunately, the method you provided `inSplitScreenMode` does not work. Is there anything missing? – Mayur More Aug 24 '20 at 12:08
  • @MayurMore do you have a properly set-up `AccessibilityService` (ie. receives `AccessibilityEvent`s)? In order to detect this, your service mustn't filter events from system apps by providing appropriate `android:packageNames` attribute. Lastly as with all Android APIs, this largely varies by manufacturer implementation (personally I tested this on a Pixel 3 running android 9) – Alex Ionescu Aug 25 '20 at 12:00
  • @AlexLonescu It worked! The accessibilityFlag, flagRetrieveInteractiveWindows was missing from the accessibility.xml. :) – Mayur More Aug 25 '20 at 15:10
  • @MayurMore forgot about the service flags as it's been a while. Glad it's working :D – Alex Ionescu Aug 25 '20 at 16:41
3

Inside Fragment you can use

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    if (((Activity)getContext()).isInMultiWindowMode()){
        // ...
    }
}
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
GMG
  • 1,498
  • 14
  • 20