Broadcast Receiver(广播接收者)可以用来监听Broadcast Intent。要使Broadcast Receiver能接收广播,就需要对其进行注册,既可以使用代码,也可以在应用程序的manifest文件中注册。无论怎么注册,都需要使用一个Intent Filter来自定它需要监听哪些Intent和数据。
要创建一个新的Broadcast Receiver,需要扩展BroadcastReceiver类并重写onReceive事件处理方法。
public class MyReceiver extends BroadcastReceiver { private static final String TAG = "My Receiver"; public static final String ACTION = "com.paad.intents.MyReceiverAction"; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "My Receiver Received Broadcast"); } }
下面这段代码展示如何实现一个Broadcast Receiver,通从Broadcast Intent中提取数据和几个extra,并使用它们来启动一个新的Activity。在下面的部分中,将会学习如何在代码和应用程序的manifest中注册它。
public class LifeformDetectedReceiver extends BroadcastReceiver { public final static String EXTRA_LIFEFORM_NAME = "EXTRA_LIFEFORM_NAME"; public final static String EXTRA_LATITUDE = "EXTRA_LATITUDE"; public final static String EXTRA_LONGITUDE = "EXTRA_LONGITUDE"; public static final String ACTION_BURN = "com.paad.alien.action.BURN_IT_WITH_FIRE"; public static final String NEW_LIFEFORM = "com.paad.alien.action.NEW_LIFEFORM"; @Override public void onReceive(Context context, Intent intent) { // Get the lifeform details from the intent. Uri data = intent.getData(); String type = intent.getStringExtra(EXTRA_LIFEFORM_NAME); double lat = intent.getDoubleExtra(EXTRA_LATITUDE, 0); double lng = intent.getDoubleExtra(EXTRA_LONGITUDE, 0); Location loc = new Location("gps"); loc.setLatitude(lat); loc.setLongitude(lng); if (type.equals("facehugger")) { Intent startIntent = new Intent(ACTION_BURN, data); startIntent.putExtra(EXTRA_LATITUDE, lat); startIntent.putExtra(EXTRA_LONGITUDE, lng); context.startService(startIntent); } } }
在代码中注册BroadcastReceiver
影响特定Activity的UI的Broadcast Receiver通常在代码中注册。在代码中注册的接收器知会在包含它的应用程序组件运行时响应Broadcast Intent。
下面是利用一个IntentFilter来注册和注销一个BroadcastReceiver的事例:
/** * Registering and unregistering a Broadcast Receiver in code */ private IntentFilter filter = new IntentFilter(LifeformDetectedReceiver.NEW_LIFEFORM); private LifeformDetectedReceiver receiver = new LifeformDetectedReceiver(); @Override public synchronized void onResume() { super.onResume(); // Register the broadcast receiver. registerReceiver(receiver, filter); } @Override public synchronized void onPause() { // Unregister the receiver unregisterReceiver(receiver); super.onPause(); }
除了可以在代码中注册BroadcastReceiver之外,还可以在manifest配置文件中注册
实例:
<receiver android:name=".MyReceiver"> <intent-filter> <action android:name="com.paad.intents.MyReceiverAction" /> </intent-filter> </receiver>
广播有序的Intent
当Broadcast Receiver 接收Intent的顺序十分重要时,特别是当需要Broadcast Receiver能够影响将来的接收器收到的Broadcast Intent时,可以使用sendOrderedBroadcast方法,如下:
String permission = "com.xxx.MY_BROADCAST_PERMISSION";
sendOrderedBroadcast(intent,permission);
使用这个方法时,Intent将会按照优先级顺序被传递给所有具有合适权限(当指定了权限时)的已注册的BroadcastReceiver。可以在Broadcast Receiver的Intent Filter manifest节点中使用android:priority属性指定其权限,值越大,代表优先级越高。
<receiver android:name=".MyReceiver" > <intent-filter android:priority="100"> <action android:name="com.paad.intents.MyReceiverAction" /> </intent-filter> </receiver>
Sticky Intent是Broadcast Receiver的有用变体,可以保存它们最后一次广播的值,并且当有一个新的Broadcast Receiver被注册为接收该广播时,它们会把这些值作为Intent返回。
当调用registerReceiver来指定一个匹配Sticky Broadcast Intent的Intent Filter时,返回值将是最后一次Intent广播,例如电池电量变化的广播。
发送粘性广播:sendStickyBroadcast(intent)。
删除一个粘性广播,可以调用removeStickyBroadcast,并传入要删除的Sticky Intent。
removeStickyBroadcast(intent)。