最终的效果图:
强制下线功能的实现首先需要一个关闭所有活动的功能。
我们新建一个ActivityController.java:
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<>();
public static void addActivity(Activity activity){
activities.add(activity);
}
public static void removeActivity(Activity activity){
activities.remove(activity);
}
public static void finishAll(){
for (Activity activity : activities) {
if (!activity.isFinishing()){
activity.finish();
}
}
}
}
继续建立一个BaseActivity.java:
public class BaseActivity extends AppCompatActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
建立登陆界面和活动:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="账号:"
android:textSize="30dp"/>
<EditText
android:id="@+id/user_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码:"
android:textSize="30dp"/>
<EditText
android:inputType="textPassword"
android:id="@+id/user_password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
<Button
android:id="@+id/user_login"
android:text="Login"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
LoginActivity.java:
public class LoginActivity extends BaseActivity {
private EditText username;
private EditText password;
private Button login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
username = (EditText)findViewById(R.id.user_name);
password = (EditText)findViewById(R.id.user_password);
login = (Button)findViewById(R.id.user_login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (username.getText().toString().equals("123")&&password.getText().toString().equals("123")){
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
}else {
Toast.makeText(LoginActivity.this,"账号或密码错误",Toast.LENGTH_SHORT).show();
}
}
});
}
}
跳转页面
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context="com.example.eason.broadcastdown.MainActivity">
<Button
android:id="@+id/down_login"
android:layout_width="368dp"
android:layout_height="wrap_content"
tools:layout_editor_absoluteX="8dp"
android:text="downlogin"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"/>
</android.support.constraint.ConstraintLayout>
这里加入了一个强制下线的按钮。
修改MainActivity.java:
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button downlogin = (Button)findViewById(R.id.down_login);
downlogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//发送广播
Intent intent = new Intent("com.example.eason.DOWN");
sendBroadcast(intent);
}
});
}
}
修改BaseActivity.java:
public class BaseActivity extends AppCompatActivity {
private downLoginReceiver mDownLoginReceiver;
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
ActivityCollector.addActivity(this);
}
@Override
protected void onResume() {
super.onResume();
//过滤,接受广播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.eason.DOWN");
mDownLoginReceiver = new downLoginReceiver();
registerReceiver(mDownLoginReceiver,intentFilter);
}
@Override
protected void onPause() {
super.onPause();
if (mDownLoginReceiver != null){
unregisterReceiver(mDownLoginReceiver);
mDownLoginReceiver = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
class downLoginReceiver extends BroadcastReceiver{
@Override
public void onReceive(final Context context, final Intent intent) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("警告:");
builder.setMessage("您的账号在另一台设备登陆,请重新登陆");
builder.setCancelable(false);
builder.setPositiveButton("好的", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCollector.finishAll();//销毁全部活动
Intent intent1 = new Intent(context,LoginActivity.class);//跳转
startActivity(intent1);
}
});
builder.show();
}
}
}
说明:这里我们会好奇为什么是在onResume(),onPause()内注册广播,销毁广播,因为这个时候该活动处于栈顶,非栈顶的活动没必要也不应该接收到这条广播。
修改LoginActivity为主界面:
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
效果图: