之前在写通讯录应用时,将整体的代码写完后,自测时发现非常非常多的问题,其中一个非常重要严重的就是可以发出短信,但收不到任何的短信息,这搞的我好捉鸡啊!后来调试发现是由于没有收到短信的消息导致的,然后将自己手机中的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. python3.x Day6 socketserver

    socketserver是啥? 简化了编写网络服务器,就是对于socket的再一次封装sockerserver包含4个类可以使用:A=socketserver.TCPServer() #用于TCP/I ...

  2. Python之模块和包的创建与使用

    一.模块的概念 在计算机的开发过程中,随着程序代码越写越多,在一个文件里代码就越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,放在不同的文件里面,这样,每个文件包含的代码就相对 ...

  3. 常见算法的python实现

    提到排序算法,常见的有如下几种:冒泡排序.选择排序.插入排序.快速排序.堆排序.归并排序.希尔排序:查找算法最常见二分查找.这些算法的时间复杂度如下: 算法名称 时间复杂度(一般情况) 冒泡排序 O( ...

  4. Matlab学习笔记(三)

    二.MATLAB基础知识 (四)数组 MATLAB总是把数组看作存储和运算的基本单位,标量数据也被看作是(1×1)的数组 一维数组的创建 创建一维数组的几种方法:(e_two_14.m) 直接输入法: ...

  5. 基本dos

    文件夹的操作:   进入指定盘符:盘符名+:     dir:列出当前控制台下的所有文件以及文件夹  . cd +文件夹名称:进入指定文件夹     cd.. 返回上一级 cd \返回到当前目录的根目 ...

  6. Python之条件 循环和其他语句 2014-4-6

    #条件 循环和其他语句 23:30pm-1:431.print和import的更多信息 使用逗号将多个表达式输出 >>> print 'age:',42 age: 42 >&g ...

  7. jQuery_计算器实例

    知识点: fadeIn()---计算器界面载入淡入效果 hover()---鼠标移入移出某个元素时触发的事件 click()---鼠标单击事件 css()---对元素样式的操作 val()---获取表 ...

  8. Leetcode 147.对链表进行排序

    对链表进行插入排序 对链表进行插入排序. 插入排序算法: 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表. 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它 ...

  9. python 几种点积运算方式效率分析

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51793984 本文列举出几种pytho ...

  10. DRF JWT的用法 & Django的自定义认证类 & DRF 缓存

    JWT 相关信息可参考: https://www.jianshu.com/p/576dbf44b2ae DRF JWT 的使用方法: 1. 安装 DRF JWT # pip install djang ...