/*** 在界面上弹出一个对话框,让用户无法进行任何其他操作,必须要点击对话框中的确定按钮,然后回到登录界面* 强制下线功能需要先关闭掉所有的活动,然后回到登录界面*/
1. 定义一个ActivityCollector.java类,来收集活动,主要是为了关闭所有活动
public class ActivityCollector { //创建活动收集类,以定义所有Activity关闭的方法 public static List<Activity> activities = new ArrayList<Activity>(); public static void addActivity(Activity activity) { //将Activity添加到集合 activities.add(activity); } public static void removeActivity(Activity activity) { //将Activity从集合移除 activities.remove(activity); } public static void finishAll() { //关闭集合中所有Activity for (Activity activity : activities) { if (!activity.isFinishing()) { activity.finish(); } } } } 2. 创建一个BaseActivity,让所有Activity继承,因为所有Activity都需要该类下的onCreate和onDestroy方法 public class BaseActivity extends AppCompatActivity { //作为所有类的父类 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { //在活动创建的时候,就将该活动加入到ActivityCollector中 super.onCreate(savedInstanceState); ActivityCollector.addActivity(this); } @Override protected void onDestroy() { //在活动销毁的时候,将该活动从ActivityCollector中移除,因为该活动已经结束不用再在ActivityCollector结束 super.onDestroy(); ActivityCollector.removeActivity(this); } } 3. 登录界面布局 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:stretchColumns="1"> <TableRow> <TextView android:layout_height="wrap_content" android:text="Account:" /> <EditText android:id="@+id/account" android:layout_height="wrap_content" android:hint="Input your account" /> </TableRow> <TableRow> <TextView android:layout_height="wrap_content" android:text="Password:" /> <EditText android:id="@+id/password" android:layout_height="wrap_content" android:inputType="textPassword" /> </TableRow> <TableRow> <Button android:id="@+id/login" android:layout_height="wrap_content" android:layout_span="2" android:text="Login" /> </TableRow> </TableLayout>4. 登录界面的LoginActivity
public class LoginActivity extends BaseActivity { @BindView(R.id.et_account) EditText etAccount; @BindView(R.id.et_password) EditText etPassword; @BindView(R.id.btn_login) Button btnLogin; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login); ButterKnife.bind(this); } @OnClick(R.id.btn_login) public void onClick() { String account = etAccount.getText().toString(); String password = etPassword.getText().toString(); //账号:admin 密码:123456 登录成功 if (account.equals("admin") && password.equals("123456")) { Intent intent = new Intent(this, MainActivity.class); startActivity(intent); finish(); } else { Toast.makeText(this, "账号或密码错误", Toast.LENGTH_SHORT).show(); } } }5. 登录成功后的界面MainActivity
将MainActivity 理解成是登录成功后进入的程序主界面,只需要加入强制下线功能。
强制用户下线的逻辑并不是写在MainActivity里的,而是应该写在接收这条广播的广播接收器里面,这样强制下线的功能就不会依附于任何的界面,不管是在程序的任何地方,只需要发出这样一条广播,就可以完成强制下线的操作了
public class MainActivity extends BaseActivity { @BindView(R.id.btn_force_offline) Button btnForceOffline; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); } @OnClick(R.id.btn_force_offline) public void onClick() { //发送了一条广播,广播的值为com.example.p206.FORCE_OFFLINE,这条广播就是用于通知程序强制用户下线的 Intent intent = new Intent("com.example.p206.FORCE_OFFLINE"); sendBroadcast(intent); } } 6. 创建广播接收器ForceOfflineReceiver public class ForceOfflineReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, Intent intent) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("警告") .setMessage("您已强制下线,请重新登录") .setCancelable(false) //不可以点击返回键取消对话框 .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { ActivityCollector.finishAll(); //销毁所有活动 Intent intent1 = new Intent(context, LoginActivity.class); //重启LoginActivity intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //因为是在广播接收器里启动活动的,因此一定要给Intent加入FLAG_ACTIVITY_NEW_TASK这个标志 context.startActivity(intent1); } }); AlertDialog dialog = builder.create(); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); //把AlertDialog的类型设为TYPE_SYSTEM_ALERT,不然它将无法在广播接收器里弹出 dialog.show(); } } 7. AndroidManifest.xml <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> //权限 <activity android:name=".LoginActivity"> //主活动界面LoginActivity <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity" /> <receiver android:name=".ForceOfflineReceiver"> //广播接收器 <intent-filter> <action android:name="com.example.p206.FORCE_OFFLINE" /> </intent-filter> </receiver>