使用 Google Messenger 时发现它有设置默认短信应用的功能,于是研究了一下实现方式。
Android 4.4 KitKat 开始,Google 推出了默认短信应用的机制。官方对此的解释是:
Some of you have built SMS apps using hidden APIs — a practice we discourage because hidden APIs may be changed or removed and new devices are not tested against them for compatibility. So, to provide you with a fully supported set of APIs for building SMS apps.
简而言之,做得足够好、用户量足够大,Google 就会重视并官方支持。
API 概览#
从 Android 4.4 开始引入了两个新 Intent:
SMS_DELIVER_ACTION — 短信WAP_PUSH_DELIVER_ACTION — 彩信
设置默认应用#
1
2
3
| Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getPackageName());
startActivity(intent);
|
完整实现:注册与取消注册#
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
| // 检查当前是否是默认短信应用
currentPackageName = getPackageName();
String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(this);
if (currentPackageName != null && !currentPackageName.equals(defaultSmsApp)) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(DEDAULTSMS, defaultSmsApp);
editor.apply();
}
// 注册为默认
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getPackageName());
startActivity(intent);
}
});
// 恢复默认
unregister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
String defaultSmsApp = sharedPreferences.getString(DEDAULTSMS, null);
if (defaultSmsApp != null) {
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp);
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "failed unregister", Toast.LENGTH_SHORT).show();
}
}
});
|
关键逻辑说明#
代码的核心思路:
- 启动时保存当前默认短信应用的包名到 SharedPreferences
- 用户点击"注册"时,将自己设为默认
- 用户点击"取消注册"时,从 SharedPreferences 读取之前的默认应用并恢复
关于 Android Q (10) 的变更:
从 Android 10 开始,Google 引入了 RoleManager API,推荐使用 RoleManager.createRequestRoleIntent(RoleManager.ROLE_SMS) 替代旧的 ACTION_CHANGE_DEFAULT 方式。但上述实现仍兼容大多数版本。
参考资料#