Android团队通过Android开发博客透漏今年会放出Android 4.4 (KitKat) ,同时更新了 SMS 的部分API。博客上讲只有default SMS app才能对短信数据库有写权限,但是用户可以把第三方应用设置为default SMS app。有些中文的报道说“在Android 4.4中,只有默认的信息应程序才有权限接收和发送短信”,本文作者认为是不完全正确的,非default SMS app也能读写短信,只不过是不能写入短信数据库中。我们看一看android开发者博客是怎么讲述其他应用短信接收和发送问题的。
1)接收短信问题:
-
Other apps that only want to read new messages can instead receive the
-
SMS_RECEIVED_ACTION broadcast intent when a new SMS arrives.
其他应用可以接收SMS_RECEIVED_ACTION的广播接收到短信,接收到这个广播,短信不会写入短信数据库。
2)发送短信问题:
-
When your app is not currently selected as the default SMS app, it's important that you
-
disable the ability to send new messages from your app because, without the ability to
-
write to the SMS Provider, any messages you send won't be visible in the user's default SMS app.
没有 default SMS app能力的app发送短信,不会出现在短信数据库中。
Android开发者博客中重点讲到了3个方面的问题:
1、怎么开发default SMS app
2、怎么提示用户设置自己的app为default SMS app
3、对短信备份恢复类App的一点建议
怎么开发default SMS app
现存的短信类App不会默认升级为default SMS app,需要完成Android新的规范协议。Android 4.4中,系统收到短信时,只有一个应用能收到SMS_DELIVER_ACTION,这个应用就是default SMS app,WAP_PUSH_DELIVER_ACTION也是类似。如果现存的短信类App不做改造,运行在Android 4.4也不会Crash,但是写入短信数据库数据时会失败。
为了使你的应用出现在系统设置的Default SMS app中,你需要在manifest 文件声明一下几种能力。
1、接收SMS_DELIVER_ACTION(
"android.provider.Telephony.SMS_DELIVER"
)的broadcast receiver,这个broadcast receiver需要有BROADCAST_SMS权限。这些是为了让你的应用能接收到SMS messages。
2、接收WAP_PUSH_DELIVER_ACTION(
"android.provider.Telephony.WAP_PUSH_DELIVER"
) 的broadcast receiver,这个需要BROADCAST_WAP_PUSH权限。这些是为了让你的应用能接收到MMS messages。
3、实现发送短信功能,需要有个Activity完成
ACTION_SENDTO
("android.intent.action.SENDTO"
)intent filter,并使用schemas,sms:
,smsto:
,mms:
, 以及mmsto:。
这可以使其他应用调用你的发短信能力。
4、实现一个提供intent filter for
ACTION_RESPONSE_VIA_MESSAGE
("android.intent.action.RESPOND_VIA_MESSAGE"
) with schemas,sms:
,smsto:
,mms:
, andmmsto
服务。这个服务需要SEND_RESPOND_VIA_MESSAGE权限。
这允许用户使用您的应用程序提供即时短信回应电话呼入。
下面是一个manifest文件的例子:
-
<manifest>
-
...
-
<application>
-
<!-- BroadcastReceiver that listens for incoming SMS messages -->
-
<receiverandroid:name=".SmsReceiver"
-
android:permission="android.permission.BROADCAST_SMS">
-
<intent-filter>
-
<actionandroid:name="android.provider.Telephony.SMS_DELIVER"/>
-
</intent-filter>
-
</receiver>
-
-
<!-- BroadcastReceiver that listens for incoming MMS messages -->
-
<receiverandroid:name=".MmsReceiver"
-
android:permission="android.permission.BROADCAST_WAP_PUSH">
-
<intent-filter>
-
<actionandroid:name="android.provider.Telephony.WAP_PUSH_DELIVER"/>
-
<dataandroid:mimeType="application/vnd.wap.mms-message"/>
-
</intent-filter>
-
</receiver>
-
-
<!-- Activity that allows the user to send new SMS/MMS messages -->
-
<activityandroid:name=".ComposeSmsActivity">
-
<intent-filter>
-
<actionandroid:name="android.intent.action.SEND"/>
-
<actionandroid:name="android.intent.action.SENDTO"/>
-
<categoryandroid:name="android.intent.category.DEFAULT"/>
-
<categoryandroid:name="android.intent.category.BROWSABLE"/>
-
<dataandroid:scheme="sms"/>
-
<dataandroid:scheme="smsto"/>
-
<dataandroid:scheme="mms"/>
-
<dataandroid:scheme="mmsto"/>
-
</intent-filter>
-
</activity>
-
-
<!-- Service that delivers messages from the phone "quick response" -->
-
<serviceandroid:name=".HeadlessSmsSendService"
-
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
-
android:exported="true">
-
<intent-filter>
-
<actionandroid:name="android.intent.action.RESPOND_VIA_MESSAGE"/>
-
<categoryandroid:name="android.intent.category.DEFAULT"/>
-
<dataandroid:scheme="sms"/>
-
<dataandroid:scheme="smsto"/>
-
<dataandroid:scheme="mms"/>
-
<dataandroid:scheme="mmsto"/>
-
</intent-filter>
-
</service>
-
</application>
-
</manifest>
Android 4.4可以使用SMS_RECEIVED_ACTION广播来观察收到了短信,这样可以知道特定的短信收到了,但是我们不能对接收到短信做处理。
设置自己的app为default SMS app
Android4.4中提供了新的方法 Telephony.Sms.getDefaultSmsPackage(),可以获取到当前Default SMS app的包名。用户打开你的应用时可以通过判断知道自己的应用是否为Default SMS app。如果不是,可以通过startActivity()
方法启动类似如下的Dialog。具体实现可参考下面的代码。
-
publicclass ComposeSmsActivity extends Activity {
-
-
@Override
-
protectedvoid 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() {
-
publicvoid 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);
-
}
-
}
-
}
对短信备份恢复类App的一点建议
短信备份恢复类应用没有Default SMS app的能力,不能写入短信数据库数据,就起不到恢复短信的作用了。Android开发者博客给出的建议是临时的设置自己的应用为Default SMS app,临时获取一次写入短信数据库数据能力,等短信恢复完成再改回原来的应用为Default SMS app。
1、获取默认App的包名并保存。
String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);
2、让用户修改你的app为 Default SMS app
Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName());
startActivity(intent);
3、恢复完短信,再让用户修改回Default SMS app,使用第一步保存的包名。
Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp);
startActivity(intent);
上面是一些Android4.4短信变化的介绍,大部分是翻译自Android开发者博客,由于作者英语水平有限,可能与原作者的理解有些出入,敬请读者谅解。
参考:
http://android-developers.blogspot.com/2013/10/getting-your-sms-apps-ready-for-kitkat.html
本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/1344875,如需转载请自行联系原作者