Android学习笔记40:Android四大组件之BroadcastReceiver
Android应用程序的四大组件分别是Activity、Service、BroadcastReceiver和ContentProvider。其中,Activity、Service和ContentProvider在之前的博文中都已经介绍过了,具体如下:
(1)Activity:《Android学习笔记38:Android四大组件之Activity》
(2)Service:《Android学习笔记39:Android四大组件之Service》
(3)ContentProvider:《Android学习笔记37:使用Content Providers方式共享数据》
本文将主要对BroadcastReceiver进行介绍。
1.系统广播
BroadcastReceiver是一种负责接收广播消息并对消息做出响应的组件,它和Service一样,并不提供与用户交互的UI界面。
在Android系统中存在许多标准的广播动作,其中常见的有以下一些:
(1)Intent.ACTION_CAMERA_BUTTON; //按下拍照按键
(2)Intent.ACTION_DATA_CHANGED; //设备日期发生改变
(3)Intent.ACTION_TIME_CHANGED; //设置时间发生改变
(4)Intent.ACTION_TIMEZONE_CHANGED; //时区发生改变
(5)Intent.ACTION_BOOT_COMPLETED; //系统启动完成
(6)Intent.ACTION_PACKAGE_ADDED; //成功安装APK
(7)Intent.ACTION_PACKAGE_CHANGED; //已安装的APK被改变
(8)Intent.ACTION_PACKAGE_REMOVED; //删除APK
(9)Intent.ACTION_PACKAGE_DATA_CLEARED; //清除应用程序的数据
(10)Intent.ACTION_BATIERY_LOW; //电池电量低
(11)Intent.ACTION_BATIERY_CHANGED; //充电状态电池电量发生变化
(12)Intent.ACTION_POWER_CONNECTED; //连接外部电源
(13)Intent.ACTION_POWER_DISCONNECTED; //断开外部电源
(14)Intent.ACTION_HEADSET_PLUG; //插入耳机
(15)Intent.ACTION_INPUT_METHOD_CHANGED; //输入法改变
(16)Intent.ACTION_MEDIA_CHECKING; //插入外部储存设备进行检测
(17)Intent.ACTION_MEDIA_MOUNTED; //外部存储设备Mount成功
(18)Intent.ACTION_MEDIA_REMOVED; //外部存储设备移除
(19)Intent.ACTION_SCREEN_OFF; //屏幕关闭
(20)Intent.ACTION_SCREEN_ON; //屏幕打开
(21)Intent.ACTION_SHUTDOWN; //关闭系统
以上这些都是Android系统中内置的一些广播动作,我们可以直接在我们的应用程序中接收这些广播动作,并根据所接收到的不同广播做出相应的处理。
2.发布广播
除了以上介绍的这些Android系统内置的广播之外,如果我们想要在自己的应用程序中创建并发布一个自定义的广播也是很容易的。
广播的内容和用于过滤广播的动作是携带在Intent对象中被发送出去的,所以我们可以通过Intent类提供的putExtra()方法向Intent对象中加入广播内容,通过Intent类提供的setAction()方法向Intent对象中加入过滤广播的动作。具体实现方法如下代码所示:
1 /* 2 * Function : 点击事件处理 3 * Author : 博客园-依旧淡然 4 */ 5 public void onClick(View view) { 6 switch(view.getId()) { 7 case R.id.button: 8 Intent intent = new Intent(); //创建Intent对象 9 intent.setAction(MY_ACTION); //设置Intent对象的Action属性 10 intent.putExtra("key_msg", mEditText.getText().toString()); //向Intent对象中添加广播内容 11 sendBroadcast(intent); //发送广播 12 break; 13 } 14 }
在以上的代码中,我们通过setAction()方法向Intent对象中加入了过滤广播的动作,这个动作是我们自定义的,像Android中内置的广播动作一样,这个动作可以用来唯一的识别我们自定义的广播。这里我将该动作定义如下:
private static final String MY_ACTION = "com.example.android_broadcast.msg";
此外,我们通过putExtra()方法向Intent对象中加入了广播的内容,其中广播的内容是EditText控件中的输入内容。putExtra()方法提供了以键值对的形式存储数据。
最后,我们通过sendBroadcast()方法,将携带有广播信息的Intent对象发送出去即可。
需要注意的一点是,在Context类中提供了3种方式发送广播,分别是:
(1)Context.sendBroadcast();
(2)Context.sendStickyBroadcast();
(3)Context.sendOrderedBroadcast();
其中,使用sendBroadcast()方式发送出去的Intent,所有满足条件的BroadcastReceiver都会执行其onReceive()方法,但是如果有多个满足条件的BroadcastReceiver,那么其执行onReceive()方法的顺序则是不一定的。
使用sendStickyBroadcast()方式发送出去的Intent会一直存在,并且在以后如果调用registerReceive()方法注册一个满足条件的BroadcastReceiver时,Intent对象会直接返回给新注册的BroadcastReceiver。
使用sendOrderedBroadcast()方式发送出去的Intent,会根据BroadcastReceiver注册时IntentFilter设置的优先级的顺序来执行onReceive()方法,但是相同优先级的BroadcastReceiver执行onReceive()方法的顺序是不一定的。
3.接收广播
如果在我们的应用程序中需要接收某个广播(Android内置的广播或我们自定义的广播),并对接收到的广播进行相应的处理,那么我们需要创建一个BroadcastReceiver类(继承自android.Content.BroadcastReceiver类),并实现BroadcastReceiver类的onReceive()方法。BroadcastReceiver类中的onReceive()方法在接收到发给自己的广播时会被调用。
除此之外,我们还需要对我们创建的BroadcastReceiver类进行注册,注册的方式有两种:一种是在AndroidManifest.xml文件中注册BroadcastReceiver,另一种是直接在代码中通过registerReceive()方法注册BroadcastReceiver。
下面就分别说说这两种方式都是如何实现的。
3.1在AndroidManifest.xml文件中注册BroadcastReceiver
首先,我们需要创建一个BroadcastReceiver类,用来接收并处理刚才发布的广播信息,具体如下代码所示:
1 /* 2 * Class : BroadcastReceiver类,用于接收并处理广播信息 3 * Author : 博客园-依旧淡然 4 */ 5 public class MyBroadcastReceiver extends BroadcastReceiver { 6 7 @Override 8 public void onReceive(Context context, Intent intent) { 9 String msg = intent.getStringExtra("key_msg"); //获取广播的内容 10 Toast.makeText(context, "接收到的广播信息为:" + msg, Toast.LENGTH_LONG).show(); 11 } 12 13 }
通过以上的代码,我们创建了一个名为“MyBroadcastReceiver”的BroadcastReceiver 类,在onReceive()方法中取出了广播的内容,并将其显示出来。
完成了MyBroadcastReceiver的代码编写之后,还需要在AndroidManifest.xml文件中注册该组件。具体方法如下所示:
1 <receiver 2 android:name=".MyBroadcastReceiver"> 3 <intent-filter> 4 <action android:name="com.example.android_broadcast.msg" /> 5 </intent-filter> 6 </receiver>
<receiver></receiver>标签嵌套在<application></application>标签里,其中,android:name=".MyBroadcastReceiver"指定了所要注册的BroadcastReceiver组件的名字。<intent-filter></intent-filter>标签中的<action>标签则用于指定该BroadcastReceiver组件的过滤规则。可以看到,该标签中的android:name="com.example.android_broadcast.msg",正是我们之前定义的广播动作。由此,便唯一的确定了MyBroadcastReceiver所要响应的是哪一个广播动作。
3.2通过registerReceive()方法注册BroadcastReceiver
在Activity中,我们也可以直接在onStart()方法中通过调用registerReceiver()方法注册BroadcastReceiver,在onStop()方法中通过调用unregisterReceiver()方法解除对BroadcastReceiver的注册,如下代码所示:
1 /* 2 * Function : onStart()方法 3 * Author : 博客园-依旧淡然 4 */ 5 protected void onStart() { 6 super.onStart(); 7 IntentFilter intentFilter = new IntentFilter(); 8 intentFilter.addAction(MY_ACTION); //设置Action 9 registerReceiver(myBroadcastReceiver, intentFilter); //注册BroadcastReceiver组件 10 } 11 12 /* 13 * Function : onStop()方法 14 * Author : 博客园-依旧淡然 15 */ 16 protected void onStop() { 17 unregisterReceiver(myBroadcastReceiver); //解除注册BroadcastReceiver组件 18 super.onStop(); 19 }
需要注意的一点是,如果你是在Activity的onResume()方法中注册BroadcastReceiver的,那么就需要在Activity的onPause()方法中解除对BroadcastReceiver的注册。
3.3注册广播的两种方式的区别
在AndroidManifest.xml文件中注册的BroadcastReceiver,属于常驻型广播,即使应用程序关闭了,如果有广播信息来,所创建的BroadcastReceiver同样能够接收到。所以这是一种静态注册广播的形式。
通过registerReceive()方法注册的BroadcastReceiver,属于非常驻型广播,通常在Activity结束时就会调用unregisterReceiver()方法解除BroadcastReceiver。所以这是一种动态注册广播的形式。