让你的短信应用迎接Android 4.4(KitKat)

时间:2021-08-03 15:01:57

原文地址:Getting Your SMS Apps Ready for KitKat

发送和接收短信是手机最基本的功能,很多的开发者也开发了很多成功的应用来增强Android这一方面的体验。你们当中的某些人可能基于隐藏API来开发短信应用,这种做法我们是不推荐的,因为隐藏API可能会有改变或者被移除,这样新的设备可能无法通过兼容性测试。因此,为了让你能够用到全面支持的API集来开发短信应用,以及短信应用体验的可预见性,Android 4.4 (KitKat)公开了现有的API并且增加了默认短信应用的概念,也就是说用户可以在系统设置中进行选择默认短信。

这意味着如果你在之前的Android版本中使用了隐藏API,你需要对你的应用进行一些调整以便让你的应用可以在今年晚些时候Android 4.4发布之后能够在Android4.4上继续使用。

让你的应用成为默认短信

在Android 4.4上,只有一个应用能接收到新增的SMS_DELIVER_ACTION intent,这个intent是当系统接收到新短信时用来发送广播的。哪个应用接收这个广播取决于用户在系统设置里选择了哪个应用作为默认短信应用。同样的,也只有默认的短信应用能在系统接收到新彩信的时候接收到Android
4.4新增加的WAP_PUSH_DELIVER_ACTION intent。
让你的短信应用迎接Android 4.4(KitKat)

其他只想读取新信息的应用可以接收SMS_RECEIVED_ACTION广播,这个广播也是系统接收到新短信时发送的。但是只有接收到SMS_DELIVER_ACTION的应用(用户指定的默认短信应用)可以写入由android.provider.Telephony类和子类定义的SMS
Provider。因此,尽快升级你的短信应用让它可以成为默认短信应用是很重要的,因为就算你现有的应用不会在Android 4.4的设备上crash,但它尝试写入SMS Provider的时候会在没有提示的情况下失败。

为了让你的应用在系统设置中作为一个可选的默认短信应用,你的manifest文件必须声明一些特定的内容。所以你必须为你的应用更新以下内容:

  • 在一个broadcast receiver中包含一个SMS_DELIVER_ACTION("android.provider.Telephony.SMS_DELIVER")的intent
    filter。这个broadcast receiver同样需要BROADCAST_SMS权限。

    这让你的应用可以直接接收到进来的短信。

  • 在一个broadcast receiver包含一个WAP_PUSH_DELIVER_ACTION("android.provider.Telephony.WAP_PUSH_DELIVER")的intent
    filter,MIME类型是"application/vnd.wap.mms-message"。这个broadcast receiver同样需要BROADCAST_WAP_PUSH权限。

    这让你的应用可以直接接收到进来的彩信。

  • 在你用来发送新信息的activity中包含一个ACTION_SENDTO("android.intent.action.SENDTO")的intent
    filter,schemas为sms:, smsto:, mms:, 和mmsto:。

    这让你的应用可以接收到其他想发送信息的应用请求的intent。

  • 在一个service里面包含一个ACTION_RESPONSE_VIA_MESSAGE("android.intent.action.RESPOND_VIA_MESSAGE")的intent
    filter,schemas是sms:, smsto:, mms:, 和 mmsto:。这个service同样需要SEND_RESPOND_VIA_MESSAGE权限。

    这让用户在来电的时候用你的应用进行即时的短信息回复。

举个例子,这是一个含有必要组件和intent filter的manifest文件:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<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=".ComposeSmsActivity" >
<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>

现有所有接收带SMS_RECEIVED_ACTION这个filter的广播的应用可以照常的在Android 4.4上工作,但只能作为新信息的查看者,因为除非你的应用也能接收到SMS_DELIVER_ACTION广播,否则你无法在Android 4.4上写入SMS Provider。

从Android 4.4开始,你应该停止监听SMS_RECEIVED_ACTION广播,你可以通过运行时来检查Android平台的版本,然后通过PackageManager.setComponentEnabledSetting()来禁用掉接收SMS_RECEIVED_ACTION的broadcast receiver。当然如果你的应用只需要读取一些特定的短信息比如用来做电话号码校验的,你也可以继续监听这个广播。如果你在Android 4.4上确实需要处理SMS_RECEIVED_ACTION这个intent,那么不要调用API取消掉这个broadcast,因为别的应用可能也会需要接收这个广播。

提示:要区分这两个短信广播,可以想象成SMS_RECEIVED_ACTION只是简单地说“嘿,系统接收到一条短信”而SMS_DELIVER_ACTION却是说“系统传递给你的应用一条短信,因为你是系统默认的短信应用”。

当不是默认短信应用时禁用掉相应的功能

当你的应用不是当前系统默认的短信应用,那么把你应用发送新信息的功能禁用掉是很重要的。因为你无法写入SMS Provider,所有你发送的信息在用户默认的短信应用中都不可见。所以当你的activity resume的时候你可以通过查询Telephony.Sms.getDefaultSmsPackage()来检查你的应用是不是默认的短信应用,这个方法返回当前默认短信应用的包名。如果结果跟你的包名不匹配,那么就把发送信息的功能禁用掉。

要让你的应用能够接收和发送信息,你可以弹出一个让用户可以选择你的应用作为默认短信应用的系统对话框。要弹出这个对话框,调用startActivity(),用Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT这个intent作为参数,这个intent包含一对key-value值,分别是Sms.Intents.EXTRA_PACKAGE_NAME和你的包名。

让你的短信应用迎接Android 4.4(KitKat)

要提供一个良好的用户体验,可以在你的activity resume的时候检查默认的短信应用,并且修改你的UI,把让用户修改默认短信应用这样一个信息给包括进来。比如,你的Activity可能会包括像下面这样的代码:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class ComposeSmsActivity extends Activity {

    @Override
protected 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" interface
View viewGroup = findViewById(R.id.not_default_app);
viewGroup.setVisibility(View.VISIBLE); // Set up a button that allows the user to change the default SMS app
Button button = (Button) findViewById(R.id.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" interface
View viewGroup = findViewById(R.id.not_default_app);
viewGroup.setVisibility(View.GONE);
}
}
}

给短信备份还原类应用的建议

由于写SMS Provider这样一个功能局限在用户选择的默认短信应用,当前所有只为短信备份还原设计的应用在Android 4.4上会无法还原短信。一个备份还原短信的应用同样需要被设置成默认的短信应用才能写入短信到SMS Provider当中去。当然,一个应用如果没有发送和接收短信的功能,那么它也不应该一直被设置成默认短信应用。所以当用户打开你的应用准备做一次性还原操作时,你可以根据以下的设计提供一个功能性的UI体验:

  1. 查询当前默认的短信应用包名并把包名保存起来。

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

  2. 请求用户把你的应用设置成默认短信应用以便进行短信还原(你必须作为默认短信应用才可以写入数据到SMS Provider中)。

1
2
3
Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName());
startActivity(intent);
  1. 当你还原完所有短信之后,请求用户把步骤一保存的应用设置回默认短信应用。
1
2
3
Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp);
startActivity(intent);

准备升级你的短信应用

为了给你的用户提供最好的Android体验,我们建议你尽可能快的升级你的应用。为了帮助你做出调整,我们马上会提供Android 4.4必要的SDK组件以便让你能编译和测试你在Android 4.4上做出的修改。敬请期待!

让你的短信应用迎接Android 4.4(KitKat)的更多相关文章

  1. 做好准备,让你的短信应用迎接Android 4&period;4&lpar;KitKat&rpar;

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

  2. 无废话Android之常见adb指令、电话拨号器、点击事件的4种写法、短信发送器、Android 中各种布局(1)

    1.Android是什么 手机设备的软件栈,包括一个完整的操作系统.中间件.关键的应用程序,底层是linux内核,安全管理.内存管理.进程管理.电源管理.硬件驱动 2.Dalvik VM 和 JVM ...

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

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

  4. 转载:Android自动化测试- 自动获取短信验证码

    前言:android应用的自动化测试必然会涉及到注册登录功能,而许多的注册登录或修改密码功能常常需要输入短信验证码,因此有必要能够自动获得下发的短信验证码. 主要就是实时获取短信信息. android ...

  5. android自动获取短信验证码

    前言:android应用的自动化测试必然会涉及到注册登录功能,而许多的注册登录或修改密码功能常常需要输入短信验证码,因此有必要能够自动获得下发的短信验证码.主要就是实时获取短信信息.android上获 ...

  6. Android接收短信

    Android收到短信时会广播android.provider.Telephony.SMS_RECEIVED消息,因此只要定义一个Receiver,收听该消息,就能接收短信. <receiver ...

  7. java攻城师之路&lpar;Android篇&rpar;--搭建开发环境、拨打电话、发送短信、布局例子

    一.搭建开发环境 1.所需资源 JDK6以上 Eclipse3.6以上 SDK17, 2.3.3 ADT17 2.安装注意事项 不要使用中文路径 如果模拟器默认路径包含中文, 可以设置android_ ...

  8. android 入门 002 (拨打电话&comma;发送短信)

    一.拨打电话 1.首先做好界面,代码如下: layout =>activity_main.xml 中 <LinearLayout xmlns:android="http://sc ...

  9. Android学习4&mdash&semi;短信发送器的实现

    界面预览: 由图中可以看出,此APP需要的组件有:两个TextView,一个用于显示手机号码的标题,另一个用于显示短信内容的标题.                                    ...

随机推荐

  1. &lbrack;转&rsqb;ASP&period;NET应用程序生命周期趣谈&lpar;一&rpar;

    这几天一直在看ASP.NET应用程序生命周期,真是太难了,我理解起来费了劲了,但偏偏它又是那么重要,所以我希望能给大家带来一篇容易理解又好用的文章来帮助学习ASP.NET应用程序生命周期.这篇就是了. ...

  2. python学习笔记七 初识socket&lpar;进阶篇&rpar;

    socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...

  3. Device Path in WinPrefetchView

    As we know that the Prefetch file is used for optimizing the loading time of the application in the ...

  4. Linux命令之rz - 批量上传文件,简单易用(转载)

    用途说明 rz命令能够批量上传文件,当然也可上传单个文件啦.使用的协议是古老的ZMODEM协议,尽管协议古老,但毫不影响的简单易用的特性.一般情 况我们要上传文件到Linux系统,要么使用ftp(还得 ...

  5. 初识springboot&lpar;傻瓜式教程&rpar;

    初识springboot(傻瓜式教程) 项目所需的版本 IDEA 2018 maven 3.x jdk-1.8 IDEA创建spring-boot项目(maven方法) 1.创建一个maven工程 点 ...

  6. MySQL常见报错汇总

    1>.ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it canno ...

  7. Unity3D用户手册

    Unity Manual 用户手册 Welcome to Unity. 欢迎使用Unity. Unity is made to empower users to create the best int ...

  8. shiro源码篇 - shiro的session的查询、刷新、过期与删除,你值得拥有

    前言 开心一刻 老公酷爱网络游戏,老婆无奈,只得告诫他:你玩就玩了,但是千万不可以在游戏里找老婆,不然,哼哼... 老公嘴角露出了微笑:放心吧亲爱的,我绝对不会在游戏里找老婆的!因为我有老公! 老婆: ...

  9. BZOJ1775&lbrack;USACO 2009 Dec Gold 3&period;Video Game Troubles&rsqb;——DP

    题目描述 输入 * 第1行: 两个由空格隔开的整数: N和V * 第2到第N+1行: 第i+1行表示第i种游戏平台的价格和可以在这种游戏平台上面运行的游 戏.包含: P_i, G_i还有G_i对由空格 ...

  10. linq not in

    linq not in 查询 or join not in var query = from c in _opvRepository.Table join a in _orderRepository. ...