/**
* 在界面上弹出一个对话框,让用户无法进行任何其他操作,必须要点击对话框中的确定按钮,然后回到登录界面
* 强制下线功能需要先关闭掉所有的活动,然后回到登录界面
*/
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>