之前在写通讯录应用时,将整体的代码写完后,自测时发现非常非常多的问题,其中一个非常重要严重的就是可以发出短信,但收不到任何的短信息,这搞的我好捉鸡啊!后来调试发现是由于没有收到短信的消息导致的,然后将自己手机中的QQ通讯录尝试着卸载掉,这时就可以收到了.

后来有时间了在网上查找相关资料,并且按照网上的理论编写了代码测试,解决了这个问题,在这里通过博客把解决的方法记录下来.

首先要知道广播分为无序,有序,sticky三种广播

无序广播应该最常用的,就是普通的广播,任何BroadcastReceiver都可以收到的广播,但是多个BroadcastReceiver在接受无序广播时也是有顺序前后之分的,也就是说每个BroadcastReceiver都会排队来接受无序广播,至于前后的顺序是怎么样的可以通过优先级等来设置.

有序广播也就是说最先收到有序广播的BroadcastReceiver在截获到这个广播后,可以选择继续下发此广播,或者中断此广播的发送,如果中断此有序广播的话,那么后面排队等待的BroadcastReceiver将接受不到此广播了,比如android系统在接受到短信息时所发送的广播"android.provider.Telephony.SMS_RECEIVED"就是有序广播

sticky广播由于暂时没有使用到,所以还不了解,等需要的时候再做研究

BroadcastReceiver广播接收器可以分为静态和动态的两种

静态接收器就是在AndroidManifest.xml注册的

动态接收器则是在代码中注册的

要了解很重要的一点:在相同优先级的情况下,动态接收器接受到广播的优先级会比静态接收器接受到广播的优先级高!

在了解上面的理论知识后,就开始实践下如何最先截获短信

首先在测试程序中静态注册广播接收器,并且将接受短信广播消息优先级设置为最高(一般第三方程序都会设置成最高)

AndroidManifest.xml

  1. <receiver
  2. android:name="huahua.interceptsms.MyReceiver">
  3. <intent-filter android:priority="2147483647">
  4. <action android:name="android.provider.Telephony.SMS_RECEIVED" />
  5. <action android:name="android.intent.action.BOOT_COMPLETED" />
  6. </intent-filter>
  7. </receiver>

MyReceiver.java

  1. package huahua.interceptsms;
  2. import android.app.Service;
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.os.Vibrator;
  7. import android.util.Log;
  8. public class MyReceiver extends BroadcastReceiver{
  9. @Override
  10. public void onReceive(Context context, Intent intent) {
  11. if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
  12. {
  13. Intent i =new Intent(context, MyService.class);
  14. context.startService(i);
  15. }
  16. if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
  17. Log.v("huahua", "MyReceiver收到短信发来的消息");
  18. }
  19. }
  20. }

这样就可以了很简单.然后给10086发短信, 10086回复短信后发现QQ通讯录收到短信了,但是"MyReceiver收到短信发来的消息"Log消息却没有打印,说明没收到.

这时我们就要采用动态注册的方法了

MainActivity.java

  1. package huahua.interceptsms;
  2. import android.os.Bundle;
  3. import android.app.Activity;
  4. import android.content.BroadcastReceiver;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.IntentFilter;
  8. import android.util.Log;
  9. public class MainActivity extends Activity {
  10. private SmsReceiver smsReceiver;
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_main);
  15. //动态注册接受短信消息
  16. IntentFilter localIntentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
  17. //设置优先级
  18. localIntentFilter.setPriority(Integer.MAX_VALUE);
  19. smsReceiver = new SmsReceiver();
  20. registerReceiver(smsReceiver, localIntentFilter);
  21. }
  22. private class SmsReceiver extends BroadcastReceiver{
  23. @Override
  24. public void onReceive(Context context, Intent intent) {
  25. // TODO Auto-generated method stub
  26. if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
  27. Log.v("huahua", "MainActivity收到短信发来的消息");
  28. }
  29. }
  30. }
  31. @Override
  32. protected void onDestroy() {
  33. // TODO Auto-generated method stub
  34. super.onDestroy();
  35. unregisterReceiver(smsReceiver);
  36. }
  37. }

在主Activity中,将广播的优先级同样设置为最高,然后启动程序,继续刚才的操作.发现还是被QQ通讯录收到短信了,Log信息"MainActivity收到短信发来的消息"也没打印出来

这是因为在相同优先级,同样都是动态注册的BroadcastReceiver在接受有序广播时,哪个BroadcastReceiver先注册,则哪个BroadcastReceiver可以先截获有序广播!

 
下面来证明这个理论
如何让自己最先注册到动态BroadcastReceiver呢? 我们可以在刚开机时,去创建一个Service,然后在Service中动态注册BroadcastReceiver.由于"android.intent.action.BOOT_COMPLETED"开机消息是个无序广播,那么每个应用都能收到,至于收到这个消息的顺序可以通过设置优先级.这里我在AndroidManifest.xml将开机广播优先级设置为最高,已保证第一个去注册动态BroadcastReceiver.
 

MyService.Java

  1. package huahua.interceptsms;
  2. import android.app.Service;
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.content.IntentFilter;
  7. import android.os.IBinder;
  8. import android.os.Vibrator;
  9. import android.util.Log;
  10. import android.widget.Toast;
  11. public class MyService extends Service{
  12. private SmsReceiver smsReceiver;
  13. @Override
  14. public IBinder onBind(Intent arg0) {
  15. // TODO Auto-generated method stub
  16. return null;
  17. }
  18. @Override
  19. public void onCreate() {
  20. // TODO Auto-generated method stub
  21. super.onCreate();
  22. //动态注册接受短信消息
  23. IntentFilter localIntentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
  24. //设置优先级
  25. localIntentFilter.setPriority(Integer.MAX_VALUE);
  26. smsReceiver = new SmsReceiver();
  27. registerReceiver(smsReceiver, localIntentFilter);
  28. //这里震动一秒钟,用来感受下刚开机是否马上收到开机消息,并启动Service
  29. Vibrator vib = (Vibrator)MyService.this.getSystemService(Service.VIBRATOR_SERVICE);
  30. vib.vibrate(1000);
  31. Log.v("huahua", "MyService启动"+ System.currentTimeMillis());
  32. Toast.makeText(MyService.this, "MyService启动", Toast.LENGTH_SHORT).show();
  33. }
  34. private class SmsReceiver extends BroadcastReceiver{
  35. @Override
  36. public void onReceive(Context context, Intent intent) {
  37. // TODO Auto-generated method stub
  38. if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
  39. Log.v("huahua", "MyService收到短信发来的消息");
  40. Vibrator vib = (Vibrator)MyService.this.getSystemService(Service.VIBRATOR_SERVICE);
  41. vib.vibrate(1000);
  42. //不将此短信消息下发给其他程序,如QQ通讯录等应用将收不到信息了
  43. abortBroadcast();
  44. }
  45. }
  46. }
  47. @Override
  48. public void onDestroy() {
  49. // TODO Auto-generated method stub
  50. super.onDestroy();
  51. unregisterReceiver(smsReceiver);
  52. }
  53. }

好了,现在将测试程序安装到手机中再重启机器.会发现刚开机就会震动1秒钟并且有打印信息,表示已经动态注册了

BroadcastReceiver,然后接受短信.这时终于可以看到Log信息"MyService收到短信发来的消息"打印出来了,并且QQ通讯录收不到任何短信了

记得还要在AndroidManifest.xml加入相应的权限

  1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  2. <uses-permission android:name="android.permission.RECEIVE_SMS"/>
  3. <uses-permission android:name="android.permission.VIBRATE" />

也许还有疑问:如果都把自己程序的"android.intent.action.BOOT_COMPLETED"开机消息设置为优先级最高,那谁会最先收到开机消息呢?

我这里做了个小实验,在自己的通讯录程序中和测试程序中都同样的设置最高优先级开机广播,然后打印信息发现

通讯录中的Serivce先启动,测试程序的Service后启动,那么很显然通讯录程序是先接受到开机广播的,那么也将会优先接收到有序广播

"android.provider.Telephony.SMS_RECEIVED"

关于哪个应用先收到这个开机消息,网上有大牛说跟apk的文件名有所关系.由于某些原因我没有测试

还有关于更多详细解释广播优先级问题,有兴趣的朋友可以自己看看这篇博客,讲解的很清楚

android安全问题(四) 抢先开机启动 - 结果篇

之前有听说别人投诉10086说自己智能机收不到短信了,很有可能一个原因就是自己手机下载了病毒或者不友善软件,其软件使用此方法来让其他程序都收不到短信消息

建议大家也自己写代码测试一下,这样更能加深体会

源码下载地址 :http://download.csdn.net/download/zhangxuebing2/6557371

来自:http://blog.csdn.net/huahuadashen/article/details/16337407

Android抢先截获短信(附源码)的更多相关文章

  1. 短信平台软件开发,短信发送平台销售,短信软件源码,G客短信发送平台

    一:web短信平台组成  需要短信软件平台源码的联系QQ:290615413 vx:290615413  整套短信系统平台还是由B/S(客户端+后台,取消了以前C/S的管理后台) ,C/S发送服务端和 ...

  2. 完整的Android手机短信验证源码

    短信验证功能我分两个模块来说,短信验证码的后台和代码实现短信验证码的功能. 一.短信验证码的后台      1.注册Mob账号:http://www.mob.com/#/login 2.注册成功之后, ...

  3. 【mob】Android短信验证+源码

    在很多的应用当中,都涉及到了短信验证的功能,比如在注册或者找回密码的时候,那么我们如何通过第三方的平台来完成这个功能呢? 本面博文就实现短信验证,来做一个小的栗子. 第一步-下载开发包 第二步-将SD ...

  4. Android-看操作系统短信应用源码-隐式意图激活短信界面

    选择模拟器Unknown Google Nexus,在选择system_process(系统进程) 操作模拟器的,操作系统短信应用,让操作系统短信打印日志,来查看: 然后就找到来,操作系统短信应用打印 ...

  5. 网页短信平台源码和开发功能介绍 思路和功能 G客短信平台

    G客短信源码介绍 (只介绍现有功能模块文字介绍配系统截图) 一:后台首页 ​ QQ:290615413 VX:290615413

  6. 10个经典的Android开源项目(附源码包)

    最近在抽空学习Android系统开发,对Android学习也比较感兴趣,刚开始学就试着在网上找几个项目源码研究看下,以下就将找到的Android项目源码列出,希望对正在或准备学习Android系统开发 ...

  7. Android中Canvas绘图基础详解(附源码下载) (转)

    Android中Canvas绘图基础详解(附源码下载) 原文链接  http://blog.csdn.net/iispring/article/details/49770651   AndroidCa ...

  8. 50个Android开发人员必备UI效果源码[转载]

    50个Android开发人员必备UI效果源码[转载] http://blog.csdn.net/qq1059458376/article/details/8145497 Android 仿微信之主页面 ...

  9. [转载] 50个Android开发人员必备UI效果源码

    好东西,多学习! Android 仿微信之主页面实现篇Android 仿微信之界面导航篇Android 高仿QQ 好友分组列表Android 高仿QQ 界面滑动效果Android 高仿QQ 登陆界面A ...

随机推荐

  1. dubbo理解

    Dubbo服务的调用基本上都是出现在分布式项目中,最常见的电商网站.涉及买卖的APP等. 比如某个购物APP,目前最常见的架构就是做成分布式架构,拆分成很多个系统,比如用户模块.短信模块.产品模块.订 ...

  2. [Python3网络爬虫开发实战] 2.5-代理的基本原理

    我们在做爬虫的过程中经常会遇到这样的情况,最初爬虫正常运行,正常抓取数据,一切看起来都是那么美好,然而一杯茶的功夫可能就会出现错误,比如403 Forbidden,这时候打开网页一看,可能会看到“您的 ...

  3. web前端开发——css

    一.css介绍 1.css是什么? Cascading Style Sheets缩写,层叠样式表.样式定义如何显示HTML元素,样式通常又会存在于样式表中. 2.为什么需要css? 使HTML页面变得 ...

  4. 慕课笔记利用css进行布局【两列布局】

    <html> <head> <title>两列布局</title> <style type="text/css"> bo ...

  5. django2

    八 Models 数据库的配置 1    django默认支持sqlite,mysql, oracle,postgresql数据库.  <1> sqlite django默认使用sqlit ...

  6. JavaEE JDBC 读写LOB大对象

    JDBC 读写LOB大对象 @author ixenos LOB 除了数字.字符串和日期之外,许多数据库还可以存储大对象,例如图片或其他数据, 在SQL中,二进制(字节型)大对象称为BLOB,字符型大 ...

  7. 扫描局域网内所有主机和MAC地址的Shell脚本

    #!/bin/bash #author: InBi #date: 2011-08-16 #website: http://www.itwhy.org/2011/08-20/939.html ##### ...

  8. oracle 互锁的sql查询

    SELECT DECODE(request, 0, 'Holder: ', 'Waiter: ') || sid sess,       id1,       id2,       lmode,    ...

  9. [luoguP1578] 奶牛浴场(DP)

    传送门 O(s2)算法 详见论文 王知昆--浅谈用极大化思想解决最大子矩形问题 我就复制你能把我怎么样QAQ #include <cstdio> #include <iostream ...

  10. 概率dp呜呜

    概率dp有环怎么办? 答案可劲迭代 ,然后可劲消元 , 怎么消? 我就不知道了. 呵呵