今天闲来无事,研究了下Android的Broadcast,发现Broadcast在Android系统中担任着很艰巨的角色。
Broadcast是Android的四大组件之一;Broadcast分为普通广播和无序广播。
有序广播可以设置优先级,优先级高的接收者可以终止广播的传播。但是在普通广播中,优先级高的就不能终止广播的传播。
1 /** 2 * 发送一个普通广播 3 */ 4 private void sendBroadcasts() { 5 // TODO Auto-generated method stub 6 Intent intent = new Intent(); 7 intent.setAction("com.zhj.test"); 8 intent.putExtra("msg", "hello world!");//参数 9 sendBroadcast(intent); 10 } 11 12 /** 13 * 发送一个有序广播 14 */ 15 private void sendSortBroadcasts() { 16 // TODO Auto-generated method stub 17 Intent intent = new Intent(); 18 intent.setAction("com.zhj.test"); 19 intent.putExtra("msg", "hello world!");//参数 20 sendOrderedBroadcast(intent, null); 21 }
广播按注册方式分为动态注册和静态注册;
(1)静态注册:
静态注册是直接在AndroidManifest.xml中配置,规则如下:
<receiver android:enabled=["true" | "false"] android:exported=["true" | "false"] android:icon="drawable resource" android:label="string resource" android:name="string" android:permission="string" android:process="string" > . . . </receiver>
其中,需要注意的属性
android:exported ——此broadcastReceiver能否接收其他App的发出的广播,这个属性默认值有点意思,其默认值是由receiver中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。(同样的,activity/service中的此属性默认值一样遵循此规则)同时,需要注意的是,这个值的设定是以application或者application user id为界的,而非进程为界(一个应用中可能含有多个进程);
android:name —— 此broadcastReceiver类名;
android:permission ——如果设置,具有相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收;
android:process ——broadcastReceiver运行所处的进程。默认为app的进程。可以指定独立的进程(Android四大基本组件都可以通过此属性指定自己的独立进程)
常见的注册方式为:
<receiver android:name=".MyBroadcastReceiver" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
(2)动态注册:
动态注册时,无须在AndroidManifest中注册<receiver/>组件。直接在代码中通过调用Context的registerReceiver函数,可以在程序中动态注册BroadcastReceiver。registerReceiver的定义形式如下:
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)
下面是一个动态注册广播的例子:
1 private static SortedBroadcast mSortedBroadcast = null; 2 //注册广播 3 private void registerHomeKeyReceiver(Context context) { 4 mSortedBroadcast = new SortedBroadcast(); 5 final IntentFilter homeFilter = new IntentFilter( 6 Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 7 homeFilter.setPriority(1000); 8 context.registerReceiver(mSortedBroadcast, homeFilter); 9 } 10 //销毁广播 11 private void unregisterHomeKeyReceiver(Context context) { 12 if (null != mSortedBroadcast) { 13 context.unregisterReceiver(mSortedBroadcast); 14 } 15 } 16 17 @Override 18 protected void onResume() { 19 // TODO Auto-generated method stub 20 super.onResume(); 21 registerHomeKeyReceiver(this);//可以不再此处注册 22 } 23 24 @Override 25 protected void onPause() { 26 // TODO Auto-generated method stub 27 super.onPause(); 28 unregisterHomeKeyReceiver(this);//可以不再此处销毁 29 }
下面的一个广播接受器实现了接收点击Home键发出的广播(点击Home键发出的广播必须使用静态注册才可以监听到)
1 /** 2 * 本篇主要实现了对Home键的监听 3 * 4 * @author Administrator 5 * 6 */ 7 public class SortedBroadcast extends BroadcastReceiver { 8 9 @Override 10 public void onReceive(Context context, Intent intent) { 11 // 接收自定义的广播 12 if (intent.getAction().equals("com.zhj.test")) { 13 String str = intent.getStringExtra("msg");// 接收发送广播的时候传递的参数 14 Toast.makeText(context, "receiver2:" + str, Toast.LENGTH_SHORT) 15 .show(); 16 abortBroadcast(); 17 } 18 19 // 对Home键的监听 20 if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { 21 String reason = intent.getStringExtra("reason"); 22 if (reason.equals("homekey")) { 23 Toast.makeText(context, "短按Home键", Toast.LENGTH_SHORT).show(); 24 } else if (reason.equals("recentapps")) { 25 Toast.makeText(context, "长按/双击 Home键", Toast.LENGTH_SHORT) 26 .show(); 27 } else if (reason.equals("lock")) { 28 Toast.makeText(context, "锁屏", Toast.LENGTH_SHORT).show(); 29 } else if (reason.equals("assist")) { 30 Toast.makeText(context, "未知" + reason, Toast.LENGTH_SHORT) 31 .show(); 32 } else { 33 Toast.makeText(context, "event:" + reason, Toast.LENGTH_SHORT) 34 .show(); 35 } 36 abortBroadcast();//终止广播的传递(仅在接收有序广播的时候有效) 37 } 38 } 39 }
通过广播启动一个activity,当我们通过一个广播启动activity的时候,程序强行停止,报错
经过一番查找,发现通过以下的方式可以启动:
@Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Intent intent2 = new Intent(context, StartActivity.class); intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent2); }
=