今天闲来无事,研究了下Android的Broadcast,发现Broadcast在Android系统中担任着很艰巨的角色。

Broadcast是Android的四大组件之一;Broadcast分为普通广播和无序广播。

有序广播可以设置优先级,优先级高的接收者可以终止广播的传播。但是在普通广播中,优先级高的就不能终止广播的传播。

     /**
* 发送一个普通广播
*/
private void sendBroadcasts() {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction("com.zhj.test");
intent.putExtra("msg", "hello world!");//参数
sendBroadcast(intent);
} /**
* 发送一个有序广播
*/
private void sendSortBroadcasts() {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction("com.zhj.test");
intent.putExtra("msg", "hello world!");//参数
sendOrderedBroadcast(intent, null);
}

广播按注册方式分为动态注册和静态注册;

(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)

下面是一个动态注册广播的例子:

     private static SortedBroadcast mSortedBroadcast = null;
//注册广播
private void registerHomeKeyReceiver(Context context) {
mSortedBroadcast = new SortedBroadcast();
final IntentFilter homeFilter = new IntentFilter(
Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
homeFilter.setPriority(1000);
context.registerReceiver(mSortedBroadcast, homeFilter);
}
//销毁广播
private void unregisterHomeKeyReceiver(Context context) {
if (null != mSortedBroadcast) {
context.unregisterReceiver(mSortedBroadcast);
}
} @Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
registerHomeKeyReceiver(this);//可以不再此处注册
} @Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterHomeKeyReceiver(this);//可以不再此处销毁
}

下面的一个广播接受器实现了接收点击Home键发出的广播(点击Home键发出的广播必须使用静态注册才可以监听到)

 /**
* 本篇主要实现了对Home键的监听
*
* @author Administrator
*
*/
public class SortedBroadcast extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
// 接收自定义的广播
if (intent.getAction().equals("com.zhj.test")) {
String str = intent.getStringExtra("msg");// 接收发送广播的时候传递的参数
Toast.makeText(context, "receiver2:" + str, Toast.LENGTH_SHORT)
.show();
abortBroadcast();
} // 对Home键的监听
if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra("reason");
if (reason.equals("homekey")) {
Toast.makeText(context, "短按Home键", Toast.LENGTH_SHORT).show();
} else if (reason.equals("recentapps")) {
Toast.makeText(context, "长按/双击 Home键", Toast.LENGTH_SHORT)
.show();
} else if (reason.equals("lock")) {
Toast.makeText(context, "锁屏", Toast.LENGTH_SHORT).show();
} else if (reason.equals("assist")) {
Toast.makeText(context, "未知" + reason, Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(context, "event:" + reason, Toast.LENGTH_SHORT)
.show();
}
abortBroadcast();//终止广播的传递(仅在接收有序广播的时候有效)
}
}
}

通过广播启动一个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);
}

=

05-11 17:57