强制下线功能比较常见,很多应用程序都具备这个功能。例如你的QQ号在别处登录了,就会将你强制挤下线。其实实现强行挤下线的思路很简单,只需要在界面上弹出一个对话框,让用户无法进行其他操作。必须要点到对话框中的确定按钮,然后回到登录界面即可。
1.强制下线功能需要先关闭所有的活动,然后回到登录界面,此时我们先建一个ActivityCollector类用于管理所有活动的功能:

1 package com.example.myapplication; 2 3 import android.app.Activity; 4 5 import java.util.ArrayList; 6 import java.util.List; 7 8 public class ActivityCollector { 9 public static List<Activity> activitys=new ArrayList<>();//存放活动的集合 10 //添加活动 11 public static void addActivity(Activity activity){ 12 activitys.add(activity); 13 } 14 //移除活动 15 public static void remove(Activity activity){ 16 activitys.remove(activity); 17 } 18 //关闭所有活动 19 public static void finshAll(){ 20 for(Activity activity:activitys){ 21 if(!activity.isFinishing()){ 22 activity.finish(); 23 } 24 } 25 activitys.clear(); 26 } 27 }
2.然后创建一个BaseActivity类作为所有活动的父类,此父类会动态注册一个广播接收器:
1 package com.example.myapplication; 2 3 import android.content.BroadcastReceiver; 4 import android.content.ComponentName; 5 import android.content.Context; 6 import android.content.DialogInterface; 7 import android.content.Intent; 8 import android.content.IntentFilter; 9 import android.os.Bundle; 10 import android.view.WindowManager; 11 12 import androidx.annotation.Nullable; 13 import androidx.appcompat.app.AlertDialog; 14 import androidx.appcompat.app.AppCompatActivity; 15 16 public class BaseActivity extends AppCompatActivity { 17 private ForceOfflineReceiver receiver; 18 19 @Override 20 protected void onResume() { 21 super.onResume(); 22 //注册广播 23 IntentFilter intentFilter=new IntentFilter(); 24 intentFilter.addAction("com.example.My Application.FORCE_OFFLINE"); 25 receiver=new ForceOfflineReceiver(); 26 registerReceiver(receiver,intentFilter); 27 } 28 29 @Override 30 protected void onPause() { 31 super.onPause(); 32 if(receiver!=null){ 33 unregisterReceiver(receiver); 34 receiver=null; 35 } 36 } 37 38 @Override 39 protected void onCreate(@Nullable Bundle savedInstanceState) { 40 super.onCreate(savedInstanceState); 41 ActivityCollector.addActivity(this); 42 } 43 @Override 44 protected void onDestroy() { 45 super.onDestroy(); 46 ActivityCollector.remove(this); 47 } 48 49 class ForceOfflineReceiver extends BroadcastReceiver{ 50 51 @Override 52 public void onReceive(final Context context, Intent intent) { 53 AlertDialog.Builder builder=new AlertDialog.Builder(context); 54 builder.setTitle("警告"); 55 builder.setMessage("你被迫下线,请再次登录!"); 56 builder.setCancelable(false); 57 builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 58 @Override 59 public void onClick(DialogInterface dialog, int which) { 60 ActivityCollector.finshAll();//销毁所有活动 61 Intent i=new Intent(context,LoginActivity.class); 62 startActivity(i);//重新启动登录界面 63 } 64 }); 65 AlertDialog alertDialog=builder.create(); 66 alertDialog.show(); 67 68 } 69 } 70 }
3.登录界面activity_login.xml

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <LinearLayout 8 android:orientation="horizontal" 9 android:layout_width="match_parent" 10 android:layout_height="60dp"> 11 <TextView 12 android:layout_width="90dp" 13 android:layout_height="wrap_content" 14 android:layout_gravity="center_vertical" 15 android:textSize="18sp" 16 android:text="用户名:"/> 17 <EditText 18 android:id="@+id/username" 19 android:layout_width="0dp" 20 android:layout_height="wrap_content" 21 android:layout_weight="1" 22 android:layout_gravity="center_vertical"/> 23 </LinearLayout> 24 25 <LinearLayout 26 android:orientation="horizontal" 27 android:layout_width="match_parent" 28 android:layout_height="60dp"> 29 <TextView 30 android:layout_width="90dp" 31 android:layout_height="wrap_content" 32 android:layout_gravity="center_vertical" 33 android:textSize="18sp" 34 android:text="密码:"/> 35 <EditText 36 android:id="@+id/password" 37 android:layout_width="0dp" 38 android:layout_height="wrap_content" 39 android:layout_weight="1" 40 android:layout_gravity="center_vertical"/> 41 </LinearLayout> 42 <Button 43 android:id="@+id/login" 44 android:layout_width="match_parent" 45 android:layout_height="60dp" 46 android:text="登录"/> 47 48 49 </LinearLayout>
4.修改MainActivity.java,发送下线广播
1 package com.example.myapplication; 2 3 import androidx.appcompat.app.AlertDialog; 4 import androidx.appcompat.app.AppCompatActivity; 5 6 import android.content.BroadcastReceiver; 7 import android.content.ComponentName; 8 import android.content.Context; 9 import android.content.DialogInterface; 10 import android.content.Intent; 11 import android.content.IntentFilter; 12 import android.os.Bundle; 13 import android.view.View; 14 import android.view.WindowManager; 15 import android.widget.Button; 16 import android.widget.Toast; 17 18 public class MainActivity extends BaseActivity { 19 20 @Override 21 protected void onCreate(Bundle savedInstanceState) { 22 super.onCreate(savedInstanceState); 23 setContentView(R.layout.activity_main); 24 Button forceOffline=(Button)findViewById(R.id.force_offline); 25 forceOffline.setOnClickListener(new View.OnClickListener() { 26 @Override 27 public void onClick(View v) { 28 Intent intent=new Intent("com.example.My Application.FORCE_OFFLINE"); 29 sendBroadcast(intent); 30 } 31 }); 32 33 } 34 35 }
activity_main.xml代码非常简单,只需要一个发送按钮就行:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <Button 8 android:id="@+id/force_offline" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" 11 android:text="发生强制下线广播"/> 12 13 14 </LinearLayout>
最后,修改AndroidManifest.xml,将登录界面设置为主活动
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.myapplication"> 4 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 5 <application 6 android:allowBackup="true" 7 android:icon="@mipmap/ic_launcher" 8 android:label="@string/app_name" 9 android:roundIcon="@mipmap/ic_launcher_round" 10 android:supportsRtl="true" 11 android:theme="@style/AppTheme"> 12 <activity android:name=".LoginActivity"> 13 <intent-filter> 14 <action android:name="android.intent.action.MAIN" /> 15 16 <category android:name="android.intent.category.LAUNCHER" /> 17 </intent-filter> 18 </activity> 19 <activity android:name=".MainActivity"> 20 21 </activity> 22 </application> 23 24 </manifest>
结果: