设置默认短信的渣渣翻译
原文-http://www.tuicool.com/articles/R7zmMr
4.4以上基于信息安全的考虑,android要求只能一个系统短信,仅仅一个app可以接受当系统短信到达时发送的SMS_DELIVER_ACTION意图。 app收到这个广播取决于用户选择哪个短信app作为系统默认设定。 同样地,当MMS到达的时候仅仅系统SMSapp可以接受WAP_PUSH_DELIVER_ACTION. 意图。
当新SMS到达的时候,其它app有兴趣在新短信的话,可以接受SMS_RECEIVED_ACTION 广播。然而,仅仅接受SMS_DELIVER_ACTION的广播(用户指定的默认SMS app)是 可以写入SMS通过android.provider.Telephony类和子类。例如,尽可能地设置 默认的SMS短信,就可以更新你的信息app,虽然在Android 4.4设备中现有的 app不会崩溃,当尝试写入SMS服务的时候它可能会失败的。
为了你的app在系统默认SMS的app中,你要维护文件必须声明一些特殊的能力。 所以你必须更新你的app做下列事情,
==在广播接受者,包含intent filter 的SMS_DELIVER_ACTION("android. provider.Telephony.SMS_DELIVER").广播接受者必须请求BROADCAST_SMS权限。 这允许你的app去直接接受SMS消息。
==在广播接受者,包含intent filter 的WAP_PUSH_DELIVER_ACTION(android. provider.Telephony.WAP_PUSH_DELIVER")伴随MIME类型"application/vnd. wap.mms-message".广播接受者必须请求BROADCAST_WAP_PUSH权限。这允许你的 app直接接受MMS消息。
==在你的活动中传送新的消息,包含了intent filter的ACTION_SENDTO(" android.intent.action.SENDTO")的约束,sms:,smsto:,mms:,和mmsto: 这允许你的app去接受来自其它想传送信息的apps的意图。
==在服务中,包含一个intent filter 的ACTION_RESPONSE_VIA_MESSAGE( "android.intent.action.RESPOND_VIA_MESSAGE")伴随约束,sms:,smsto:, mms:,和mmsto: 这个服务必须要求SEND_RESPONSE_VIA_MESSAGE权限。这允许 用户去反应接收的电话用你的app去发一个即时文本消息。 例如,这里是一个必要的部分和intent filters的配置表。 <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>
任何在存在的apps中接收SMS_RECEIVED_ACTION广播中将继续工作在同样的4.4, 但是仅仅观察新来到的消息,因为除非你的app接收SMS_DELIVER_ACTION广播, 你不能在4.4写入SMS Provider。
4.4开始,你应该停止监听SMS_RECEIVED_ACTION广播,你可以在运行时通过 检查平台版本然后让你在PackageManager.setComponentEnabledSettion()接收 SMS_RECEIVED_ACTION广播。然而,如果你的app需要去读明确的SMS消息你可以 继续监听广播,比如执行电话号码的验证。如果你在4.4中处理SMS_RECEIVED_ACTION 意图,不要取消广播,因为其它apps可能需要处理它。
Tip:为了区别两个SMS广播,想象SMS_RECEIVED_ACTION简单地说"系统接收 一个SMS",然而SMS_DELIVER_ACTION说"系统传递给你的app一个短信,因为 你是默认的SMS app" 当没有设置默认的SMSapp的时候让功能不能用 当你的app目前没有选择默认的SMSapp,它是很重要的让你不能让你的能力去发送新的消息从你的app,没有能力去写入到SMS Provider,任何你发送的 消息在用户的默认SMSapp中不能看到。所以当你的活动resumes时,你可以检查 是否你的app是默认的SMS app通过查询Telephony.Sms.getDefaultSmsPackage(), 这会返回当前默认的SMSapp的包名字。如果不匹配你的包名,不能让发送消息能力 可用。 为了让你的app发送和接收消息,你可以展示一个对话框让系统运行用户来让你的 app成为默认的SMSapp.为了展示对话框,调用startActivity()伴随Telephony.Sms. Intents.ACTION_CHANGE_DEFAULT意图,包含额外的Sms.Intents.EXTRA_PACKAGE_NAME键和你的包名的字符串值。
为了提供一个优雅的用户体验,当你的活动恢复和修改你的UI到包含一个允许用户去改变默认SMSapp的消息要检查是否你的app是默认的SMSapp。例如,你的活动可能会包含代码像下面这样: 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); } } } 短信备份和恢复的app的建议 因为写入SMS Provider的能力会限制了要求app是用户选择的默认SMSapp,任何存在的app纯洁设计去备份和恢复SMS短信目前将不能让恢复SMS短消息在4.4 一个备份和恢复SMS消息的app必须要设置为默认的SMSapp这样它就可以在SMS提供者中写入短信。 然而,如果app没有发送和接收SMS消息,那么就不要保持默认的SMSapp。所以,你可以提供一个功能性的用户体验用下列设计,当用户打开你的app初始化一次恢复操作:
1.查询目前默认的SMS app的包名和储存它。 String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);
2.请求用户改变默认的SMSapp到你的app为了恢复SMS消息(你必须设置默认的SMS app 来写入SMS Provider)。 Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName()); startActivity(intent);
3.当你完成恢复了所有的SMS消息时,请求用户去改变默认的SMSapp返回到之前 的选择了的app(保存在步骤1中) Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp); startActivity(intent); 准备更新你的SMS app 我们鼓励你去更新你的apps尽快地提供给你的用户最好的体验在Android上面。 为了帮助你做出改变,我们尽可能地在4.4提供必要的SDK部分来允许你编译 和测试你的改变。敬请期待。