广播
Android为了系统级别的消息通知,引入的一套类似广播消息的机制。每个程序可以对自己感兴趣的广播进行注册,这样该程序就只会接受自己所关心的广播
在Android中,发送广播通过Intent,接收广播通过BroadCast Receiver广播接收器来接收
广播类型
标准广播
完全异步执行的广播,广播发出后,所有广播接收器几乎同时接收到该消息。这种广播效率更高,但缺点是无法中途被截断
有序广播
一种同步执行广播,在广播发出后,同一时间,只有一个广播接收器能够收到这条广播,当这个广播接收器逻辑执行完毕后,广播才继续传递,所以这种广播的传递具有先后顺序,优先级高的广播接收器先接收到。并且这种广播可以中途在广播接收器处被截断,导致后面的广播接收器不能接收到这条广播
接收系统广播
动态注册广播接收器用于监听网络变化
package cn.ywrby.broadcasttext;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
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"); //添加动作进行筛选,只截获CONNECTIVITY_CHANGE的信息
netWorkChangeReceiver=new NetWorkChangeReceiver(); //初始化
registerReceiver(netWorkChangeReceiver,intentFilter); //调用注册生成器方法,传入接收器和筛选器
}
//每一个动态生成的广播接收器,都需要定义销毁方法
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(netWorkChangeReceiver); //调用方法,移除接收器
}
//定义网络变化广播接收器,继承BroadcastReceiver广播接收器,实现方法onReceive在接收到广播后调用
class NetWorkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//ConnectivityManager一种专门用于管理网络连接的系统服务类,这里通过getSystemService方法获取
ConnectivityManager connectivityManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
//调用这个类的getActiveNetworkInfo得到NetworkInfo实例
NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
//再通过这个实例的isAvailable判断是否有网络,并通过Toast告知用户
if(networkInfo!=null&&networkInfo.isAvailable()){
Toast.makeText(context,"network is available!",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"network is not available!",Toast.LENGTH_SHORT).show();
}
}
}
}
注意,这里需要在配置文件中声明访问系统网络状态的权限,否则程序可能崩溃
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
静态注册实现开机启动
新建广播接收器类继承BroadCastReceiver,然后在配置文件中声明权限并注册(同时对广播进行筛选)
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context,"Boot Complete!",Toast.LENGTH_SHORT).show();
}
}
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
发送广播
发送标准广播
Button bt_sender=findViewById(R.id.bt_broadcastsender);
bt_sender.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("cn.ywrby.broadcasttext.My_BroadCastText");
sendBroadcast(intent);
}
});
发送有序广播
发送有序广播只需要在发送标准广播的基础上进行简单修改
Button bt_sender=findViewById(R.id.bt_broadcastsender);
bt_sender.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("cn.ywrby.broadcasttext.My_BroadCastText");
sendOrderedBroadcast(intent,null);
}
});
只需要修改发送广播的方法为sendOrderedBroadcast,该方法第二个参数是与权限相关的字符串,这里传入null即可
发送有序广播是具有先后顺序的,所以可以在注册接收器时规定优先级
<intent-filter android:priority="100">
并且可以在接收器类中,调用abortBroadcast();方法,截断当前收到的广播,使其无法继续向下级传播
使用本地广播
前文所提到的广播发送和接收都是全局状态下的,也就是发送的广播可以被任何应用程序获得,这是具有一定安全隐患的,比方某个应用程序内的私密数据在传播过程中可能被其他应用程序截获,或者是某个应用程序不断接收其他应用发送的垃圾广播
为解决这种问题,Android引入了本地广播机制,这种广播只能在当前应用内发送与接收
实际操作中也比较简单,实质就是通过LocalBroadcastManager对发送的广播进行管理
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager.getInstance(this); //获取实例
Button bt_local=findViewById(R.id.bt_local);
bt_local.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("cn.ywrby.localbroadcasttext.Local_Broadcast");
localBroadcastManager.sendBroadcast(intent); //发送本地广播
}
});
localReceiver=new LocalReceiver();
intentFilter=new IntentFilter();
intentFilter.addAction("cn.ywrby.localbroadcasttext.Local_Broadcast");
localBroadcastManager.registerReceiver(localReceiver,intentFilter); //本地注册
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver); //在本地直接移除注册
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Local Broadcast!!",Toast.LENGTH_SHORT).show();
}
}
}