How to check if any system dialog
(like the one below or USSD) is displayed in Android ?
Programmatic way or cmd root way? Any variants.
How to check if any system dialog
(like the one below or USSD) is displayed in Android ?
Programmatic way or cmd root way? Any variants.
You can theoretically do this using the AccessibilityService
, but it is rather complicated and may or may not work on different devices. Users will need to manually enable accessibility features for your application. You can get callbacks from Android whenever any window is opened and you can then interrogate the window to determine if it has specific text in it or belongs to a specific package, etc. This is a "brute force" approach, but it can be useful in some situations.
A system dialog is an activity. You can detect it by the top activity class name using ActivityManager.
final ActivityManager manager = (ActivityManager) context
.getSystemService(Activity.ACTIVITY_SERVICE);
In devices with API Level less than 23 (M):
final List<ActivityManager.RunningTaskInfo> runningTasks = manager.getRunningTasks(1);
final ComponentName componentName = runningTasks.get(0).topActivity;
final String className = componentName.getClassName();
if (className.equals("YOUR_EXPECTED_ACTIVITY_CLASS_NAME")) {
// do something
}
In newer devices:
final List<ActivityManager.AppTask> appTasks = manager.getAppTasks();
final ComponentName componentName = appTasks.get(0).getTaskInfo().topActivity;
final String className = componentName.getClassName();
if (className.equals("YOUR_EXPECTED_ACTIVITY_CLASS_NAME")) {
// do something
}
Or in this case, you can check if the device is in airplane mode before starting the activity:
private boolean isAirplaneModeOn(final Context context) {
final int airplaneMode = Settings.System.getInt(
context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON,
0
);
return airplaneMode != 0;
}
...
if (!isAirplaneModeOn(this)) {
// do something
}
Your question made me think of a solution in use by the permissions management in Android 6+. Have you ever seen the error message if a Toast or system alert dialog opens up when trying to set permissions? Android "Screen Overlay Detected" message if user is trying to grant a permission when a notification is showing
The way they did it is by overriding the dispatchTouchEvent
method in Activity
. This can check if anything is 'in the way' intercepting touch events. You can use your special Activity as a base class for any Activity in your app that you wish to detect any overlays on it.
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
mObscured = (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0;
return super.dispatchTouchEvent(event);
}
Add a public method to check at any given time if your activity is obscured
public boolean isObscured() {
return mObscured;
}
You should be careful - as it's not clear from the question - if a second Activity from a system or privileged app is at the front of the stack then your own activity will no longer be receiving touch events. This is to capture the fragments, toasts, floating widgets and other items that may share the view hierarchy.