Auto logout after 15 minutes due to inactivity in android
Asked Answered
L

8

6

How to use timer in android for auto logout after 15 minutes due to inactivity of user?

I am using bellow code for this in my loginActivity.java

public class BackgroundProcessingService extends Service {

        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
         timer = new CountDownTimer(5 *60 * 1000, 1000) {

                public void onTick(long millisUntilFinished) {
                   //Some code
                    //inactivity = true;
                    timer.start();
                    Log.v("Timer::", "Started");
                }

                public void onFinish() {
                   //Logout
                    Intent intent = new Intent(LoginActivity.this,HomePageActivity.class);
                    startActivity(intent);
                    //inactivity = false;
                    timer.cancel();
                    Log.v("Timer::", "Stoped");
                }
             };
            return null;
        }

    }

and onclick of login button I have called intent for service.

Intent intent1 = new Intent(getApplicationContext(),
                        AddEditDeleteActivity.class);
                startService(intent1);

Please advice......

This type of error message is shown after 15 mins

This type of error message is shown after 15 mins

Leucas answered 6/11, 2012 at 5:26 Comment(6)
I believe you are looking for inactivity, rather than anactivityYulma
@Yulma yes its inactivity.Leucas
start a service and start a timer in it and handle your session there.Piling
@Yulma I have edited my code please advice.....Leucas
Best practice is to use alarmmanager or handler.Chrestomathy
There is a library I developed to help with this use case. Please feel free to take a look. github.com/jose96043/TimezOutSubstratosphere
D
10

Use CountDownTimer

CountDownTimer timer = new CountDownTimer(15 *60 * 1000, 1000) {

        public void onTick(long millisUntilFinished) {
           //Some code
        }

        public void onFinish() {
           //Logout
        }
     };

When user has stopped any action use timer.start() and when user does the action do timer.cancel()

Dextrorotation answered 6/11, 2012 at 5:32 Comment(6)
@Leucas The Ibinder is used for inter process communication place the codein startservice() method of service. Here are some tutorial for service vogella.com/articles/AndroidServices/article.html and when timer ends i.e. on the onFinish() method call the stopself() to stop the service and do what you need to do in thatDextrorotation
@Leucas The above was if you need to use a service but i dont think you need to use a service for my code that i had suggested it works in a different thread by default. In place of startService(intent1); you can use the timer.start() to start the timerDextrorotation
thanks its working but it gives message to close app.If I said OK then it is displaying home page.what to do for changing that message? and I want this on my remaining activities,What to do?please advice...thanks in advance....Leucas
To make it accessible by all activities make it public static CountDownTimer timer and you can use staticly and tell me what gives a message, I am not able to understand you ??Dextrorotation
I have attached screenshot of error message.If I press ok then it take me on my homepage.I dont want that type of message.It will automatically take me on homepage after 15 mins.but this will happen only if my app is ideal or no one is working on it,even I am working on it it gives this message.Leucas
This is an ANR error, its because main thread is not responding. Read this developer.android.com/guide/practices/responsiveness.html Do all network operation in some other thread rather than the Main ThreadDextrorotation
J
5

I am agree with Girish in above answer. Rash for your convenience i am sharing code with you.

public class LogoutService extends Service {
        public static CountDownTimer timer;
    @Override
    public void onCreate(){
        super.onCreate();
          timer = new CountDownTimer(1 *60 * 1000, 1000) {
                public void onTick(long millisUntilFinished) {
                   //Some code
                    Log.v(Constants.TAG, "Service Started");
                }

                public void onFinish() {
                    Log.v(Constants.TAG, "Call Logout by Service");
                    // Code for Logout
                    stopSelf();
                }
             };
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

Add the following code in every activity.

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

    LogoutService.timer.start();
}

@Override
protected void onStop() {
    super.onStop();
    LogoutService.timer.cancel();
}   
Jinnyjinrikisha answered 27/3, 2014 at 7:45 Comment(5)
Is this Service is exported and enabled in Manifest.xml. ?Antagonize
I am getting NullPointerException at LogoutService.timer.start()Antagonize
@XoXo - Declare this service in AndroidManifest.xml with enable=trueSogdiana
This code will logout user even if user is active on app. and you stop timer at onStop(). what about app is in background, user will never be logout if app is in background?Crockery
This code was close but didn't work for me while using startActivityForResult(..., ...) and closing out activities when I was done with them using finish(). The onStop() method would get called after the onResume method of the previous or next activity, so it would start it up and end it immediately. What I found was I didn't need to cancel it at all, just start it over and over again and it resets the timer to the top each time.Shun
T
4

First Create Application class.

public class App extends Application{

   private static LogoutListener logoutListener = null;
   private static Timer timer = null;

   @Override
   public void onCreate() {
       super.onCreate();
   }


   public static void userSessionStart() {
           if (timer != null) {
               timer.cancel();
           }
           timer = new Timer();
           timer.schedule(new TimerTask() {
               @Override
               public void run() {
                   if (logoutListener != null) {
                       logoutListener.onSessionLogout();
                       log.d("App", "Session Destroyed");
                   }
               }
           },  (1000 * 60 * 2) );
       }

       public static void resetSession() {
           userSessionStart();
       }

       public static void registerSessionListener(LogoutListener listener) {
           logoutListener = listener;
       }
}

This App Class add into manifest

<application
       android:name=".App"
       android:allowBackup="false"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:roundIcon="@mipmap/ic_launcher_round"
       android:supportsRtl="true"
       android:usesCleartextTraffic="true"
       android:theme="@style/AppTheme">
       <activity android:name=".view.activity.MainActivity"/>

</application>

Then Create BaseActivity Class that is use in whole applications

class BaseActivity extends AppCompatActivity implements LogoutListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //setTheme(App.getApplicationTheme());
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //Set Listener to receive events
        App.registerSessionListener(this);
    }

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
        //reset session when user interact
        App.resetSession();

    }

    @Override
    public void onSessionLogout() {
        // Do You Task on session out
    }

}

After that extend Base activity in another activity

public class MainActivity extends BaseActivity{

    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
Trilateral answered 4/5, 2020 at 9:40 Comment(4)
You save my day.Kaycekaycee
Great solution. But imagine this scenario: I launch the MainActivity and don't do anything afterwards. Will I still receive the onSessionLogout callback in BaseActivity after the 2mins have elapsed? I think you should also call App.resetSession(); in the onCreate of BaseActivity.Visual
Missing LogoutListenerInternational
public interface LogoutListener { void onSessionLogout(); }International
N
1

You can start a service and start a timer in it. Every 15 minutes, check if a flag, let's say inactivity flag is set to true. If it is, logout form the app.

Every time the user interacts with your app, set the inactivity flag to false.

Natter answered 6/11, 2012 at 5:33 Comment(0)
A
1

you may need to create a BaseActivity class which all the other Activities in your app extend. in that class start your timer task (TimerTask()) in the onUserInteraction method:

override fun onUserInteraction() {
    super.onUserInteraction()
    onUserInteracted()
}

. The onUserInteracted class starts a TimerTaskService which will be an inner class for my case as below:

private fun onUserInteracted() {
     timer?.schedule(TimerTaskService(), 10000)
}

The TimerTaskService class will be asfollows. Please note the run on UI thread in the case you want to display a DialogFragment for an action to be done before login the user out:

inner class TimerTaskService : TimerTask() {
    override fun run() {
        /**This will only run when application is in background
         * it allows the application process to get high priority for the user to take action
         * on the application auto Logout
         * */
//            val activityManager = applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
//            activityManager.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_NO_USER_ACTION)

        runOnUiThread {
            displayFragment(AutoLogoutDialogFragment())
            isSessionExpired = true
        }
        stopLoginTimer()
    }
}

You will realise i have a stopTimer method which you have to call after the intended action has be envoked, this class just has timer?.cancel() and you may also need to include it in the onStop() method.

NB: this will run in 10 seconds because of the 10000ms

Ardoin answered 22/3, 2018 at 15:37 Comment(0)
T
1

Use the build-in function called: onUserInteraction() like below:

  @Override
public void onUserInteraction() {
    super.onUserInteraction();
    stopHandler();  //first stop the timer and then again start it
    startHandler();
}
Topmost answered 28/5, 2020 at 7:15 Comment(0)
D
0

I hope this will help

I found it on github https://gist.github.com/dseerapu/b768728b3b4ccf282c7806a3745d0347

public class LogOutTimerUtil {

 public interface LogOutListener {
  void doLogout();
 }

 static Timer longTimer;
 static final int LOGOUT_TIME = 600000; // delay in milliseconds i.e. 5 min = 300000 ms or use timeout argument

 public static synchronized void startLogoutTimer(final Context context, final LogOutListener logOutListener) {
  if (longTimer != null) {
   longTimer.cancel();
   longTimer = null;
  }
  if (longTimer == null) {

   longTimer = new Timer();

   longTimer.schedule(new TimerTask() {

    public void run() {

     cancel();

     longTimer = null;

     try {
      boolean foreGround = new ForegroundCheckTask().execute(context).get();

      if (foreGround) {
       logOutListener.doLogout();
      }

     } catch (InterruptedException e) {
      e.printStackTrace();
     } catch (ExecutionException e) {
      e.printStackTrace();
     }

    }
   }, LOGOUT_TIME);
  }
 }

 public static synchronized void stopLogoutTimer() {
  if (longTimer != null) {
   longTimer.cancel();
   longTimer = null;
  }
 }

 static class ForegroundCheckTask extends AsyncTask < Context, Void, Boolean > {

  @Override
  protected Boolean doInBackground(Context...params) {
   final Context context = params[0].getApplicationContext();
   return isAppOnForeground(context);
  }

  private boolean isAppOnForeground(Context context) {
   ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
   List < ActivityManager.RunningAppProcessInfo > appProcesses = activityManager.getRunningAppProcesses();
   if (appProcesses == null) {
    return false;
   }
   final String packageName = context.getPackageName();
   for (ActivityManager.RunningAppProcessInfo appProcess: appProcesses) {
    if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
     return true;
    }
   }
   return false;
  }
 }

}

Use above code in Activity as below :

public class MainActivity extends AppCompatActivity implements LogOutTimerUtil.LogOutListener
{
    @Override
    protected void onStart() {
        super.onStart();
        LogOutTimerUtil.startLogoutTimer(this, this);
        Log.e(TAG, "OnStart () &&& Starting timer");
    }

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
        LogOutTimerUtil.startLogoutTimer(this, this);
        Log.e(TAG, "User interacting with screen");
    }


    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "onPause()");
    }

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

        Log.e(TAG, "onResume()");
    }

    /**
     * Performing idle time logout
     */
    @Override
    public void doLogout() {
      // write your stuff here
    }
}
Dated answered 13/7, 2018 at 12:41 Comment(0)
S
0
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
    ev?.let { event ->
        if (event.action == ACTION_DOWN) {
            //start counting user's inactivity
            //or launch a coroutine with delay before logout
        }
    }
    return super.dispatchTouchEvent(ev)
}
Siemens answered 31/7, 2023 at 16:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.