How to detect when my Activity has been obscured?

2019-04-14 16:05发布

问题:

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?

回答1:

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.



回答2:

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