广播BroadcastReceiver

    |     2015年7月21日   |   Receiver广播   |     0 条评论   |    1930

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


一、广播示意图与两种注册

Android 广播示意图:

QQ╜╪═╝20150721155254

静态广播(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 可截流。

转载请注明来源:广播BroadcastReceiver
本文链接地址:https://ai.zhousir.top/?p=901
回复 取消