In this tip, I will provide the way to call a method (logout) when user inactivity in 5 minutes. Depending on the specific case, you can add more operations with your own requirements.
Detecting user inactivity
Activity
is not visible with user, onPause()
and onStop()
were called and when user reopen the Activity
, onStart()
and onResume()
were invoked! We will rely on this life cycle to solve this problem. The solution is: if onPause()
was called and after 5 minutes, onResume()
is not being called, we will logout and redirect user to login screen.
java.util.Timer and the sample code
Timer
and TimerTask
are 2 objects will be used to resolve problem. We initialize a Timer
instance in onPause()
and schedule a TimerTask
(will be invoked after 5 minutes (300,000ms)) and in onResume()
, we must cancel this Timer
instance!
Source code for our activity:
MainActivity.java
And it's layout:
package vn.ecpay.autologout;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
private Timer timer;
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
protected void onPause() {
super.onPause();
timer = new Timer();
Log.i("Main", "Invoking logout timer");
LogOutTimerTask logoutTimeTask = new LogOutTimerTask();
timer.schedule(logoutTimeTask, 300000); //auto logout in 5 minutes
}
@Override
protected void onResume() {
super.onResume();
if (timer != null) {
timer.cancel();
Log.i("Main", "cancel timer");
timer = null;
}
}
private class LogOutTimerTask extends TimerTask {
@Override
public void run() {
//redirect user to login screen
Intent i = new Intent(MainActivity.this, LoginActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
}
}
}
activity_mian.xml
That is the main screen, we'll reach here after login, so this is a simple example of a login activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="vn.ecpay.autologout.MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:gravity="center"
android:padding="@dimen/activity_horizontal_margin"
android:text="Hi, friend! You logged in, after 5 minutes inactivity, you will be logout!" />
</LinearLayout>
LoginActivity.java
Login screen layout:
package vn.ecpay.autologout;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
public class LoginActivity extends AppCompatActivity {
private TextInputLayout userName;
private TextInputLayout password;
private View btnLogin;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
userName = (TextInputLayout) findViewById(R.id.username_field);
password = (TextInputLayout) findViewById(R.id.pass_field);
btnLogin = findViewById(R.id.btn_login);
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (userName.getEditText().getText().toString().trim().equals("")) {
Toast.makeText(LoginActivity.this, "Please input your user name", Toast.LENGTH_SHORT).show();
} else if (password.getEditText().getText().toString().trim().equals("")) {
Toast.makeText(LoginActivity.this, "Please input your password", Toast.LENGTH_SHORT).show();
} else if (userName.getEditText().getText().toString().equals("devexchanges") &&
password.getEditText().getText().toString().equals("admin")) {
//Correct user name and password, go to main screen
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(LoginActivity.this, "Wrong input data", Toast.LENGTH_SHORT).show();
}
}
});
}
}
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/activity_horizontal_margin">
<android.support.design.widget.TextInputLayout
android:id="@+id/username_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/pass_field">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="User name"
android:inputType="text" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/pass_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login"
android:layout_marginTop="@dimen/activity_horizontal_margin"
android:layout_below="@+id/pass_field" />
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vn.ecpay.autologout">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="@string/app_name" />
</application>
</manifest>
Important Note
: I used TextInputLayout
in login activity - a widget from Design Support Library, so you must add it's dependency to your app/build.gradle
:
compile 'com.android.support:design:23.4.0'
Running application, we have this output:
Click login, we will go to main screen:
And if you click home button (to go home screen - close app) or the screen light turn off, after 5 minutes, unless reactivating your app, you will be auto redirect to the login screen!
Final thoughts
onUserInteraction()
method (reset "countdown time" when this method called). Some links in Stackoverflow you can take a glance:- http://stackoverflow.com/questions/4208730/how-to-detect-user-inactivity-in-android
- http://stackoverflow.com/questions/25018539/how-to-detect-user-inactivity
- http://stackoverflow.com/questions/5689591/android-best-way-to-detect-and-handle-user-inactivity