一、概述

最近测试提交了一个bug:用我们的应用删除Android5.0手机上的短信失败。

二、原因分析

在google查阅后得知:Android为了防止第三方软件拦截短信和偷发短信吸费,在android4.4之后,只有默认的短信应用才有权限操作短信数据库。

Android4.4短信机制的改变:
Getting Your SMS Apps Ready for KitKat

4.4 之前:

  • 新接收短信广播 SMS_RECEIVED_ACTION 为有序广播。任意应用可接到该广播并中止其继续传播。中止后优先级低的短信应用和系统短信服务将不知道新短信到达,从而不写进数据库。这样就做到了拦截(其实很多恶意应用也这么干)。
  • 任意应用都可以操作短信数据库,包括新建(含伪造收件箱和发件箱短信)、修改(含篡改历史短信)、删除。
  • 任意应用都可以发送短信和彩信,但默认不写进短信数据库,除非应用手动存入,否则用户是看不到的(配合拦截就可以安静地吸费了)。

4.4 及之后:

  • 设立默认短信应用机制,成为默认短信后的应用将全面接管(替代)系统短信服务。与设置默认浏览器类似,成为默认短信应用需要向用户申请。
  • 新接收短信广播 SMS_RECEIVED_ACTION 更改为无序广播,增加只有默认短信应用能够接收的广播 SMS_DELIVER_ACTION和WAP_PUSH_DELIVER_ACTION 。二者的不同在于,当默认短信应用收到 SMS_DELIVER_ACTION 时它要负责将其存入数据库。任意应用仍然可以接收到 SMS_RECEIVED_ACTION 广播但不能将其中止。因此所有的应用和系统短信服务都可以接收到新短信,没有应用能够再用中止广播的方式拦截短信。
  • 只有默认短信应用可以操作短信数据库,包括新建(含伪造收件箱和发件箱短信)、修改(含篡改历史短信)和删除。其它应用只能读取短信数据库。默认短信应用需要在发送短信、收到新短信之后手动写入系统短信数据库,否则其它应用将读取不到该条短信。默认短信应用可以通过控制不写入数据库的方式拦截短信。
  • 任意应用仍然都可以发送短信,但默认短信应用以外的应用发短信的接口底层改为调用系统短信服务,而不再直接调用驱动通信,因此其所发短信会被系统短信服务自动转存数据库。此外,只有默认短信应用可以发送彩信。

简单来说,第三方非默认短信应用:
1. 可以收短信、发短信并接收短信回执,但是不能删除短信
2. 可以查询短信数据库,但是不能新增、删除、修改短信数据库
3. 无法拦截短信

但是!极少数国产手机厂商会修改这个机制,实际测试中发现小米就修改了这个机制!小米4,android6.0系统,miui稳定版8.2,运行非默认应用,居然还是可以删除短信。但是别的小米手机又是不行的。非常奇怪。

三、如何解决

提示用户设置自己的app为default SMS app

为了使我们的应用出现在系统设置的Default SMS app中,我们需要在Manifest中做一些声明,获取对应的权限:
1. 声明一个 broadcast receiver控件,对SMS_DELIVER_ACTION广播进行监听,当然这个receiver也要声明BROADCAST_SMS权限。
2. 声明一个 broadcast receiver控件,对WAP_PUSH_DELIVER_ACTION广播进行监听,当然这个receiver也要声明BROADCAST_WAP_PUSH权限。
3. 在短信发送界面,需要监听 ACTION_SENDTO,同时配置上sms:, smsto:, mms:, and mmsto这四个概要,这样别的应用如果想发送短信,你的这个activity就能知道。
4. 需要有一个service,能够监听ACTION_RESPONSE_VIA_MESSAGE,同时也要配置上sms:, smsto:, mms:, and mmsto这四个概要,并且要声明SEND_RESPOND_VIA_MESSAGE权限。这样用户就能在来电的时候,用你的应用来发送拒绝短信。

<manifest>  ...  <application>  <!-- BroadcastReceiver that listens for incoming SMS messages -->  <receiver android:name=".SmsReceiver"  android:permission="android.permission.BROADCAST_SMS">  <intent-filter>  <action android:name="android.provider.Telephony.SMS_DELIVER" />  </intent-filter>  </receiver>  <!-- BroadcastReceiver that listens for incoming MMS messages -->  <receiver android:name=".MmsReceiver"  android:permission="android.permission.BROADCAST_WAP_PUSH">  <intent-filter>  <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />  <data android:mimeType="application/vnd.wap.mms-message" />  </intent-filter>  </receiver>  <!-- Activity that allows the user to send new SMS/MMS messages -->  <activity android:name=“.MainActivity" >  <intent-filter>  <action android:name="android.intent.action.SEND" />                  <action android:name="android.intent.action.SENDTO" />  <category android:name="android.intent.category.DEFAULT" />  <category android:name="android.intent.category.BROWSABLE" />  <data android:scheme="sms" />  <data android:scheme="smsto" />  <data android:scheme="mms" />  <data android:scheme="mmsto" />  </intent-filter>  </activity>  <!-- Service that delivers messages from the phone "quick response" -->  <service android:name=".HeadlessSmsSendService"  android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"  android:exported="true" >  <intent-filter>  <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />  <category android:name="android.intent.category.DEFAULT" />  <data android:scheme="sms" />  <data android:scheme="smsto" />  <data android:scheme="mms" />  <data android:scheme="mmsto" />  </intent-filter>  </service>  </application>
</manifest>

通过 Telephony.Sms.getDefaultSmsPackage()方法来判断自己的应用是否为Default SMS app。如果不是,可以通过startActivity() 方法启动类似如下的Dialog。

public class  MainActivity extends Activity {@Overrideprotected void onResume() {super.onResume();final String myPackageName = getPackageName();if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {// App is not default.// Show the "not currently set as the default SMS app" interfaceView viewGroup = findViewById(R.id.ll_not_default_app);viewGroup.setVisibility(View.VISIBLE);// Set up a button that allows the user to change the default SMS appView button = findViewById(R.id.btn_change_default_app);button.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, myPackageName);startActivity(intent);}});} else {// App is the default.// Hide the "not currently set as the default SMS app" interfaceView viewGroup = findViewById(R.id.ll_not_default_app);viewGroup.setVisibility(View.GONE);}}

四、源码下载:

https://github.com/wenzhiming/520sms

五、参考资料

  • 默认短信应用
  • Getting Your SMS Apps Ready for KitKat
  • android4.4短信处理机制发生了那些变化?

Android4.4以后第三方应用无法删除短信的解决方案相关推荐

  1. iphone查看删除的短信_手机资讯:iPhone手机可以批量删除短信吗如何操作

    如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多知识的,这些知识很多小伙伴一般都是不知道的,就好比最近就有很多小伙伴们想要知道iPhone手机可以批量删除短信吗如何操作,那么既 ...

  2. Android开发删除短信

    本人一直有一个需求,想要手机自动拦截黑名单里联系人的信息并自动删除这些短信,手机管家之类的软件可以拦截但是没找到能删除这些短信的,于是就萌生了想自己写一个android软件的想法. 加上物联网的兴起, ...

  3. ios13全选手势_iOS13系统5个简单实用的技巧 快速选择/三指操作/批量删除短信/文字转表情...

    iOS 13 已经发布一段时间,苹果带来了不少新内容和细节上的优化,一起来看看 iOS 13 还有哪些隐藏的小技巧,希望对大家有所帮助. iOS13系统5个简单实用的技巧: 快速选择文本 当您在编辑文 ...

  4. android短信删除,Android删除短信的方法

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 1.删除短信的函数,一条一条的删除所有短信 /* * Delete all SMS one by one */ public void deleteSMS ...

  5. android 删除短信无效,android删除短信(绕过权限)

    android的很多功能都是需要权限才能操作,还是有很多功能我们是可以直接操作的,只需要在配置文件中注明权限就行了,可是有些虽然注明了权限,但是还是会提示说你没权限.比如删除短信.让手机进入休眠状态( ...

  6. python实现第三方验证码获取_python利用第三方模块,发送短信验证码(测试案例)...

    今天学到个利用python第三方,发送短信验证码的代码,速实现一遍,短信立即收到,果断记录在案! 环境:虚拟机上centos7平台,python2.7版本: 第三方服务提供商是:云通讯官网:www.y ...

  7. android 删除短信权限,Android删除短信的方法

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 1.删除短信的函数,一条一条的删除所有短信 /* * Delete all SMS one by one */ public void deleteSMS ...

  8. Mac下使用AppleScript批量删除短信

    在https://www.jianshu.com/p/bae74f9eb8e2基础上修改,并参考了https://juejin.cn/post/6850418120416591885的获取鼠标方法. ...

  9. iphone6手机已彻底删除短信如何恢复

    iphone6手机已彻底删除短信如何恢复 记住最初的时分盗短信仍是一件很猖狂的工作,大家的安全意识也没有那么的激烈,由于我经常去外地出差,有时分一去即是几个月,所以关于自个的短信安全我仍是格外注重的, ...

最新文章

  1. python3读取excel数据-python3读取Excel表格数据的代码分享
  2. 读书笔记:锋利的JQuery
  3. 小孔成像实验探究的软件_【亲子实验】科学小制作:神秘小潜艇科学小论文作品在科学课(小学版)2004年第5期发表,科学小发明潜水艇与沉浮子...
  4. matlab如何提高运算速速,如何提高以下程序的运算速度及有选择性的保存数据?...
  5. python 函数定义位置_PYTHON--函数定义
  6. 【Tyvj】1473校门外的树3 线段树/树状数组 区间修改+单点访问
  7. Ural_1225 Flags
  8. C++ API 设计 15 第十章 测试
  9. Java依赖包下载地址
  10. excel使用教程_Office办公软件(word、ppt、excel)视频教程(更新)
  11. 补全Windows10中的emoji 替换系统emoji字体
  12. 垂直滤波和水平滤波的区别_无锡有源滤波器的功能是_灿勤科技
  13. 微信小程序:2022虎年全新头像框制作
  14. 以后你肯定会用到的,25个常用Matplotlib图的Python代码,可以不会不能没有,建议收藏
  15. ACPYPE中FAILED: [Errno 2] No such file or directory: 'FFF_AC.prmtop'的解决方法
  16. 广州大学--金融股票数据分析
  17. 超说网络NO.4 | 深入了解应用层原理(中科大 郑烇)
  18. Windows注册表及常见子项
  19. SMB v1远程代码执行漏洞(CVE-2020-1301)复现
  20. bit、byte、位、字节、汉字的关系

热门文章

  1. 区块链隐私保护:MimbleWimble 和 Grin 简介
  2. Python淘宝美眉图片下载爬虫视频教程-何家胜-专题视频课程
  3. grafana告警配置
  4. MPU6500寄存器映射及说明
  5. 用机器学习改善网络通话质量
  6. 两台电脑实现共用鼠标键盘的软件ShareMouse
  7. 3.7 倒计时计时器——全部代码
  8. 【knife4j】适配 spring boot 2.6.6
  9. python3 requests+bs4爬取某网页MM图片
  10. 楼宇对讲朝智能家居成长 可从多角度切入