Returns views from the shown DecorViews. - Android User Interface

Android examples for User Interface:View Hide Show

Description

Returns views from the shown DecorViews.

Demo Code

/* Athrun - Android automation testing Framework.
 Copyright (C) 2010-2012 TaoBao UI AutoMan Team

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., HuaXing road, Hangzhou,China. 
 Email:taichan@taobao.com,shidun@taobao.com,bingyang.djj@taobao.com
 *//*from   w w  w .  j ava 2  s  .  co m*/
//package com.java2s;
import java.lang.reflect.Field;
import java.util.ArrayList;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

public class Main {
    private static Class<?> windowManager;
    private static String windowManagerString;

    /**
     * Returns views from the shown DecorViews.
     * 
     * @param onlySufficientlyVisible
     *            if only sufficiently visible views should be returned
     * @return all the views contained in the DecorViews
     * 
     */
    public static ArrayList<View> getAllViews(
            boolean onlySufficientlyVisible) {
        final View[] views = getDecorViews();
        final ArrayList<View> allViews = new ArrayList<View>();
        final View[] popupViews = getPopupViews(views);

        if (views != null && views.length > 0) {
            View view;

            for (int i = 0; i < popupViews.length; i++) {
                view = popupViews[i];

                try {
                    addChildren(allViews, (ViewGroup) view,
                            onlySufficientlyVisible);

                } catch (Exception ignored) {
                    // do nothing here
                }
            }

            view = getNormalViews(views);
            try {
                addChildren(allViews, (ViewGroup) view,
                        onlySufficientlyVisible);

            } catch (Exception ignored) {
                // do nothing here
            }
        }

        Log.i("Changju", "There are " + allViews.size()
                + " views in current screen.");
        return allViews;
    }

    public static View[] getDecorViews() {
        Object wmi;
        try {
            Field views = windowManager.getDeclaredField("mViews");
            views.setAccessible(true);
            Field instanceField = windowManager
                    .getDeclaredField(getWindowManagerString());
            instanceField.setAccessible(true);
            wmi = instanceField.get(null);
            synchronized (wmi) {
                return ((View[]) views.get(wmi)).clone();
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            // } catch (InvocationTargetException e) {
            // e.printStackTrace();
            // } catch (NoSuchMethodException e) {
            // e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        throw new RuntimeException("getWindowDecorViews() return null.");
    }

    private static final View[] getPopupViews(View[] views) {
        final View[] decorViews = new View[views.length];
        int i = 0;
        View view;

        for (int j = 0; j < views.length; j++) {
            view = views[j];
            if (!(view.getClass().getName()
                    .equals("com.android.internal.policy.impl.PhoneWindow$DecorView"))) {
                decorViews[i] = view;
                i++;
            }
        }
        return decorViews;
    }

    /**
     * Adds all children of {@code viewGroup} (recursively) into {@code views}.
     * 
     * @param views
     *            an {@code ArrayList} of {@code View}s
     * @param viewGroup
     *            the {@code ViewGroup} to extract children from
     * @param onlySufficientlyVisible
     *            if only sufficiently visible views should be returned
     * 
     */
    static void addChildren(ArrayList<View> views, ViewGroup viewGroup,
            boolean onlySufficientlyVisible) {
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            final View child = viewGroup.getChildAt(i);

            if (onlySufficientlyVisible && child.isShown()) {
                views.add(child);

            } else if (!onlySufficientlyVisible) {
                views.add(child);
            }

            if (child instanceof ViewGroup) {
                addChildren(views, (ViewGroup) child,
                        onlySufficientlyVisible);
            }
        }
    }

    private static final View getNormalViews(View[] views) {
        final View[] decorViews = new View[views.length];
        int i = 0;
        View view;

        for (int j = 0; j < views.length; j++) {
            view = views[j];
            if (view.getClass()
                    .getName()
                    .equals("com.android.internal.policy.impl.PhoneWindow$DecorView")) {
                decorViews[i] = view;
                i++;
            }
        }
        return getContainerViews(decorViews);
    }

    private static String getWindowManagerString() {
        if (windowManagerString == null) {
            if (android.os.Build.VERSION.SDK_INT >= 17) {
                windowManagerString = "sDefaultWindowManager";
            } else if (android.os.Build.VERSION.SDK_INT >= 13) {
                windowManagerString = "sWindowManager";
            } else {
                windowManagerString = "mWindowManager";
            }
        }
        return windowManagerString;
    }

    private static final View getContainerViews(View[] views) {
        View container = null;
        long drawingTime = 0;
        View view;

        for (int i = 0; i < views.length; i++) {
            view = views[i];
            if (view != null && view.isShown() && view.hasWindowFocus()
                    && view.getDrawingTime() > drawingTime) {
                container = view;
                drawingTime = view.getDrawingTime();
            }
        }
        return container;
    }
}

Related Tutorials