Android开发之短信拦截--BroadcastReceiver学习

来源:互联网 发布:有哪些相亲软件 编辑:程序博客网 时间:2024/06/09 02:35

今天工作中遇到一点小问题和心得,正好分享出来让大家今后少走弯路。


基础知识部分:

首先,Android提供了一个应用可以获取系统事件的手段:BroadcastReceiver,这个组件属于系统四大组件之一,非常强大。应用可以在系统中注册一个BroadcastReceiver组件,之后系统如有广播事件抛出,应用可以通过receiver中设置的intent-filter来过滤到自己想要的消息。

注册BroadcastReceiver可以使用两种方法:

  1. 通过在AndroidManifest.xml文件中定义<Receiver>字段静态注册;
  2. 通过在程序中Context.registerReceiver()动态注册;

那么,应用怎么确定获取消息的先后顺序呢?Android提供了两种类型的Broadcast:

  1. Normal broadcast:应用抛出的这种类型的广播是异步的,应用接收到的顺序也是不可控制的;同时,应用无法选择是否不将该广播传递给下一个应用(系统会自动派发管理,保证每一个应用都可接收到该广播);
  2. Ordered broadcast:应用按顺序处理该广播,并且可以决定是否将广播消息继续传递下去;接收到广播的顺序按照android:priority属性值决定(程序中同样可以控制),同一个priority值的应用按照应用的包名的字符顺序排列顺序来决定接收广播的顺序;

ok,应用获取消息的顺序,如何获取广播消息等基础知识讲完了,那么我们来看看如何截获短信:

首先应用需要注册一个Receiver,短信是一个Ordered broadcast,我们的例子里面使用静态方法注册:

 <receiver android:name=".SmsReceiver"> <intent-filter android:priority="2324324234">  <action android:name="android.provider.Telephony.SMS_RECEIVED" />   </intent-filter>  </receiver>

注意这里的priority可以适当设置大一点,只要不超过Integer.MAX_VALUE就可以。紧接着下面就可以在onReceive里面处理广播来的消息。

public class SmsReceiver extends BroadcastReceiver {private static final String LOG_TAG = "[SmsReceiver]";private Context context = null;@Overridepublic void onReceive(Context context, Intent intent) {this.context = context;Log.e(LOG_TAG, "---on Receive = ");}}

如果需要取消后续receiver对broadcast消息的响应,在onReceive中调用abortBroadcast();即可。







后面的故事:

今天调试程序的时候发现过两个问题,解决方法和思路同时提供:

  • 短信先被盛大的”Youni短信“程序拦截

经查,是由于priority设置过小所致,调大到priority并且将包名设置的比”Youni短信“程序排名靠前即可。

  • 短信在双卡手机中拦截时出现异常

经厂商提醒,是由于Android默认不支持双卡而SmsMessage.createFromPdu这个方法调用了TelephonyManager.getDefault().getPhoneType();所致。具体参见Android源码:

publicstatic SmsMessage createFromPdu(byte[] pdu) {SmsMessageBase wrappedMessage;int activePhone = TelephonyManager.getDefault().getPhoneType();if (PHONE_TYPE_CDMA == activePhone) {wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);} else {wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);}returnnew SmsMessage(wrappedMessage);}
具体解决方案我就不赘述了,请大家参见http://www.cnblogs.com/sinber/archive/2011/06/22/CDMA_GSM_SMS.html这篇文章吧。


但还有个问题:我们的应用希望拦截短信并且不再给后续的receiver抛出消息,但在这种双卡手机中又必须去读取短信数据,实在想不到更好用的方法了,纠结啊。。。




补充:

实际上之前讲的大部分内容无论动态创建监听器或静态创建都是适用的,不过还存在以下的顺序导致你的程序可能监听不到短信内容,这里仅讨论优先级大家都相同的情况:

  1. 动态注册(RegistReceiver)的应用优先级高于静态注册(AndroidManifest.xml);
  2. 大家都是动态注册的情况下,先注册的应用优先级更高一些;
  3. 大家都是静态注册的情况下,按照字符排列顺序决定谁先收到广播消息;




原创粉丝点击