广播是应用之间传消息的机制。电池状态、来电、短信都会发出广播。开发者实现 BroadcastReceiver 监听这些 Intent,再做业务处理。发送靠 Context.sendBroadcast() / sendOrderedBroadcast(),同一条广播可被多个订阅者收到。
一、广播示意图与两种注册
Android 广播示意图:

静态广播(Manifest 注册)
public class MyBroadcastReceiver extends BroadcastReceiver {
String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED)) {
// 相关处理:地域变换、电量不足、来电来信
}
}
}
<receiver android:name=".MyBroadcastReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
动态广播(代码注册)
private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 相关处理,如收短信,监听电量变化
}
};
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(myBroadcastReceiver, intentFilter);
二、生命周期:onReceive 别做重活
每次广播到来都会新建 Receiver 对象、调用 onReceive(),执行完对象即销毁。生命周期大约十秒;onReceive 超过约 10 秒,系统会当无响应,弹出 ANR。
耗时工作应发 Intent 给 Service 去做,不要开子线程糊弄:Receiver 很快结束,所在进程变成空进程,内存紧张时优先被杀,子线程一起死。
三、广播类型与注册注销
| 类型 |
行为 |
| 普通 / 无序广播 |
所有监听者都能收到 |
| 有序广播 |
按 intent-filter 的 priority(-1000~1000,越大越先)接收;可改内容;abortBroadcast() 可中止向下传播 |
| 粘性 / 异步广播 |
sendStickyBroadcast(intent) |
代码注册:registerReceiver(BroadcastReceiver, IntentFilter)。注销:unregisterReceiver(...)。Activity 里建议在 onPause() 注销。
四、实例:短信 / 自定义 / 电话状态
步骤:1. 定义 Receiver;2. 注册。下面同时处理短信、自定义 Action、去电、来电状态。
public class SmsBroadCastReceiver extends BroadcastReceiver {
private static boolean incomingFlag = false;
private static String incoming_number = null;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("android.provider.Telephony.SMS_RECEIVED")) {
Toast.makeText(context, "接收短消息静态广播", Toast.LENGTH_SHORT).show();
Logs.v("接收短消息静态广播 >>>>>>>>>>>>>>>> ");
} else if (action.equals(MyReceiverActivity.ACTION_SCXH)) {
Toast.makeText(context, "自定义静态广播接收到", Toast.LENGTH_SHORT).show();
Logs.v("自定义静态广播 >>>>>>>>>>>>>>>> ");
} else if (action.equals("android.intent.action.NEW_OUTGOING_CALL")) {
incomingFlag = false;
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Logs.i("拨打电话:" + phoneNumber);
} else if (action.equals("android.intent.action.PHONE_STATE")) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
switch (tm.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
incomingFlag = true;
incoming_number = intent.getStringExtra("incoming_number");
Logs.i("来电 :" + incoming_number);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if (incomingFlag) {
Logs.i("摘机(正在通话中) :" + incoming_number);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if (incomingFlag) {
Logs.i("空闲 >>>>>");
}
break;
}
}
}
}
Manifest 注册与权限:
<receiver android:name="com.warmtel.android.receiver.systemreceiver.SmsBroadCastReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<action android:name="com.warmtel.android.receiver_ACTION_XH" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
发送自定义广播:
Intent intent = new Intent("com.warmtel.android.receiver_ACTION_XH");
sendBroadcast(intent);
五、电话监听 PhoneStateListener
private void receiverPhoneStateListener(){
TelephonyManager tpm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
tpm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
}
class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Logs.d("空闲 >>>>> ");
break;
case TelephonyManager.CALL_STATE_RINGING:
Logs.v("来电 >>>>> ");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Logs.w("摘机(正在通话中) >>>>> ");
break;
}
}
}
一句话总结:BroadcastReceiver 过滤 Intent;静态写 Manifest、动态 register/unregister。onReceive 要快,重活交给 Service。有序广播靠 priority,abortBroadcast 可截流。