1

My app will be running in the background and will alert the user if he isn't active on the device after 10 seconds. I cannot use the following method since the screen is supposed to be kept on all the time.

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();

Another method I found is overriding OnUserInteraction() on activity. But it seem to only work on our app's activity. What I want is to know if the user is interacting even if the app is not in foreground ie, there's no user interface. Is there any specific method to do this without using the screen timeout? Is it possible to know if my device is inactive using a service?

AruN
  • 171
  • 4
  • 15
  • You'll have to use a foreground service. – Darshan Feb 19 '20 at 06:28
  • @DarShan can you elaborate? – AruN Feb 19 '20 at 07:10
  • @AruN Possible duplicate of you requirement https://stackoverflow.com/a/36171929/6280156 – Ankit Tale Feb 19 '20 at 07:17
  • @Venky, I guess not, it seems we can only call onUserInteraction() while we are on our own app's activity. What I want is to know if the user is interacting even if the app is not in foreground. I'll edit and add this in question for avoiding further confusion. – AruN Feb 19 '20 at 07:19
  • May be possible using [`UsageStatsManager`](https://developer.android.com/reference/android/app/usage/UsageStatsManager). – greeble31 Feb 20 '20 at 12:19

1 Answers1

0

Well I found a way myself, thanks for the suggestions guys. Use a Service which sets up an overlay using WindowManager with LayoutParams(0,0,0,0) and then use WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH flag. This will return a MotionEvent called OUTSIDE_TOUCH, Which helped me to detect touch anywhere on screen even if my app isn't on foreground.

int overlayType = Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_SYSTEM_ALERT : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                0, 0, 0, 0,
                overlayType,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);
        wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        touchListenerView = new View(this);
        touchListenerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                handleInactive(event);
                return false;
            }
        });
        wm.addView(touchListenerView, params);

I am able to use this and a handler.postDelayed() to find out if my device is active or inactive within a specific time.

AruN
  • 171
  • 4
  • 15