@Juan is locally, and I use a timer because I just want to measure
times
This answer does not answer how to implement a timer that triggers a session closure, but how to "close" a local session by measuring the elapsed time and comparing against a predefined limit.
The solution is to save a value long
with the time returned by System.currentTimeMillis()
every time you interact with the app, and compare this value against the previous one to determine if it passed more than the time limit.
The comparison is achieved by making the difference horaInteraccionActual - horaUltimaInteracción
. The result of the difference are milliseconds so to take it to minutes you have to divide by 60000.
To preserve the value of the last interaction we can persist in SharedPreferences
.
This variable can be read in onResume()
and saved in onPause()
.
The solution is simple compared to alternatives that involve the use of a service with CountdownTimer, or using AlarmManager. And from the practical point of view what is obtained as a result is very similar: After a certain time the user can not use the app without authenticating .
The difference is that you can not notify the end of session at the end of time (5 minutes in the question), and if there is to do some closing work, it is delayed until the next user interaction. (Although this is debatable since a solution with AlarmManager may be subject to delays as well).
The activity:
public class TimedActivity extends AppCompatActivity {
private static final String APP_PREFS = "AppPrefs";
private static final String PRF_UMA_INTERACCION = "ultima_interaccion";
private static final int TIEMPO_LIMITE_MINS = 5;
private long ultimaInteraccion = -1;
private SharedPreferences prefs = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefs = getSharedPreferences(APP_PREFS, MODE_PRIVATE);
}
@Override
protected void onResume() {
super.onResume();
ultimaInteraccion = prefs.getLong(PRF_UMA_INTERACCION, -1);
}
@Override
protected void onPause() {
SharedPreferences.Editor editor = prefs.edit();
editor.putLong(PRF_UMA_INTERACCION, ultimaInteraccion);
editor.commit();
super.onPause();
}
/** Un ejemplo de interaccion **/
public void unaInteraccion(){
if(isSesionValida()){
//Ejecutar interaccion
interaccionConcretada();
}else{
cerrarSesion();
pedirLogin();
}
}
/**
* Valida que se esté en la ventana de tiempo permitida para la sesión
* @return true si se está en la ventana, y false si se está en la ventana o si no
* hay una última interacción contra que comparar
*/
private boolean isSesionValida(){
boolean rtn;
if(ultimaInteraccion == -1){
rtn = false;
}else {
long horaActual = System.currentTimeMillis();
int tiempoTranscurridoMins = (int) ((horaActual - ultimaInteraccion) / 60000);
rtn = tiempoTranscurridoMins <= TIEMPO_LIMITE_MINS;
}
return rtn;
}
/**
* Método de conveniencia para llamar cuando se quiere acutalizar la hora de la
* última interacción. Presumiblemente, después de procesar la interacción actual.
*/
private void interaccionConcretada(){
ultimaInteraccion = System.currentTimeMillis();
}
private void cerrarSesion(){
// Si el cierre de sesión requiere hacer algo más se puede hacer acá
}
private void pedirLogin(){
boolean autenticado = false;
// Pedir autenticación para abrir nuevamente una sesion.
autenticado = <resultado de la autenticación>; // true si se autentica al usuario y false si no se autentica
if(autenticado){
interaccionConcretada();
...; //Ir a pantalla principal por ejemplo
}
}
}