Detecting user inactivity and showing a pincode screen

196 Views Asked by At

I need to show a Pincode screen when the user is inactive for more than 1 minute.

I found this answer that gave me a good solution for my needs and I implemented it on my BaseActivity.

But now I am having a problem with the onUserInteraction() method, which is being called twice (and triggering my Runnable twice) everytime I press a button and start a new activity, because when I come back after 1 minute to the previous screen, the pincode screen is showing.

I've changed my Runnable to be static, but I lose the context to start the pincode activity.

What could I do to start the activity from the runnable or to make sure the onUserInteraction() is being triggered only when something is tapped on the screen?

My current code:

  public class BaseActivity {
        private static final String TAG = BaseActivity.class.getSimpleName();

    static private Handler disconnectHandler = new Handler() {
        public void handleMessage(Message msg) {
        }
    };

    private Runnable disconnectCallback = new Runnable() {
        @Override
        public void run() {
            Intent intent = new Intent(BaseActivity.this, CustomPinActivity.class);
            startActivity(intent);
        }
    };

    public void resetDisconnectTimer() {
        disconnectHandler.removeCallbacks(disconnectCallback);
        disconnectHandler.postDelayed(disconnectCallback, getResources().getInteger(R.integer.disconnect_timeout));
    }

    public void stopDisconnectTimer() {
        disconnectHandler.removeCallbacks(disconnectCallback);
    }

    @Override
    public void onUserInteraction() {
        resetDisconnectTimer();
    }

    @Override
    protected void onResume() {
        super.onResume();
        resetDisconnectTimer();
    }

    @Override
    public void onStop() {
        super.onStop();
        stopDisconnectTimer();
    }
}

Manifest:

<activity
        android:name=".CustomPinActivity"
        android:launchMode="singleTop"
        android:label="@string/title_activity_pincode" />

<activity android:name=".base.BaseActivity"
        android:launchMode="singleTop" />
1

There are 1 best solutions below

0
On

Well, I think the problem is the method onUserInteraction(). The documentation says:

All calls to your activity's onUserLeaveHint() callback will be accompanied by calls to onUserInteraction().

The link here. The documentation for onUserLeaveHint() says:

This callback and onUserInteraction() are intended to help activities manage status bar notifications intelligently; specifically, for helping activities determine the proper time to cancel a notification.

Second link here.

I understand, that onUserInteraction() method will be called each time an activity is paused, and before the pause. So I would use a flag like:

    private boolean mStartingActivity;
    private Runnable disconnectCallback = new Runnable() {
            @Override
            public void run() {
                        mStartingActivity = true;
                        Intent intent = new Intent(BaseActivity.this, CustomPinActivity.class);
                        startActivity(intent);
                    }
                };

@Override 
public void onUserInteraction() {
                    if(!mStartingActivity)
                          resetDisconnectTimer();
                }

@Override
protected void onResume() {
                    super.onResume();
                    resetDisconnectTimer();
                    mStartingActivity = false;
                }

I gess, there are more elegant solutions. I hope it helps.