Sometimes we need to log out the user or expire his session if he did not perform any interaction with the app for 5 minutes or even If he locks the screen from the lock button. This can be implemented very easily by maintaining a thread(Waiter) which will give alert once 5 minutes are over after last user interaction.
First, create a file AppLockManager like this.
public class ApplockManager { private static ApplockManager instance; private DefaultApplock currentAppLocker; public static ApplockManager getInstance() { if (instance == null) { instance = new ApplockManager(); } return instance; } public void enableDefaultAppLockIfAvailable(Application currentApp) { currentAppLocker = new DefaultApplock(currentApp); } public void updateTouch(){ currentAppLocker.updateTouch(); } }
Then create a file DefaultApplock by extending ActivityLifeCycleCallbacks this will provides with lifecycle methods like onActivityResume and onActivityPause etc.
public class DefaultApplock implements Application.ActivityLifecycleCallbacks { final String TAG = DefaultApplock.class.getSimpleName(); private Application mCurrentApp; private long WAIT_TIME = 5*60*1000; private Waiter waiter; private Date mLostFocusDate; public DefaultApplock(Application app) { super(); mCurrentApp = app; //Registering Activity lifecycle callbacks mCurrentApp.unregisterActivityLifecycleCallbacks(this); mCurrentApp.registerActivityLifecycleCallbacks(this); } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { // for UserInactivity if(waiter!=null) { waiter.stopThread(); } waiter=new Waiter(activity,WAIT_TIME); waiter.start(); // for Screen lock if (shouldShowUnlockScreen()) { Log.d(TAG, "time over"); // Intent intent = new Intent(activity.getApplicationContext(), ActivitySplashScreen.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); Log.d(TAG, "changing mLostFocus to null"); mLostFocusDate = null; activity.getApplicationContext().startActivity(intent); } } private boolean shouldShowUnlockScreen() { Boolean isvalid = false; if (mLostFocusDate == null) { isvalid = false; } else { Log.d(TAG, "Timeout ->"+timeSinceLocked()); if (timeSinceLocked() >= (WAIT_TIME/1000)) { isvalid = true; } else { mLostFocusDate = null; } } Log.d(TAG, isvalid.toString()); return isvalid; } private int timeSinceLocked() { return Math.abs((int) ((new Date().getTime() - mLostFocusDate.getTime()) / 1000)); } @Override public void onActivityPaused(Activity activity) { if(waiter!=null) { waiter.stopThread(); } mLostFocusDate = new Date(); } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { } public void updateTouch() { if(waiter!=null) { waiter.touch(); } mLostFocusDate = new Date(); } }
Now Create a Waiter thread which will keep a record of the time that is elapsed after the last user interaction and will provide an alert once that time exceeds 5 minutes.
public class Waiter extends Thread { private static final String TAG=Waiter.class.getName(); private long lastUsed; private long period; private boolean stop = false; private Context mContext; public Waiter(Context context,long period) { this.period=period; stop=false; mContext = context; } public void run() { long idle=0; this.touch(); Log.d("Value of stop",String.valueOf(stop)); do { idle=System.currentTimeMillis()-lastUsed; // Log.d(TAG, "Application is idle for "+idle +" ms"); try { Thread.sleep(2000); //check every 5 seconds } catch (InterruptedException e) { Log.d(TAG, "Waiter interrupted!"); } if(idle > period) { idle=0; //do something here - e.g. call popup or so // Perform Your desired Function like Logout or expire the session for the app. stopThread(); } } while(!stop); Log.d(TAG, "Finishing Waiter thread"); } public synchronized void touch() { lastUsed=System.currentTimeMillis(); } public synchronized void forceInterrupt() { this.interrupt(); } public synchronized void setPeriod(long period) { this.period=period; } public synchronized void stopThread() { stop = true; } public synchronized void startThread() { stop = false; } public synchronized void closeThread() { // Perform Your desired Function like Logout or expire the session for the app. stopThread(); } }
Now in your base activity Override UserInteraction Method to update the timer for the waiter thread. In this method we will start the timer every time user perform any interaction with the app. getApp() function will be used to get applicationContext().
public ABFSApplication getApp() { return (ABFSApplication) this.getApplication(); } @Override public void onUserInteraction() { super.onUserInteraction(); getApp().touch(); Log.d("TAG", "User interaction to " + this.toString()); }
Now lastly in your application file write this method touch to update userInteraction.
public void touch() { ApplockManager.getInstance().updateTouch(); }
Please do subscribe email to get all newsletters of this blog and if you feel that this post will help you to understand then do not forget to subscribe, share and comment below.
I am a very enthusiastic Android developer who develops applications for devices powered by the Android operating system. I keep myself updated with the latest technologies available in Android.
Hi everyone, In this article, we are going to learn how to hide the production… Read More
Hello everyone, Today in this article, we are going to learn about localisation to support… Read More
Hello everyone, In this article, we are going to learn something to handle the callback… Read More
In this article, we are learning about the run time permissions for request permission launchers.… Read More
Hello everyone. In my last tutorial, we learned about the Jetpack Compose introduction and about applying the… Read More
Hello everyone, In this article, we are going to learn about the Jetpack Compose with… Read More