安卓系统大量的使用了Broadcast Intents去广播系统的事件,好比网络链接、底座模式的状态、电话接听状态等。 java
固然也能够自定义的去广播。 android
当你广播消息的时候,Intent指定action,data,和category,这样准确去肯定由哪一个广播接受者去接受广播。 git
对于自定义的action,为了避免重名,一般是以包名为开头,如:
public static final String NEW_LIFEFORM_DETECTED =“com.paad.action.NEW_LIFEFORM”; 网络
咱们知道intent是能够指定uri标识数据(setData),或者添加额外的基础类型数据: app
例子:
框架
Intent intent = new Intent(LifeformDetectedReceiver.NEW_LIFEFORM); intent.putExtra(LifeformDetectedReceiver.EXTRA_LIFEFORM_NAME, detectedLifeform); intent.putExtra(LifeformDetectedReceiver.EXTRA_LONGITUDE, currentLongitude); intent.putExtra(LifeformDetectedReceiver.EXTRA_LATITUDE, currentLatitude); sendBroadcast(intent);
那就是大名鼎鼎的BroadcastReceiver(广播接受者)来接收Broadcast Intents。 ide
做为组件之一,像activity同样,也能够为其定义intent-filter这里先不讨论。 ui
固然须要为其注册,像activity同样,对于广播接受者,注册方式分为2种:第一种在代码中动态注册,第二种就像activity同样在mainfest中直接注册声明。 线程
在mainfest中的接受者,不须要自我的所在的app跑起来,当有合适的Intent发来的时候,它会自动启动。 code
BroadcastReceiver 框架代码:
public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //TODO: React to the Intent received. } }
这个Reiceiver的onReceive方法默认在主线程中执行,因此避免ANR,不要作耗时的操做。
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); } } }
private IntentFilter filter = new IntentFilter(LifeformDetectedReceiver.NEW_LIFEFORM); private LifeformDetectedReceiver receiver = new LifeformDetectedReceiver(); @Override public void onResume() { super.onResume(); // 在运行时注册。 registerReceiver(receiver, filter); } @Override public void onPause() { // 在暂停状态注销。 unregisterReceiver(receiver); super.onPause(); }
<receiver android:name=”.LifeformDetectedReceiver”> <intent-filter> <action android:name=”com.paad.alien.action.NEW_LIFEFORM”/> </intent-filter> </receiver>
就是发送有序的广播,根据广播接受者的优先级不一样,优先级高的接收者能够优先接受到发来的有序广播,除非你中途停止了广播(abortBroadcast),否则会继续往下传播。
那么如何广播有序的Intents?
String requiredPermission = “com.paad.MY_BROADCAST_PERMISSION”;
sendOrderedBroadcast(intent, requiredPermission);
<receiver android:name=”.MyOrderedReceiver” android:permission=”com.paad.MY_BROADCAST_PERMISSION”> <intent-filter android:priority=”100”> <action android:name=”com.paad.action.ORDERED_BROADCAST” /> </intent-filter> </receiver>
代码中的话:
IntentFilter 对象的setPriority便可。
一个常见的例子来接收有序广播:目标是接收一个处理过的结果集。首先把最终接收到结果的接受者优先级设低点,而后比它高的接受者优先处理了这些数据,层层处理,最后的接受者接收到的会是最终的结果。
//在未被最后个接受者接收时,所初始化的值。
int initialResult = Activity.RESULT_OK;
String initialData = null;
String initialExtras = null;
// A special Handler instance on which to receive the final result.
// Specify null to use the Context on which the Intent was broadcast.
Handler scheduler = null;
sendOrderedBroadcast(intent, requiredPermission, finalResultReceiver,
scheduler, initialResult, initialData, initialExtras);
怎么得到最终的值?
在接受者的onReceive里,能够get到这些值。
英文意思解释起来貌似是粘性的Intent(意图),那么什么是粘性的呢?与其它的intent有什么不一样?
答:这种intent会保存与最后一个广播相关的值,也就是说下一个接收到的也是最近的值。
IntentFilter battery = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent currentBatteryCharge = registerReceiver(null, battery);
上述代码,你会发现注册的接收者竟然是为null,首先这里是为了接收到当前系统电池状态的广播intent---系统设备状态广播(好比电池、还有底座状态等),它们广播的是Sticky Intents,因此你常常不须要去弄个接收者去接收这些intents. 只要像上面代码那样registerReceiver它会返回最新的intent。
那么我如何去广播我本身的Sticky intents?
答:首先,你的App的mainfest必须包含BROADCAST_STICKY权限。而后在程序中,你就可使用sendStickyBroadcast(intent)去发送这样的广播。
既然你说这种Intent会保留下值来,那么我不想要了,如何移除它呢?
答:removeStickyBroadcast(intent).