I would like to be able to detect if my Activity has been obscured by, say, a system alert or some other overlay (for example the power menu when I long press on the power button), or some malware that detects the launch of my Activity. I noticed that the foreground app in this case would still be my app, so I can't simply base it on what the foreground app is. I also notice that onPause() isn't called when my Activity is obscured, so I can't put any logic in onPause() either. Even if I can though, I would then have to differentiate between a system alert/overlay and the user pressing the back/home button.
Are there any other ways for me to accomplish this?
You can check if Activity, Fragment or View is Obscured.
For Activity you need override dispatchTouchEvent method and check if event has flag FLAG_WINDOW_IS_OBSCURED. There is example code:
public class OverlayTouchActivity extends Activity {
private boolean mObscuredTouch;
public boolean isObscuredTouch() {
return mObscuredTouch;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
mObscuredTouch = (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0;
return super.dispatchTouchEvent(event);
}
}
This is a part of Android code, please check OverlayTouchActivity.java. In order to check if Fragment is obscured, execute the following piece of code in Fragment that belongs to the OverlayTouchActivity activity:
OverlayTouchActivity activity = (OverlayTouchActivity) getActivity();
if (activity.isObscuredTouch()) {
// Fragment is bbscured
}
Please see AppPermissionsFragment.java fragment (search for OverlayTouchActivity).
For View you should override onFilterTouchEventForSecurity method. For more information please see security section of View documentation.
You can use the PackageManager to query whose of the installed packages has suspect permissions like SYSTEM_ALERT_WINDOW, BIND_ACCESSIBILITY_SERVICE or BIND_DEVICE_ADMIN.
Some code ideas