广播之 接收广播 & 自定义广播 &本地广播 &强制下线功能

广播分类

  • 标准广播
    完全异步执行, 接收器同时接收,广播不可截断
  • 有序广播
    同步执行,发出后只有一个接收器能接收,结束才能继续往下走,广播可截断

接收系统广播

  • 动态注册监听网络变化
    • 创建广播接收器:
    • 新建类,继承BroadcastReceiver,重写onReceive()
    • 通过调用onDestory中的unregisterReceiver()方法实现取消注册
//声明系统访问权限
<uses-permission android:name="android:permission.ACCESS_NETWORK_STATE" />
public class BootCompleteReceiver{
	public coid onReceiver(Context context,Intent intent){
		Toast.makeText(context,"Boot Complete",Toast.LENGTH_SHORT).show();
	}
}
  • 静态注册 程序未启动就能接受到广播
    • 快捷创广播接收器
      点击创建的项目包 com.example.broadcast
      new -> Other -> Broadcast Receiver
      勾选
    • 在ActivityManifest.xml中注册
    • 自由控制注册与注销
    • 广播接收器中不允许开多线程,添加过多逻辑十分耗时,因此只常借此来 打开程序其他组件

Exported:是否允许这个广播接收器接收本程序以外的广播
Enabled:是否启用这个广播接收器
android:name指定具体注册哪一个广播接收器

 uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED

<Intent>
	<action android:name="android.intent.action.BOOT_COMPLETED">
</Intent>

发送自定义广播

public class MainActivity extends AppCompatActivity {
    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter =new IntentFilter();//创建实例

        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        //当网络状态发生变化时,发出来的正是“值为android.net.conn.CONNECTIVITY_CHANGE的广播
        //想要监听什么样的广播,就在这里添加相应的action

        networkChangeReceiver=new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver,intentFilter);
        //创建实例,注册,实现监听网络变化的功能
    }

    protected void onDestory(){
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
        //unregister,动态广播接收器最后要取消注册
    }

    class NetworkChangeReceiver extends BroadcastReceiver{
        //内部类--创建一个接收器,继承BroadcastReceiver,重写onReceiver

        public void onReceive(Context context, Intent intent){
            //当网络状态变化时,它就会执行
            //Toast.makeText(context,"network changes",Toast.LENGTH_SHORT).show();//show方法
            ConnectivityManager connectionManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
            //系统服务类得到ConnectivityManager的实例,专门管理网络连接
            // getActivityNetworkInfo拿到NetworkInfo实例,使用isavailable()方法

            NetworkInfo networkInfo=connectionManager.getActiveNetworkInfo();
            if(networkInfo!=null&&networkInfo.isAvailable()){
                Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show();
            }
        }
    }
}
  • 发送标准广播
  • 当MyBroadcastReceiver收到自定义广播时,会弹出"received in MyBraodcastReceiver",此时在ActivityManifest.xml中修改:
<Intent-fliter>
	<action android:name="com.example.broadcast.MY_BROADCAST">
</Intent_fliter>
  • 在布局中定义一个按钮 button
  • 在MainActivity:
setContentView...
//修改:
Button button=(Button)findViewById(R.id.Button)
button.setOnClickListener(new View onClickListener){//
	public void onClick(View v){
		Intent intent=new Intent ("com.exampleBroadcast.My_BROADCAST");
		//构建intent对象,传入要发送的广播值
		sendBroadCast(intent)
		//将广播发送出去,监听com.example.broadcasttest.MY_broadcast就会收到消息
	}
}
  • 发送有序广播
Intent intent=new Intent("com.example.broadcasttest,MY_BROADCAST");
sendOrderedBroadcast(intent,null);//第二个参数:与权限相关的字符串,传入null即可
  • 设定先后顺序 android:priority
<Intent-fliter android:priority="100">
	<action android:name="com.example.nroadcasttest.MY_BROADCAST"/>
  • 截断广播 abortBroadcast()
public class MyBroadcastReceiver extends BroadcastReceiver{
	public void onReceive(Context context,Intent intent){
		Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
		abortBroadcast();
	}
}

使用本地

  • LocalBroadcastManager 管理广播 getInstance获取实例 sendBroadcast(intent) 发送本地广播
  • 特点:
    • 应用程序的传递 和 接收器的接收 都只限定在本地
    • 更安全,更高效
    • 因为本地广播运行时程序已经启动,故无法通过静态注册来发送本地广播
public class MainActivity extends AppCompatActivity{
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;//定义LocalReceiver对象
    private LocalBroadcastManager localBroadcastManager;//定义LocalBroadcastManager对象
    protected void onCreate(Bundle saveInstanceState){
        super.onCreate(saveInstanceState);
        setContentView(R.layout.activity_main);

        localBroadcastManager=LocalBroadcastManager.getInstance(this);//获取实例

        Button button=(Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v){

                Intent intent=new Intent("com.example.broadcasttest.LOCAL_BROADCAST");//
                localBroadcastManager.sendBroadcast(intent);//发送本地广播

            }
        });
        intentFilter=new IntentFilter();

        intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
        localReceiver=new LocalReceiver();//
        localBroadcastManager.registerReceiver(localReceiver.intentFilter);//(un)registerReceiver注销/注册本地广播监听器
    }

    protected void onDestory(){
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);//注销
    }

    class LoaclReceiver extends BroadcastReceiver{
        public void onReceive(Context context,Intent intent){
            Toast.makeText(context,"received local broadcast",Toast.LENGTH_LONG).show();
        }
    }

强制下线

  • 构建对话框 AlterDialog.Builder
  • 对话框不可取消 setCancelable()
  • 给对话框注册确定按钮 setPositiveButton()
  • 销毁所有活动 重新启动LoginActivity: finishAll()
  • onResume() onPause() 当一个活动失去栈顶位置时就会自动取消广播接收器的注册注册和注销 ForceOfflineReceiver()

ActivityManifest.xml

如果报Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined. 在LoginActivity后面补上 android:exported="true"

//将LoginActivity改为主活动
<activity android:name=".MainActivity">
</activity>
<activity android name=".LoginActivity">
	<Intent-filter>...

activity_login.xml

orientation 是 horizonal,不然会将密码栏和login按钮遮住

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <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="Account:" />

        <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="Password:" />

        <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="Login"/>

</LinearLayout>

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/force_offline"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send force offline broadcast" />

</LinearLayout>

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 所有活动的父类

public class BaseActivity extends AppCompatActivity {

    private ForceOfflineReceiver receiver;

    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcastbestpractice.FORCE_OFFLINE");
        receiver = new ForceOfflineReceiver();
        registerReceiver(receiver,intentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if(receiver != null){
            unregisterReceiver(receiver);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }

    private class ForceOfflineReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(final Context context, Intent intent) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle("Warning");
            builder.setMessage("you are forced to be offline,please try to login again");
            builder.setCancelable(false);
            builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    ActivityCollector.finishAll();  //销毁所有活动
                    Intent intent = new Intent(context,LoginActivity.class);
                    context.startActivity(intent); //重新启动LoginActivity
                }
            });
            builder.show();
        }
    }
}

MainActivity


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);
            }
        });
    }
}

LoginActivity

public class LoginActivity extends AppCompatActivity {

    private EditText accountEdit;

    private EditText passwordEdit;

    private Button login;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login2);
        accountEdit=(EditText)findViewById(R.id.account);
        passwordEdit=(EditText)findViewById(R.id.password);//获取密码,账号实例
        login=(Button)findViewById(R.id.login);
        login.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                String account = accountEdit.getText().toString();  
                String password = passwordEdit.getText().toString();
                if (account.equals("Alice") && password.equals("12345678")) {
                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);//Intent,登录成功,就跳转到MainActivity
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(LoginActivity.this, "account or password is invalid", Toast.LENGTH_SHORT).show();
                }
            }

        });
    }
}

过程中特别撒币的把类建到了不同的包下面,导致出现了下面的提示:MainActivity must extend android.app.Activity
各位伙伴要是也出现了相同的情况,注意检查一下哟~

Git

  • Git 下载与安装
    当时下载了很多次都是失败,最后通过 复制链接 的方式下载才成功,安装很多都是默认项,next挺容易

  • 建代码仓库
    cd d: 项目在哪个盘,就写 cd 几:,如果报 No found file or directory 注意检查一下自己的路径,是不是项目所在路径,空格冒号输入时都要注意

  • add
    把想要提交的代码添加进来

  • commit
    提交

git add build.gradle    //添加 build.gradle 文件
git add app = git add.  //添加 app目录
git  commit -m "First commit." // -m加上提交描述的信息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在Android中,我们可以通过发送自定义广播来实现强制下线功能。具体实现步骤如下: 1. 创建一个自定义广播 可以在应用程序中创建一个自定义广播,例如: ``` public static final String FORCE_OFFLINE_ACTION = &quot;com.example.broadcasttest.FORCE_OFFLINE&quot;; ``` 2. 在需要实现强制下线的地方发送广播 可以在需要实现强制下线的地方发送广播,例如: ``` Intent intent = new Intent(FORCE_OFFLINE_ACTION); sendBroadcast(intent); ``` 3. 在应用程序的Manifest文件中注册广播接收器 可以在应用程序的Manifest文件中注册广播接收器,例如: ``` &lt;receiver android:name=&quot;.ForceOfflineReceiver&quot;&gt; &lt;intent-filter&gt; &lt;action android:name=&quot;com.example.broadcasttest.FORCE_OFFLINE&quot; /&gt; &lt;/intent-filter&gt; &lt;/receiver&gt; ``` 4. 实现广播接收器 实现一个广播接收器,当接收强制下线广播时,关闭所有Activity并重新启动登录界面,例如: ``` public class ForceOfflineReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(&quot;Warning&quot;); builder.setMessage(&quot;You are forced to be offline. Please try to login again.&quot;); builder.setCancelable(false); builder.setPositiveButton(&quot;OK&quot;, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCollector.finishAll(); // 关闭所有Activity Intent intent = new Intent(context, LoginActivity.class); context.startActivity(intent); // 重新启动登录界面 } }); builder.show(); } } ``` 这样,当发送强制下线广播时,所有的Activity都会被关闭,并且重新启动登录界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

blog....

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值