第五章-全局大喇叭

广播机制简介

Android中的每个应用程序都可以对自己感兴趣的广播进行注册。Android提供了一套完整的API,允许应用程序自由地发送和接收广播。

广播类型

  • 标准广播:一种完全异步执行的广播,再广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播信息,因此它们之间没有任何先后顺序可言。
  • 有序广播:一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播信息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。

接收系统广播

Android内置了很多系统级别的广播,我们可以在应用程序中通过监听这些广播来得到各种状态的信息。

动态注册监听网络变化

广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够接收到该广播,并在内部处理相应的逻辑。

注册方式:

  • 动态注册:在代码中注册。
  • 静态注册:在AndroidManifest.xml中注册。

动态注册

  1. public class MainActivity extends AppCompatActivity {
  2. private IntentFilter intentFilter;
  3. private NetworkChangeReceiver networkChangeReceiver;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. intentFilter = new IntentFilter();
  9. intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
  10. networkChangeReceiver = new NetworkChangeReceiver();
  11. registerReceiver(networkChangeReceiver,intentFilter);
  12. }
  13. protected void onDestroy() {
  14. super.onDestroy();
  15. unregisterReceiver(networkChangeReceiver);
  16. }
  17. class NetworkChangeReceiver extends BroadcastReceiver{
  18. @Override
  19. public void onReceive(Context context, Intent intent) {
  20. ConnectivityManager connectivityManager = (ConnectivityManager)
  21. getSystemService(Context.CONNECTIVITY_SERVICE);
  22. NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
  23. if (networkInfo!=null&&networkInfo.isAvailable()){
  24. Toast.makeText(context,"数据正在使用中",Toast.LENGTH_SHORT).show();
  25. }else {
  26. Toast.makeText(context,"数据连接已关闭",Toast.LENGTH_SHORT).show();
  27. }
  28. }
  29. }
  30. }

NetworkChangeReceiver继承自BroadcastReceiver,重写了onReceive()方法,每当网络发送变化时,onReceive()方法就会得到执行。

onCreate()方法分析:

  1. 创建IntenFilter实例,并给它添加了一个值为android.net.conn.CONNECTIVITY_CHANGE的action,网络状态发生变化时,系统会发出一条值为android.net.conn.CONNECTIVITY_CHANGE的值。
  2. 创建一个NetworkChangeReceiver的实例,调用registerReceiver()方法进行注册,讲NetworkChangeReceiver的实例和IntenFilter的实例传入,实现NetworkChangeReceiver会受到所有值为android.net.conn.CONNECTIVITY_CHANGE的action的广播。

注意:动态注册的广播接收器一定要取消注册。

onReceive()方法分析:

  1. 通过getSystemService()方法得到了ConnectivityManager的实例,这是一个系统服务类,专门用于管理网络连接。
  2. 调用getActiveNetworkInfo()方法得到NetworkInfo的实例。
  3. 调用isAvailable()方法,判断当前是否有网络。

注意:Android系统为了保护用户设备的安全和隐私,做了严格的规定:如果程序需要进行一些对用户来说比较敏感的操作,就必须在配置文件中声明权限才可以,否则程序将会直接奔溃。

静态注册实现开机启动

另外创建一个Broadcast Receiver类,在这个类中实现广播接收并且做出回应。

在AndroidManifest.xml中进行注册

  1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  1. <intent-filter>
  2. <action android:name="android.intent.action.BOOT_COMPLETED"/>
  3. </intent-filter>

注意:在广播接收器中是不允许开启线程的。

发送自定义广播

发送标准广播

步骤:

  1. 新建一个自定义的广播接收器,继承广播接收器。
    1. public class MyBroadcastReceiver extends BroadcastReceiver {
    2. @Override
    3. public void onReceive(Context context, Intent intent) {
    4. Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
    5. }
    6. }
  1. 注册广播接收器。

  2. 给控件加入发送自定义广播的逻辑

    1. button.setOnClickListener(new View.OnClickListener() {
    2. @Override
    3. public void onClick(View v) {
    4. Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
    5. intent.setPackage(getPackageName());
    6. sendBroadcast(intent);
    7. }
    8. });
  1. 构建Intent对象,把要发送的广播的值传入。
  2. 调用setPackage(),传入当前应用程序的包名。
  3. 调用Context的sendBroadcast()方法将广播发送出去。

发送有序广播

广播是一种可以跨进程的通信方式。

在发送自定义广播时把sendBroadcast()方法改为sendOederBroadcast()方法。

然后在注册器中通过prority设置广播接收器的优先级。