【Android入门到项目实战-- 5.3】—— 广播实战使用(强制下线到登录界面)

目录

一、前言

二、代码实现

1、关闭所有活动

2、登录界面活动

3、登录功能实现

4、强制下线按钮

5、动态注册广播接收器


一、前言

        假设有以下需求:你的某个账号在别处登录,你将强制下线。

        普通的思路是:在每个页面都设置一个弹出框,让用户无法操作,必须点击对话框中的确定按钮,然后回到登录界面。

        但是这样存在个问题:每个页面都编写一个弹出框,会很麻烦。

        广播可以轻松的实现这一功能,下面实现。

效果如下:

二、代码实现

新建一个BroadcastBestPractice项目。

强制下线需要关闭所有的活动,然后回到登录界面。

所以首先实现关闭所有活动的功能。

1、关闭所有活动

创建ActivityCollector类,用于管理所有活动,代码如下:

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();
            }
        }
        activities.clear();
    }
}

然后创建BaseActivity类作为所有活动的父类,代码如下:

public class BaseActivity extends AppCompatActivity {
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
    }
    
    protected void onDestroy(){
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}

2、登录界面活动

首先创建一个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:textSize="18sp"
            android:text="账号:"/>
        
        <EditText
            android:id="@+id/account"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            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:textSize="18sp"
            android:text="密码:"/>
        
        <EditText
            android:id="@+id/password"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:inputType="textPassword"/>
        
    </LinearLayout>
    
    <Button
        android:id="@+id/login"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="登录"/>

</LinearLayout>

3、登录功能实现

修改LoginActivity类的代码,如下:

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.password);
        login = (Button) findViewById(R.id.login);
        
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String account = accountEdit.getText().toString();
                String password = passwordEdit.getText().toString();
//                默认账号是admin,密码是123456
                if(account.equals("admin")&&password.equals("123456")){
                    Intent intent = new Intent(LoginActivity.this,MainActivity.class);
                    startActivity(intent);
                    finish();
                }else{
                    Toast.makeText(LoginActivity.this, "账号或密码错误", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

4、强制下线按钮

修改activity_main.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"
    android:orientation="vertical">

    <Button
        android:id="@+id/force_offline"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="强制下线"/>

</LinearLayout>

修改MainActivity代码,如下:

        在按钮的点击事件里发送了一条广播,用于通知程序控制用户下线,强制用户下线的逻辑写在接收这条广播的广播接收器里。

        那么在哪里创建一个广播接收器来接收这条广播?因为我们需要弹出对话框,因此使用动态注册一个广播接收器,在BaseActivity类里,因为所有活动继承这个类。

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button forceOffline = (Button) findViewById(R.id.force_offline);
        forceOffline.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.example.broadcastbestpractice.FORCE_OFFLINE");
                sendBroadcast(intent);
            }
        });
    }
}

5、动态注册广播接收器

修改BaseActivity代码如下:

        需要始终保证处于栈顶的活动才能接收到这条广播的强制下线,非栈顶活动不应该没必要去接收这条广播,所以在onResume()和onPause()方法里注册和取消注册广播接收器。

        当一个活动失去栈顶位置时自动取消广播接收器的注册。

public class BaseActivity extends AppCompatActivity {
    
    private ForceOfflineReceiver receiver;
    
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
    }
    protected void onDestroy(){
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
    
    protected void onResume(){
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcastbestpractice.FORCE_OFFLINE");
        receiver = new ForceOfflineReceiver();
        registerReceiver(receiver,intentFilter);
    }
    
    protected void onPause(){
        super.onPause();
        if(receiver != null){
            unregisterReceiver(receiver);
            receiver = null;
        }
    }
    
    class ForceOfflineReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, 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 dialogInterface, int i) {
                    ActivityCollector.finishAll();
                    Intent intent = new Intent(context,LoginActivity.class);
                    context.startActivity(intent);
                }
            });
            builder.show();
        }
    }
}

最后不要忘记修改AndroidManifest.xml文件,LoginActivity作为首页。

最后演示一下:

猜你喜欢

转载自blog.csdn.net/Tir_zhang/article/details/130142030
5.3