- 正常广播 Normal broadcasts(用
Context.sendBroadcast
()发送)是完全异步的。它们都运行在一个未定义的顺序,通常是在同一时间。这样会更有效,但意味着receiver不能包含所要使用的结果或中止的API。 - 有序广播 Ordered broadcasts(用
Context.sendOrderedBroadcast()
发送)每次被发送到一个receiver。所谓有序,就是每个receiver执行后可以传播到下一个receiver,也可以完全中止传播——不传播给其他receiver。 而receiver运行的顺序可以通过matched intent-filter 里面的android:priority来控制,当priority优先级相同的时候,Receiver以任意的顺序运行。
@Override
public void onReceive(Context context, Intent intent) {
// get data from SMS intent
Bundle bundle = intent.getExtras();
if (bundle != null){
// get message by "pdus"
Object[] objArray = (Object[]) bundle.get("pdus");
// rebuild SMS
SmsMessage[] messages = new SmsMessage[objArray.length];
for (int i=0; i < objArray.length; i++){
messages[i] = SmsMessage.createFromPdu((byte[])objArray[i]);
StringBuilder str = new StringBuilder("from: ");
str.append(messages[i].getDisplayOriginatingAddress());
str.append("\nmessage:\n");
str.append(messages[i].getDisplayMessageBody());
Toast.makeText(context, str.toString(), Toast.LENGTH_LONG)
.show();
}
}
}
}
1. 静态方式,在AndroidManifest.xml的application里面定义receiver并设置要接收的action。
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
2. 动态方式, 在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。
private BroadcastReceiver receiver;
@Override
protected void onStart() {
super.onStart();
receiver = new CallReceiver();
registerReceiver(receiver, new IntentFilter("android.intent.action.PHONE_STATE"));
}
@Override
protected void onStop() {
unregisterReceiver(receiver);
super.onStop();
}
}
而且动态注册,需要特别注意的是,在退出程序前要记得调用Context.unregisterReceiver()方法。一般在activity的onStart()里面进行注册, onStop()里面进行注销。官方提醒,如果在Activity.onResume()里面注册了,就必须在Activity.onPause()注销。
要接收某些action,需要在AndroidManifest.xml里面添加相应的permission。例如接收SMS:
下面给出动态注册的接收来电的广播处理的CallReceiver的代码:
@Override
public void onReceive(Context context, Intent intent) {
TelephonyManager teleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
switch(teleManager.getCallState()){
case TelephonyManager.CALL_STATE_RINGING: //响铃
Toast.makeText(context, "Ringing: " + intent.getStringExtra("incoming_number"), Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK: //接听
Toast.makeText(context, "OffHook: " + intent.getStringExtra("incoming_number"), Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_IDLE: //挂断
Toast.makeText(m_context, "Idle: " + incomingNumber, Toast.LENGTH_LONG).show();
break;
}
}
}
private Context m_context;
@Override
public void onReceive(Context context, Intent intent) {
m_context = context;
TelephonyManager teleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
teleManager.listen(new PhoneStateListener(){
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch(state){
case TelephonyManager.CALL_STATE_RINGING: //响铃
Toast.makeText(m_context, "Ringing: " + incomingNumber, Toast.LENGTH_LONG)
.show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK: //接听
Toast.makeText(m_context, "OffHook: " + incomingNumber, Toast.LENGTH_LONG)
.show();
break;
case TelephonyManager.CALL_STATE_IDLE: //挂断
Toast.makeText(m_context, "Idle: " + incomingNumber, Toast.LENGTH_LONG)
.show();
break;
}
}}, PhoneStateListener.LISTEN_CALL_STATE);
}
}
2. 推荐使用显式指明receiver,在配置文件AndroidManifest.xml指明;
3. 一个receiver可以接收多个action;