广播类型分为有序广播和标准广播。标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎在同一时间接收到这条广播信息,没有先后顺序可言,无法被截断。有序广播是同步执行的广播,同一时间只有一个广播接收器可以接收这条消息,只有当广播接收器中的逻辑执行完毕,广播才能继续传递。此时广播接收器是有先后顺序的,前面的广播接收器还可以截断正在传递的广播。
需要在代码中注册广播
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");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver,intentFilter);
}
@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
private class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent){
ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.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();
}
}
}
}
在MainActivity中定义一个内部类NetworkChangeReceiver,该类继承自BroadcastReceiver,并重写onReceive()方法。每当网络状态发生变化时,执行onReceive()方法。在onCreate()中创建IntentFilter 实例,为它添加值为android.net.conn.CONNECTIVITY_CHANGE的action,当网络状态发生改变时,系统发出的就是一条值为android.net.conn.CONNECTIVITY_CHANGE的广播,广播接收器想要监听什么广播只需要添加相应的action。接下来创建一个NetworkChangeReceiver的实例,然后调用registerReceiver()方法进行注册,将NetworkChangeReceiver和IntentFilter 实例传入。为防止内存泄露,在onDestroy()方法调用unregisterReceiver()方法实现取消注册广播功能。在onReceive()方法中,通过getSystemService()方法得到了ConnectivityManager的实例,这是个系统服务类,专门用于管理网络连接,然后调用getActiveNetworkInfo()方法可以得到NetworkInfo的实例,接着调用NetworkInfo的isAvailable()方法,就可以判断是否有网络。最后需要在AndroidManifest.xml文件声明权限访问网络状态。
静态注册广播可以在程序未启动时便能接收到广播。这里我们准备让程序接收一条开机广播,当收到这条广播时就可以在onReceive()方法里执行相应的逻辑,从而实现开机启动的功能。新建一个BootCompleteReceiver继承自BroadcastReceiver,代码如下所示:
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
}
}
先在AndroidManifest.xml文件添加如下权限
然后在application标签中添加标签注册广播接收器,在标签中加入想要接收的广播。由于Android系统启动完成后会发出一条值为android.intent.action.BOOT_COMPLETED的广播,因此我们在这里添加了相应的action。
首先定义一个广播接收器
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
}
}
然后在AndroidManifest.xml对这个广播接收器进行注册,让其接收一条值为com.example.broadcasttest. MY_BROADCAST的广播
然后在MainActivity构建Intent对象,并吧要发送的广播的值传入,然后调用context的sendBroadcast()方法将广播发送出去。
public class MainActivity extends Activity {
……
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest. MY_BROADCAST");
sendBroadcast(intent);
}
});
}
}
发送广播方式区别于标准广播,使用如下代码,第二个参数是一个与权限相关的字符串
sendOrderedBroadcast(intent, null);
有序广播可以通过设置广播接收器的优先级,改变先后顺序,还可以将广播截断,主要在注册中设定,在AndroidManifest.xml中的广播接收器中加入如下代码
同时也可以截断广播,只需要在广播接收器的onReceive()方法中加入如下代码
abortBroadcast();
首先是通过LocalBroadcastManager的getInstance()方法得到了它的一个实例,然后在注册广播接收器的时候调用的是LocalBroadcastManager的registerReceiver()方法,在发送广播的时候调用的是LocalBroadcastManager的sendBroadcast()方法,仅此而已。这里我们在按钮的点击事件里面发出了一条com.example.broadcasttest. LOCAL_BROADCAST广播,然后在LocalReceiver里去接收这条广播
public class LocalBroadcastActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalBroadcastManager localBroadcastManager;
private LocalReceiver localReceiver;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.local_activity);
localBroadcastManager = LocalBroadcastManager.getInstance(this);// 获取实例
Button btn = (Button)findViewById(R.id.button2);
btn.setOnClickListener(new View.OnClickListener() {
@Override
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);// 注册本地广播监听器
}
@Override
protected void onDestroy(){
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
private class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received local broadcast",Toast.LENGTH_SHORT).show();
}
}
}
最后我们再来盘点一下使用本地广播的几点优势吧。
1.可以明确地知道正在发送的广播不会离开我们的程序,因此不需要担心机密数据泄漏的问题。
2.其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐患。
3.发送本地广播比起发送系统全局广播将会更加高效。