This example will show you how to implement force logout when same user account login in another instance of same android app. It will use both android activity, service and broadcast receiver components to implement.
1. Android Force Logout Example.
Let us see the example demo first. There are two android apps ( App One and App Two ) running in same android emulator with same function. Each app provide a login form activity, after login it will direct user to dashboard activity.
When user dashboard activity is created, it will start a background service. The background service will register a broadcast receiver when it is created.
The broadcast receiver will response broadcast sent from other apps when user login in those apps.
In user login activity, if user input wrong username and password, there will popup a toast message at bottom to let user input again.
If user input correct username and password in App One login activity, it will send a custom normal broadcast to notify App Two that same user account login in App One.
App Two’s broadcast receiver which registered in background service will receive the another login broadcast. Then it will logout and show login activity again in App Two.
2. Android Force Logout Source Code.
To run the example, you need to open two android studio and run two example project. The two project has same java file. The two apps should run in same android emulator.
2.1 Base Activity Java File.
BaseActivity is the base class which login activity and dashboard activity extends. It’s child activity will be managed by a util class ActivityManagerUtil.
BaseActivity.java
package com.dev2qa.example.broadcast.activity.forceoffline; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import com.dev2qa.example.broadcast.receiver.forceoffline.ForceOfflineReceiver; import com.dev2qa.example.util.ActivityManagerUtil; /** * Created by Jerry on 1/7/2018. */ public class BaseActivity extends AppCompatActivity { private ForceOfflineReceiver forceOfflineReceiver; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Add this activity to a central activity controller. ActivityManagerUtil.addActivity(this); } @Override protected void onDestroy() { super.onDestroy(); // Remove current activity from central activity controller. ActivityManagerUtil.finishActivity(this); } }
ActivityManagerUtil.java
package com.dev2qa.example.util; import android.app.Activity; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.util.Log; import java.util.ArrayList; import java.util.List; /** * Created by Jerry on 12/11/2017. */ public class ActivityManagerUtil { // This list is used to save all activities. private static List<Activity> activityList = new ArrayList<Activity>(); // Add an activity in activityList. public static void addActivity(Activity activity) { if(activityList==null) { activityList = new ArrayList<Activity>(); } if(activity!=null) { activityList.add(activity); } } // Finish and remove an activity from activityList. public static void finishActivity(Activity activity) { if(activityList!=null) { if(activity!=null && activityList.contains(activity)) { activity.finish(); activityList.remove(activity); } } } // Finish and remove all activity in activityList. public static void finishAllActivity() { if(activityList!=null) { // First finish all the activity in the list. int size = activityList.size(); for(int i=0;i<size;i++) { Activity activity = activityList.get(i); activity.finish(); } // Then remove all the activity in the list. for(int i=0;i<size;i++) { activityList.remove(i); } } } }
2.2 Login Activity Java File.
LoginFormActivity.java
package com.dev2qa.example.broadcast.activity.forceoffline; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.dev2qa.example.R; import com.dev2qa.example.broadcast.receiver.forceoffline.ForceOfflineReceiver; public class LoginFormActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login_form); setTitle("App One. dev2qa.com - Android Force Offline Login Example."); final EditText userNameEditor = (EditText)findViewById(R.id.force_offline_login_username); final EditText passwordEditor = (EditText)findViewById(R.id.force_offline_login_password); Button loginButton = (Button)findViewById(R.id.force_offline_login_button); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String userName = userNameEditor.getText().toString(); String password = passwordEditor.getText().toString(); if("dev2qa.com".equalsIgnoreCase(userName) && "dev2qa.com".equalsIgnoreCase(password)) { // User account is correct. // Send a broadcast to let already login user force logoff. Intent forceLogoffIntent = new Intent(ForceOfflineReceiver.ACTION_FORCE_OFFLINE); sendBroadcast(forceLogoffIntent); // Start login dashboard activity. Intent intent = new Intent(getApplicationContext(), LoginDashboardActivity.class); startActivity(intent); // Finish current activity. finish(); }else { // User account is not correct, show a toast popup message. Toast.makeText(getApplicationContext(), "User name or password is not correct, please input again.", Toast.LENGTH_LONG).show(); } } }); } }
2.3 Dashboard Activity Java File.
LoginDashboardActivity.java
package com.dev2qa.example.broadcast.activity.forceoffline; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import com.dev2qa.example.R; import com.dev2qa.example.broadcast.service.forceoffline.LoginBackgroundService; public class LoginDashboardActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login_dashboard); setTitle("App One. dev2qa.com - User Dashboard Activity"); // Start a login background service to process user login force logoff action. Intent backgroundService = new Intent(getApplicationContext(), LoginBackgroundService.class); startService(backgroundService); } }
2.4 Background Service Java File.
LoginBackgroundService.java
package com.dev2qa.example.broadcast.service.forceoffline; import android.app.Service; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.support.annotation.Nullable; import com.dev2qa.example.broadcast.receiver.forceoffline.ForceOfflineReceiver; /** * Created by Jerry on 1/7/2018. */ public class LoginBackgroundService extends Service { private ForceOfflineReceiver forceOfflineReceiver; @Override public void onCreate() { super.onCreate(); // When service object is created, register a custom broadcast receiver. // So that this activity can process ACTION_FORCE_OFFLINE custom broadcast. forceOfflineReceiver = new ForceOfflineReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ForceOfflineReceiver.ACTION_FORCE_OFFLINE); registerReceiver(forceOfflineReceiver, intentFilter); } @Override public void onDestroy() { super.onDestroy(); // When service object destroy, unregister the force offline receiver. if(forceOfflineReceiver!=null) { unregisterReceiver(forceOfflineReceiver); forceOfflineReceiver = null; } } @Nullable @Override public IBinder onBind(Intent intent) { return null; } }
2.5 Force Offline Broadcast Receiver Java File.
ForceOfflineReceiver.java
package com.dev2qa.example.broadcast.receiver.forceoffline; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; import com.dev2qa.example.broadcast.activity.forceoffline.LoginFormActivity; import com.dev2qa.example.util.ActivityManagerUtil; /** * Created by Jerry on 1/7/2018. */ public class ForceOfflineReceiver extends BroadcastReceiver { public static final String ACTION_FORCE_OFFLINE = "com.dev2qa.example.broadcast.receiver.ACTION_FORCE_OFFLINE"; @Override public void onReceive(final Context context, Intent intent) { // Get intent action value. String action = intent.getAction(); // If force offline action. if(ACTION_FORCE_OFFLINE.equals(action)) { Toast.makeText(context, "This account login in another device, you need login again", Toast.LENGTH_LONG).show(); // Finish all activity. ActivityManagerUtil.finishAllActivity(); // Start the login form activity to let user login again. Intent loginFormIntent = new Intent(context, LoginFormActivity.class); context.startActivity(loginFormIntent); } } }
2.6 Login Activity Layout Xml File.
activity_login_form.xml
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="User Name :"/> <EditText android:id="@+id/force_offline_login_username" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="3" android:hint="Input user name."/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Password :"/> <EditText android:id="@+id/force_offline_login_password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="3" android:hint="Input password." android:password="true"/> </LinearLayout> <Button android:id="@+id/force_offline_login_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Login"/> </LinearLayout>
2.7 User Dashboard Layout Xml File.
activity_login_dashboard.xml
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="Welcom to user dashboard after login." android:textSize="20dp"/>
2.8 Android Manifest Xml File.
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.dev2qa.example"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".broadcast.activity.forceoffline.LoginFormActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".broadcast.activity.forceoffline.LoginDashboardActivity"></activity> <service android:name=".broadcast.service.forceoffline.LoginBackgroundService" android:enabled="true" /> </application> </manifest>