Esto usa reflexión y API ocultas para obtener las raíces de vista actualmente activas. Si un cuadro de diálogo de alerta muestra esto, se devolverá una raíz de vista adicional. Pero cuidado ya que incluso una ventana emergente de pan tostado devolverá una raíz de vista adicional.
He confirmado la compatibilidad de Android 4.1 a Android 6.0 pero, por supuesto, esto puede no funcionar en versiones de Android anteriores o posteriores.
No he comprobado el comportamiento de los modos de ventanas múltiples.
@SuppressWarnings("unchecked")
public static List<ViewParent> getViewRoots() {
List<ViewParent> viewRoots = new ArrayList<>();
try {
Object windowManager;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
windowManager = Class.forName("android.view.WindowManagerGlobal")
.getMethod("getInstance").invoke(null);
} else {
Field f = Class.forName("android.view.WindowManagerImpl")
.getDeclaredField("sWindowManager");
f.setAccessible(true);
windowManager = f.get(null);
}
Field rootsField = windowManager.getClass().getDeclaredField("mRoots");
rootsField.setAccessible(true);
Field stoppedField = Class.forName("android.view.ViewRootImpl")
.getDeclaredField("mStopped");
stoppedField.setAccessible(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
List<ViewParent> viewParents = (List<ViewParent>) rootsField.get(windowManager);
// Filter out inactive view roots
for (ViewParent viewParent : viewParents) {
boolean stopped = (boolean) stoppedField.get(viewParent);
if (!stopped) {
viewRoots.add(viewParent);
}
}
} else {
ViewParent[] viewParents = (ViewParent[]) rootsField.get(windowManager);
// Filter out inactive view roots
for (ViewParent viewParent : viewParents) {
boolean stopped = (boolean) stoppedField.get(viewParent);
if (!stopped) {
viewRoots.add(viewParent);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return viewRoots;
}
¿Qué biblioteca de terceros está utilizando y qué tipo de aplicación está trabajando? –