android4.4对短信引入了一个全新的概念:默认短信应用。即android用户可以在系统设置里面选择一个默认的短信应用,只有这个应用才能进行手机的基本短信操作。按照google自己的解释这样做的原因是因为很多第三方的APP使用了一些隐藏的API接口,应该是反射调用把,既然是反射调用的非常规接口,因此这些接口就并不会有兼容性即CTS测试,也就不能保证稳定可靠。个人看来,目前市场上第三方短信应用太多了,而且厂商经常把通话,联系人,短信打包放在一起,因此手机上经常有多个短信应用,每个应用都能收短信发短信,有点混乱,尤其有的应用没有处理好,导致收到一条短信显示两条。囧。因此这个默认短信的操作也就是很有必要的。
不过既然接口变了,那么APP这边很多东西也要改变,最典型的类似360云盘这种能恢复短信的应用,应该怎么恢复短信呢?这个稍后会提到google给了一个建议。这里还是先说下接口有了哪些变化把。

google提供了:SMS_DELIVER_ACTION(sms)&&
WAP_PUSH_DELIVER_ACTION(MMS)这两个intent来给默认的短信应用,也就是说只有默认的短信应用才能收到这两个广播,也只有能收到这两个广播的应用才能对短彩信的数据库进行写操作。也就是说只有默认短信应用才能存储短信。其他的非默认短信应用如果想收短信,可以监听:
SMS_RECEIVED_ACTION
当然这些应用也只能显示下短信,并不能存入数据库。因此直接将4.4以前的短信应用拿过来装到4.4上,这些应用仅能在来短信的时候进行查看阅读,因为没有写数据库的权限。google提供了一个控件接口:PackageManager.setComponentEnabledSetting(),可以对控件进行使能操作。这样应用可以做到检测下当前的android的平台,然后判断是否需要关掉这个广播。

另外在4.4之前, SMS_RECEIVED_ACTION
broadcast是一个有序广播,因此一些应用可以在监听到这个广播之后,进行丢弃处理,但是到了4.4之后,丢弃动作是不会生效的,这样就可以保证所有的短信应用都能收到短信。个人认为这是非常合理的……毕竟短信嘛,不能某个应用说拦截就拦截了。

非系统的短信应用,如果想进行发短信操作的话,可以在申请了SEND_SMS权限之后,调用SmsManager接口进行短信发送操作。只有非系统短信应用在发送短信之后,framework才会将这条短信写入数据库,(系统短信应用会自己写入数据库),笔者感觉这一点非常好,再也不会有应用悄悄的在后台发送短信了……

因为一个应用如果不是默认的短信应用,其很多设计的东西都不可用的,和成为默认短信应用差别非常大,因此有必要进行一些容错操作。首先,界面resume的时候需要检查下是否是默认的,可以通过查询:Telephony.Sms.getDefaultSmsPackage()来判断自己是不是默认的短信应用。如果不是建议就disable短信发送操作,因为如果用户发送彩信的话,系统不会帮忙写入数据库,应用自己又不能写入数据库,情况就很糟糕了……当然如果不是默认短信应用的话,也可以提示用户选择是否设置下,毕竟愿意点击你的应用,基本都是想用的。

sample如下:

  1. public class ComposeSmsActivity extends Activity {
  2. @Override
  3. protected void onResume() {
  4. super.onResume();
  5. final String myPackageName = getPackageName();
  6. if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {
  7. // App is not default.
  8. // Show the "not currently set as the default SMS app" interface
  9. View viewGroup = findViewById(R.id.not_default_app);
  10. viewGroup.setVisibility(View.VISIBLE);
  11. // Set up a button that allows the user to change the default SMS app
  12. Button button = (Button) findViewById(R.id.change_default_app);
  13. button.setOnClickListener(new View.OnClickListener() {
  14. public void onClick(View v) {
  15. Intent intent =
  16. new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
  17. intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,
  18. myPackageName);
  19. startActivity(intent);
  20. }
  21. });
  22. } else {
  23. // App is the default.
  24. // Hide the "not currently set as the default SMS app" interface
  25. View viewGroup = findViewById(R.id.not_default_app);
  26. viewGroup.setVisibility(View.GONE);
  27. }
  28. }
  29. }

怎么样才能让你的应用成为成为一个合格的默认短信应用呢?首先你需要在androidmanifest.xml文件中进行一些声明,获取对应的权限:
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权限。这样用户就能在来电的时候,用你的应用来发送拒绝短信。

sample如下:

  1. <manifest>
  2. ...
  3. <application>
  4. <!-- BroadcastReceiver that listens for incoming SMS messages -->
  5. <receiver android:name=".SmsReceiver"
  6. android:permission="android.permission.BROADCAST_SMS">
  7. <intent-filter>
  8. <action android:name="android.provider.Telephony.SMS_DELIVER" />
  9. </intent-filter>
  10. </receiver>
  11. <!-- BroadcastReceiver that listens for incoming MMS messages -->
  12. <receiver android:name=".MmsReceiver"
  13. android:permission="android.permission.BROADCAST_WAP_PUSH">
  14. <intent-filter>
  15. <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
  16. <data android:mimeType="application/vnd.wap.mms-message" />
  17. </intent-filter>
  18. </receiver>
  19. <!-- Activity that allows the user to send new SMS/MMS messages -->
  20. <activity android:name=".ComposeSmsActivity" >
  21. <intent-filter>
  22. <action android:name="android.intent.action.SEND" />
  23. <action android:name="android.intent.action.SENDTO" />
  24. <category android:name="android.intent.category.DEFAULT" />
  25. <category android:name="android.intent.category.BROWSABLE" />
  26. <data android:scheme="sms" />
  27. <data android:scheme="smsto" />
  28. <data android:scheme="mms" />
  29. <data android:scheme="mmsto" />
  30. </intent-filter>
  31. </activity>
  32. <!-- Service that delivers messages from the phone "quick response" -->
  33. <service android:name=".HeadlessSmsSendService"
  34. android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
  35. android:exported="true" >
  36. <intent-filter>
  37. <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
  38. <category android:name="android.intent.category.DEFAULT" />
  39. <data android:scheme="sms" />
  40. <data android:scheme="smsto" />
  41. <data android:scheme="mms" />
  42. <data android:scheme="mmsto" />
  43. </intent-filter>
  44. </service>
  45. </application>
  46. </manifest>

没有写权限,备份应用应该如何写入短信数据库呢?google提供了这样一个建议:
1.先查询下并且记录下当前的默认短信应用:

  1. String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);

2.让用户设置你的应用成为默认短信应用,如何设置前面也有sample,成为默认短信应用之后,就可以恢复短信了:

  1. Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
  2. intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName());
  3. startActivity(intent);

3.最后恢复完成短信之后,可以在将默认短信应用还原到步骤1中记录的短信应用:

  1. Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
  2. intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp);
  3. startActivity(intent);

最后笔者总结下:4.4上短信真的严格了,从此再也没有应用能够悄悄的发短信了,也不会有应用能够自行拦截短信了。各种管家,安全软件的拦截骚扰短信的功能该怎么办呢?

android4.4短信新概念的更多相关文章

  1. 做好准备,让你的短信应用迎接Android 4.4(KitKat)

    Android团队通过Android开发博客透漏今年会放出Android 4.4 (KitKat) ,同时更新了 SMS 的部分API.博客上讲只有default SMS app才能对短信数据库有写权 ...

  2. 对于android拦截短信的一些疑问

    最近折腾android4.4短信拦截的问题,要求在app上收到短信的时候弹出提示,并显示的功能. 然后找到了使用broadcastreceiver和contentprovider两种方法,那么问题来了 ...

  3. Android短信监听实现,及Android4.4之后短信机制变更

    前阵子公司有一个项目,简单的监听短信应用,功能只有如下两个: 1.监听短信并获取短信内容上传服务器: 2.从服务器获取短信内容,发送出去    按照传统的思路,监听短信我们有两种方式:第一种是使用广播 ...

  4. Android4.4 往短信收件箱中插入自定义短信(伪造短信)

    这段时间稍微有点空闲,把前一段学习Android做过的一些小项目整理整理.虽然没有什么工程量很大的项目,但是对于一个新手,解决这些问题还是花了一段时间.感觉还是非常有记录的意义呢~~~么么哒*—* 今 ...

  5. android安全问题(八)伪造短信(利用原生android4.0漏洞)

    导读:本文利用android4.0的一个原生漏洞来伪造短信.无须声明任何权限即可伪造发送方为任何号码的短信给用户. android4.0发布已经是很久很久很久很久以前的事情了,这个漏洞早就报了出来,之 ...

  6. 无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)

    1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...

  7. android4.4.2 短信广播变更

    近期三星陆续放出android4.4.2ROM更新包,android4.4.2对短信虽说是放开了权限,但其实是加强了限制,一台手机智能通过一个设置为默认应用的短信应用软件才能发送短信,否则就无法对短信 ...

  8. 新出台的治理iMessage垃圾短信的规则

    工信部拟制定<通信短信息服务管理规定>,为治理垃圾短信提供执法根据.当中,对于苹果iMessage垃圾信息泛滥现象,工信部也将跟踪研究技术监測和防范手段.这意味着长期以来处于监管" ...

  9. Android4.4 RIL短信接收流程分析

    最近有客户反馈Android接收不到短信,于是一头扎进RIL里面找原因.最后发现不是RIL的问题,而是BC72上报短信的格式不对,AT+CNMA=1无作用等几个小问题导致的.尽管问题不在RIL,但总算 ...

随机推荐

  1. 通用权限管理系统Ver2.0

    通用权限管理系统Ver2.0平台采用kendo+mvc4+Nhibernate技术实现,底层采用自定义ORM实现数据库底层代码,支持Oracle.SqlServer.mysql等常用数据库,界面采用k ...

  2. SDOI2012Longge的问题

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 930  Solved: 601[Submit][St ...

  3. [转] struts.xml配置详解

    转自:http://www.cnblogs.com/fmricky/archive/2010/05/20/1740479.html struts.xml是我们在开发中利用率最高的文件,也是Struts ...

  4. 对redis客户端jedis2.8.0的进一步封装

    jedis2.8.0的进一步封装: 1.序列化存储对象 2.结合spring,创建redis连接池 3.提供了基础的单个实体操作,有序list操作和一对多关系list的操作,对list提供了分页的封装 ...

  5. 年过三十,我为什么要学习ios 与安卓App 移动端技术

    今天跟我华为的同学谈了一些技术/人生方面的感悟,感觉自己的人生目标及后面的工作/生活有了一个比较清晰的认识与规划. 首先我谈了一下我为什么要学习ios与安卓技术,我其实不想通过这二门技术来提升我的薪酬 ...

  6. [GRYZ2015]快排练习

    用快排完成n(n<=100)个人年龄的从小到大的排序,要求出生年相同的按月排. 输入:第一行n个人 2到n+1行出生  年  月(1992 9) 输出:年龄的从小到大的排序. type ss=r ...

  7. 第一章 :绪论-Twitter数据的收集和处理

    为什么要用twitter,我心里是一万头CNM在飞奔.这个国外的东西很不好访问到的,国内的政策,你懂的,不说这个了,还是想办法翻出去再说吧. 不知道别人都用的什么工具,看到太多的注册就头大,就选了一个 ...

  8. 专门为公共部门和联邦机构所设计Microsoft Azure

    微软正式发布Microsoft Azure for Government,该云平台专门为公共部门和联邦机构所设计. 在2014年三月微软联邦执行官论坛上宣布的Microsoft Azure for G ...

  9. MFC中Listbox控件的简单使用

    MFC中listbox控件是为了显示一系列的文本,每个文本占一行.   Listbox控件可以设置属性为: LBS_CHILD   :(默认)子窗口 LBS_Visible :(默认)可视 LBS_M ...

  10. leetcode@ [139/140] Word Break & Word Break II

    https://leetcode.com/problems/word-break/ Given a string s and a dictionary of words dict, determine ...