Android广播相关内容

广播拦截和abort短信

普通广播(Normal Broadcast):

优缺点:和有序广播的优缺点相反!

发送广播的方法:
sendBroadcast()

有序广播(Ordered Broadcast):

优缺点
优点:1.按优先级的不同,优先Receiver可对数据进行处理,并传给下一个Receiver
2.通过abortBroadcast可终止广播的传播
缺点:效率低

发送广播的方法:
sendOrderedBroadcast()

特点:
优先接收到Broadcast的Receiver可通过setResultExtras(Bundle)方法将处理结果存入Broadcast中,下一个Receiver 通过 Bundle bundle=getResultExtras(true)方法获取上一个 Receiver传来的数据。

实现拦截广播,abort短信的代码如下

public class SmsReceiver extends BroadcastReceiver {
        // 当接收到短信时被触发
        @Override
        public void onReceive(Context context, Intent intent) {
            // 如果是接收到短信
            if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
                // 取消广播(这行代码将会让系统收不到短信)
                abortBroadcast();
                StringBuilder sb = new StringBuilder();
                // 接收由SMS传过来的数据
                Bundle bundle = intent.getExtras();
                // 判断是否有数据
                if (bundle != null) {
                    // 通过pdus可以获得接收到的所有短信消息
                    Object[] pdus = (Object[]) bundle.get("pdus");
                    // 构建短信对象array,并依据收到的对象长度来创建array的大小
                    SmsMessage[] messages = new SmsMessage[pdus.length];
                    for (int i = 0; i < pdus.length; i++) {
                        messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    }
                    // 将送来的短信合并自定义信息于StringBuilder当中
                    for (SmsMessage message : messages) {
                        sb.append("短信来源:");
                        // 获得接收短信的电话号码
                        sb.append(message.getDisplayOriginatingAddress());
                        sb.append("\n------短信内容------\n");
                        // 获得短信的内容
                        sb.append(message.getDisplayMessageBody());
                    }
                }
                Toast.makeText(context, sb.toString(), 5000).show();
            }
        }
    }

有序广播,添加权限




    

        

            

                
            
        
    
    

    


广播是否可以请求网络

直接请求网络是不可以的,需要开启线程请求。但是onReceived方法的周期比较短暂,可能出现广播关闭,线程还没结束,系统容易杀死无组件的进程,导致线程也被杀死。好的方式例如启动一个IntentService等。

广播引起anr的时间限制

在onReceive函数中不能做耗时操作,参考值在10s以内。严格上讲,系统级别监听的broadcastReceiver激活后也只能最多运行10秒钟,如果10秒内还没有处理完业务,Android会认为该程序无响应,并弹出ANR(application No Response)对话框。对于这种”限制“,我们处理这种限制的方式,也是项目中用到的最多一种方法:启动service。最可靠的方式是在广播中启动一个service,让service在后台去处理数据,这样就算广播生命周期结束,service也不会被销毁,因为用startService这种方式启动的service,就算访问者(广播)销毁自己也不会销毁,而且本来在广播中处理数据的耗时操作,交给了service去做,同时避免了ANR问题的出现。用启动新线程的方式也不可靠,广播的生命周期,就是内部onReceive方法的周期,当onReceiver方法结束,也就意味着广播的结束。
虽然我们可以在onReceiver内执行启动一个新线程执行耗时的业务,由于onReceiver方法周期很短暂,可能出现的情况是:子线程还没有结束广播就关闭了,广播一旦关闭,虽然子线程还可以运行,但系统会认为广播处于无组件活动的状态,在内存紧张的时候优先结束该进程,这样可能会导致子线程不能执行完任务。所以最好的方式是启动service。

你可能感兴趣的:(Android广播相关内容)