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:
, and mmsto
服务。这个服务需要 SEND_RESPOND_VIA_MESSAGE权限。
这允许用户使用您的应用程序提供即时短信回应电话呼入。
下面是一个manifest文件的例子:
- <manifest>
- ...
- <application>
-
- <receiver android:name=".SmsReceiver"
- android:permission="android.permission.BROADCAST_SMS">
- <intent-filter>
- <action android:name="android.provider.Telephony.SMS_DELIVER" />
- </intent-filter>
- </receiver>
-
-
- <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 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 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>
Android 4.4可以使用SMS_RECEIVED_ACTION广播来观察收到了短信,这样可以知道特定的短信收到了,但是我们不能对接收到短信做处理。
设置自己的app为default SMS app
Android4.4中提供了新的方法 Telephony.Sms.getDefaultSmsPackage(),可以获取到当前Default SMS app的包名。用户打开你的应用时可以通过判断知道自己的应用是否为Default SMS app。如果不是,可以通过startActivity()
方法启动类似如下的Dialog。具体实现可参考下面的代码。
- public class ComposeSmsActivity extends Activity {
-
- @Override
- protected void onResume() {
- super.onResume();
-
- final String myPackageName = getPackageName();
- if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {
-
-
- View viewGroup = findViewById(R.id.not_default_app);
- viewGroup.setVisibility(View.VISIBLE);
-
-
- 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 {
-
-
- 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://blog.csdn.net/xyz_lmn
* iOS入门群:83702688
* android开发进阶群:241395671
* 我的新浪微博:@张兴业TBOW
*/