androidandroid-viewandroid-window

Is there a way to programmatically locate all Windows within a given application?


Is it possible to programmatically enumerate all of the android.view.Windows, or decor views within an application?

Dialogs for example will both open in a new Window, separate from the main Activity window. I can locate them via Dialog.getWindow() but I'm not sure how I would do this with a built-in components such as the activity menu popup.

Is there any way, from an Application, Context, or the WindowManager, or something else, to enumerate the Windows associated with my app?

I can see all of my application's windows with adb dumpsys window, but I'm looking for a way to do this within my application without requiring root.


Solution

  • I've found a way to do it via reflection on the @hidden WindowManagerGlobal. At least so far I know this works for android-18.

    private void logRootViews() {
        try {
            Class wmgClass = Class.forName("android.view.WindowManagerGlobal");                        
            Object wmgInstnace = wmgClass.getMethod("getInstance").invoke(null, (Object[])null);
    
            Method getViewRootNames = wmgClass.getMethod("getViewRootNames"); 
            Method getRootView = wmgClass.getMethod("getRootView", String.class);
            String[] rootViewNames = (String[])getViewRootNames.invoke(wmgInstnace, (Object[])null);
    
            for(String viewName : rootViewNames) {
                View rootView = (View)getRootView.invoke(wmgInstnace, viewName);
                Log.i(TAG, "Found root view: " + viewName + ": " + rootView);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    Output:

    Found root view: com.example.paintsample/com.example.paintsample.PaintSample/android.view.ViewRootImpl@41deeff0: com.android.internal.policy.impl.PhoneWindow$DecorView{41dcc278 V.E..... R....... 0,0-768,1184}

    Found root view: PopupWindow:42887380/android.view.ViewRootImpl@42891820: android.widget.PopupWindow$PopupViewContainer{42891450 V.E..... ........ 0,0-424,618}

    Bounty is still up for grabs of course for anyone who can find a better way :)