通过第一篇的讲解,我们已经看到了如何使用Intent来启动新的应用程序组件,但是实际上他们也可以使用sendBroadcast方法来在组件间匿名的广播消息。
作为一个系统级别的消息传递机制,Intent可以在进程之间发送结构化的消息。因此,通过实现Broadcast Receiver来监听和响应应用程序内的这些Broadcast Intent。
通过使用Intent来广播一个事件,可以在不修改原始的应用程序的情况下,让我们开发人员对事件做出反应。Android大量使用了Broadcast Receiver来广播系统事件,如网络连接和短信通知等。
1.使用Intent来广播事件
在应用程序组件中,可以构建希望广播的Intent,然后使用sendBroadcast方法来发送它。
可以对Intent的动作、数据和分类进行设置,从而使Broadcast Receiver能够精确的确定他们的需求。在这种方案中,Intent动作字符串可以用来标识要广播的事件,所以他应该是能够标识事件的唯一的字符串。习惯上,动作字符串使用与Java包名相同的构建方式,如下:
<span style="font-size:14px;">public static final String MY_INTENT_ACTION = "com.happy.demo.test";</span>
如果希望在Intent中包含数据,那么可以使用Intent的data属性指定一个URI,也可可以包含extras来添加额外的基本值。
2.使用Broadcast Receiver来监听广播
Broadcast Receiver可以用来监听Broadcast Intent,但是需要对其进行注册,既可以使用代码方式来注册,也可以在应用程序的manifest.xml文件中进行注册,不管采用哪种方式,都需要使用一个Intent Filter来指定他要监听哪些Intent和数据。
对于包含在manifest.xml文件中的广播接收者 ,在Intent被广播出去的时候,应用程序不一定非要处于运行状态才能接收,他们会被自动的启动。
创建一个新的Broadcast Receiver,需要扩展Broadcast Receiver类并重写onReceive方法来进行自己的处理。比如:
<span style="font-size:14px;">package com.happy.demo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub } } </span>
当接收到一个与在注册接收器时使用的IntentFilter相匹配的Broadcast Intent的时候,就会执行onReceive方法。onReceive处理程序必须要在5秒钟以内完成,否则会显示Force Close对话框。
一般情况下,Broadcast Receiver将会更新内容、启动Service、更新Activity UI或者使用Notification Manager来通知用户。
3.在代码中注册Broadcast Receiver
影响特定Activity的UI的Boradcast Receiver通常在代码中注册,在代码中注册的接收器只会在包含它的应用程序组件运行时相应Broadcast Intent。
在接收器用来更新一个Activity中的UI元素时,一般在onResume中注册接收器,在onPause中注销接收器。代码:
<span style="font-size:14px;">@Override protected void onResume() { super.onResume(); registerReceiver(receiver, filter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(receiver); }</span>
4.在应用程序的manifets.xml文件中进行注册
要在应用程序的mainfets中包含一个Broadreceiver,可以在application节点中添加一个receiver标签,以及指定要注册的Broadcast Receiver的类名。接收器节点中需要包含一个intent-filter标签来指定要监听的动作字符串。如下:
<span style="font-size:14px;"><receiver android:name="com.happy.demo.MyBroadcastReceiver" > <intent-filter> <action android:name="com.happy.demo.one" /> </intent-filter> </receiver></span>
5.广播有序的Intent
当Broadcast Receiver接收Intent的顺序十分重要时,特别是当需要将来接收器能够影响将来的接收器收到的Broadcast Intent时,可以使用sendOrderedBroadcast方法,如下:
<span style="font-size:14px;">String requiredPermission = "com.happy.demo.one"; sendOrderedBroadcast(intent, requiredPermission);</span>
使用这个方法时,Intent将会按照优先顺序被传递给所有具有合适权限的已注册的接收器。可以在manifest.xml中使用android:priority属性指定其权限,值越大,代表优先级越高。
<span style="font-size:14px;"> <receiver android:name="com.happy.demo.MyBroadcastReceiver" android:permission="android.permission.ACCESS_CHECKIN_PROPERTIES" > <intent-filter android:priority="1000" > <action android:name="com.happy.demo.one" /> </intent-filter> </receiver></span>
发送有序广播的一种常见例子是广播想要收到其结果数据的Intent。使用sendOrderedBroadcast方法时,可以指定一个将放到接收器队列末尾的接收器,而从保证当Broadacst Receiver已被已注册的有序Broadcast Receiver处理和修改后,它也能接收到该Broadcast Intent。
在这种情况下,对于那些在返回给最后一个接收器之前可能被任何收到广播的接收器修改的Intent结果、数据和extra,为他们指定默认值通常很有帮助。如下:
<span style="font-size:14px;">sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras);</span>
6.广播Stick Intent
Stity Intent是Broadcast Intent的有用变体,可以保存他们最后一次广播的值,并且当有一个新的接收器被注册为接收该广播时,他们会把这些值作为Intent返回。
当调用registerReceiver来指定一个匹配的Sticy Broadcast Intent的Intent Filter时,返回值将是最后一个Intent广播,例如电池电量变化的广播
7.Local Boradcast Manager
局部广播管理器包含在Android Support Library中,用户简化注册Broadcast Inten以及在应程序内的组件之间发送Broadcast Intent的工作。因为局部广播的作用域要小,所以使用它比发送全局广播更加高效,而且也确保了应用程序外部的任何组件都收不到我们的广播Intent,所以也是安全的。与之相同,其他应用程序也不能向我们的接收器发送广播,避免了这些接收器成为安全漏洞。
获取Local Broadcast Manager的方法如下:
<span style="font-size:14px;">LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getApplicationContext());</span>
注册一个局部广播接收者和注册全局的一样,代码如下:
<span style="font-size:14px;">lbm.registerReceiver(receiver, intentFilter);</span>
要发送一个局部Broadcast Intent,可以使用Local Boradcast Manager的sendBroadcast方法,并传入要广播的Intent。如下:
<span style="font-size:14px;">lbm.sendBroadcast(intent);</span>
8.Pending Intent简介
PendingIntent类提供了一种创建可由其他应用程序在稍晚的时间触发的Intent的机制。
PendingIntent通常用于包装在响应将来的事件时触发的Intent,例如单机Widget或者Notification。
PendingIntent类提供了构建PendingIntent的静态方法,以便启动Activity Service或者广播Intent。
<span style="font-size:14px;">PendingIntent.getActivity(context, requestCode, intent, flags); PendingIntent.getService(context, requestCode, intent, flags); PendingIntent.getBroadcast(context, requestCode, intent, flags);</span>
PendingIntent类包含了一些静态常量,他们可以用于指定标志,以更新或取消与指定动作匹配的现有PendingIntent,也可以用于指定该Intent是否只触发一次。