第五章-全局大喇叭
广播机制简介
Android中的每个应用程序都可以对自己感兴趣的广播进行注册。Android提供了一套完整的API,允许应用程序自由地发送和接收广播。
广播类型
- 标准广播:一种完全异步执行的广播,再广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播信息,因此它们之间没有任何先后顺序可言。
- 有序广播:一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播信息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。
接收系统广播
Android内置了很多系统级别的广播,我们可以在应用程序中通过监听这些广播来得到各种状态的信息。
动态注册监听网络变化
广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够接收到该广播,并在内部处理相应的逻辑。
注册方式:
- 动态注册:在代码中注册。
- 静态注册:在AndroidManifest.xml中注册。
动态注册
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);
}
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
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,"数据正在使用中",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context,"数据连接已关闭",Toast.LENGTH_SHORT).show();
}
}
}
}
NetworkChangeReceiver继承自BroadcastReceiver,重写了onReceive()方法,每当网络发送变化时,onReceive()方法就会得到执行。
onCreate()方法分析:
- 创建IntenFilter实例,并给它添加了一个值为android.net.conn.CONNECTIVITY_CHANGE的action,网络状态发生变化时,系统会发出一条值为android.net.conn.CONNECTIVITY_CHANGE的值。
- 创建一个NetworkChangeReceiver的实例,调用registerReceiver()方法进行注册,讲NetworkChangeReceiver的实例和IntenFilter的实例传入,实现NetworkChangeReceiver会受到所有值为android.net.conn.CONNECTIVITY_CHANGE的action的广播。
注意:动态注册的广播接收器一定要取消注册。
onReceive()方法分析:
- 通过getSystemService()方法得到了ConnectivityManager的实例,这是一个系统服务类,专门用于管理网络连接。
- 调用getActiveNetworkInfo()方法得到NetworkInfo的实例。
- 调用isAvailable()方法,判断当前是否有网络。
注意:Android系统为了保护用户设备的安全和隐私,做了严格的规定:如果程序需要进行一些对用户来说比较敏感的操作,就必须在配置文件中声明权限才可以,否则程序将会直接奔溃。
静态注册实现开机启动
另外创建一个Broadcast Receiver类,在这个类中实现广播接收并且做出回应。
在AndroidManifest.xml中进行注册
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
注意:在广播接收器中是不允许开启线程的。
发送自定义广播
发送标准广播
步骤:
- 新建一个自定义的广播接收器,继承广播接收器。
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
}
}
注册广播接收器。
给控件加入发送自定义广播的逻辑
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
intent.setPackage(getPackageName());
sendBroadcast(intent);
}
});
- 构建Intent对象,把要发送的广播的值传入。
- 调用setPackage(),传入当前应用程序的包名。
- 调用Context的sendBroadcast()方法将广播发送出去。
发送有序广播
广播是一种可以跨进程的通信方式。
在发送自定义广播时把sendBroadcast()方法改为sendOederBroadcast()方法。
然后在注册器中通过prority设置广播接收器的优先级。