05广播-强制下线功能
2018-03-20 本文已影响125人
何惧l
- 创建一个ActivityCollector类管理所有的活动
public class ActivityCollector {
public static List<Activity> activityList = new ArrayList<>();
public static void addActivity(Activity activity){
activityList.add(activity);
}
public static void removeActivity(Activity activity){
activityList.remove(activity);
}
public static void finishAll(){
for(Activity activity : activityList){
if (activity.isFinishing()){
activity.finish();
}
}
}
}
- 创建BaseActivity类作为所有活动的父类
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 活动建立的时候进添加到活动活动集合中
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//销毁的时候就从活动集合中移除
ActivityCollector.removeActivity(this);
}
}
- 上面的代码都是之前写过的,下面手动创建一个登陆的界面,LoginActivity,编辑activity_login.xml中的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Account:"/>
<EditText
android:id="@+id/account"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Password:"/>
<EditText
android:id="@+id/pwd"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
<Button
android:id="@+id/but"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Login"
/>
</LinearLayout>
- 这就是一个简单的登陆界面
- 在LoginActiviyt中添加逻辑
public class LoginActivity extends BaseActivity {
private EditText accountEdit;
private EditText passwordEdit;
private Button login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
accountEdit = (EditText)findViewById(R.id.account);
passwordEdit = (EditText)findViewById(R.id.pwd);
login = (Button)findViewById(R.id.but);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 获取到输入的名字
String account = accountEdit.getText().toString();
String pwd = passwordEdit.getText().toString();
if(account.equals("pony007") && pwd.equals("123456")){
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish();
}else {
Toast.makeText(LoginActivity.this,"用户名或者密码输入错误",Toast.LENGTH_SHORT).show();
}
}
});
}
}
- 首先让它继承自我们自定义的类,若密码和用户用相对的话,进入到MainActivity页面
- 在activity.xml中,这里就也一个按钮,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/but"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="强制下线"/>
</LinearLayout>
- 点击按钮的时候触发强制下线的功能
- 在MainActivity中添加逻辑代码
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.but);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("com.example.md.FORCE_OFFLINE");
sendBroadcast(intent);
}
});
}
}
- 这里也很简单,点击按钮的时候发送一条广播
com.example.md.FORCE_OFFLINE
,这个广播就是用于通知程序强制用户下线的 - 也就是说强制用户下线的逻辑不是在MainActivity中的,而是在广播接收器中的,这样的话,强制下线的功能就不会依附与其他的任何界面,不管在程序的任何地方,只要发送了一条这样的广播,就可以强制用户下线了
- 这个时候来创建一个广播接收器,问题来了,广播接收器在哪里创建呢?由于广播接收器里需要弹出一个对话框来阻塞用户的操作,那么是一个静态注册的广播接收器,是没有办法在onReceive()中弹出对话框这个UI控件的,也不能在每个活动中注册一个动态的广播接收器
- 这个时候我们应该在BaseActivity中动态的注册一个广播接收器,因为所有的活动都是来自BaseActivity
- 在BaseActivity中
public class BaseActivity extends AppCompatActivity {
private ForceOfflineReceiver receiver;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 活动建立的时候进添加到活动活动集合中
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//销毁的时候就从活动集合中移除
ActivityCollector.removeActivity(this);
}
// 动态注册的方式监听广播
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.md.FORCE_OFFLINE");
receiver = new ForceOfflineReceiver();
registerReceiver(receiver,intentFilter);
}
//动态注册的方法需要进行注销
@Override
protected void onPause() {
super.onPause();
if (receiver != null){
unregisterReceiver(receiver);
}
}
// 接收到广播
class ForceOfflineReceiver extends BroadcastReceiver{
@Override
public void onReceive(final Context context, Intent intent) {
// 创建一个对话框
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle("这是一个警告框");
dialog.setMessage("发现异地登陆");
// 设置这个属性为false,点击Back键是不能返回的
dialog.setCancelable(false);
// 设置确定按钮对应的点击事件
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 销毁所有的活动
ActivityCollector.finishAll();
// 重新启动LoginActivity
Intent intent = new Intent(context,LoginActivity.class);
context.startActivity(intent);
}
});
//这个切记
dialog.show();
}
}
}
- 首先在onReceive()中,创建了一个对话框,这里一定要调用setCancelable()方法,将对话框设置为不可取消,当用户点击ok的时候,这个时候就会销毁所有的活动,并且重新启动了LoginActivity,
- 为什么要在onCreate()和o'nDestroy()中注册和取消注册广播接收器,因为我们要始终保证只有处于栈顶的活动才能狗接收到这强制下线的广播,非栈顶的活动不应该也没有必要去接收这条广播,所以写在onResume()和onPause()中,这个时候当一个活动失去栈顶位置的时候就会自动的取消广播接收器的注册
- 此时修改AndroidManifest.xml中的代码,让主活动为LoginActivity
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"></activity>
-
开始运行
2018-03-20_15-20-08.png
登陆后点击按钮就会发送一条强制下线的广播,此时接收到广播,就会弹出一个用户强制下线
2018-03-20_15-22-35.png
点击OK,这时就会到登陆的界面