由于电话通信是如此开放的通信渠道 - 任何人都可以随时拨打或发送短信给任何号码 - 因此 Android 用户需要能够轻松阻止不需要的来电和短信。
在 Android 7.0 之前,Android 用户必须依赖下载的应用来限制来自骚扰电话号码的来电和短信。许多此类应用要么无法按预期工作,要么由于没有用于阻止来电和消息的适当 API 而提供不太理想的体验。
一些制造商可能会出厂自带自己的阻止解决方案,但如果用户更换设备,他们可能会因缺乏互操作性而完全丢失阻止列表。最后,即使使用者正在使用提供此类功能的拨号应用和消息客户端,他们可能仍然需要在每个应用中执行阻止操作,才能使阻止对来电和短信都生效。
功能
Android 7.0 版本引入了 BlockedNumberProvider
内容提供程序,用于存储用户指定的、不应通过电话通信(来电、短信、彩信)方式联系他们的电话号码列表。系统将遵守阻止列表中的号码,限制来自这些号码的来电和短信。Android 7.0 会显示阻止号码列表,并允许用户添加和移除号码。
此外,号码阻止功能使系统和平台上的相关应用能够协同工作,以帮助保护用户并简化体验。默认拨号器、默认消息客户端、UICC 特权应用以及与系统具有相同签名的应用都可以直接从阻止列表读取和写入。由于阻止号码存储在系统上,因此无论用户使用何种拨号或消息应用,这些号码都将保持阻止状态。最后,阻止号码列表可以在任何新设备上恢复,而与制造商无关。
- 用户将获得开箱即用的阻止功能保证,并且在切换应用或更换新手机时不会丢失其阻止列表。系统上的所有相关应用都可以共享同一个列表,从而为用户提供最简化的体验。
- 应用开发者无需开发自己的方式来管理阻止列表以及传入的来电和消息。他们可以直接使用平台提供的功能。
- 被用户选为默认的拨号器/消息应用可以读取和写入提供程序。其他应用可以使用
createManageBlockedNumbersIntent()
启动阻止列表管理用户界面 - OEM 可以使用平台提供的功能来出厂自带阻止功能。OEM 可以放心,当用户从其他 OEM 的设备切换过来时,他们将获得更好的上手体验,因为阻止列表也将被转移。
- 如果运营商有自己的拨号器或消息应用,他们可以重用平台功能,让用户维护阻止列表。他们可以放心,用户的阻止列表可以与用户同在,即使他们更换了新设备。最后,所有运营商特权应用都可以读取阻止列表,因此,如果运营商想要根据阻止列表为用户提供一些额外的更强大的阻止功能,现在可以通过此功能实现。
数据流

图 1. 阻止电话号码数据流
示例和源代码
以下是使用号码阻止新功能的示例调用
从应用启动阻止号码管理器
Context.startActivity(telecomManager.createManageBlockedNumbersIntent(), null);
查询阻止号码
Cursor c = getContentResolver().query(BlockedNumbers.CONTENT_URI, new String[]{BlockedNumbers.COLUMN_ID, BlockedNumbers.COLUMN_ORIGINAL_NUMBER, BlockedNumbers.COLUMN_E164_NUMBER}, null, null, null);
放入阻止号码
ContentValues values = new ContentValues(); values.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1234567890"); Uri uri = getContentResolver().insert(BlockedNumbers.CONTENT_URI, values);
删除阻止号码
ContentValues values = new ContentValues(); values.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1234567890"); Uri uri = getContentResolver().insert(BlockedNumbers.CONTENT_URI, values); getContentResolver().delete(uri, null, null);
实施
以下是将号码阻止功能投入使用必须完成的高级别任务
- OEM 通过使用
BlockedNumberProvider
在其设备上实现来电/消息限制功能 - 如果运营商有拨号器或消息应用,则通过使用
BlockedNumberProvider
实现来电/消息限制功能 - 第三方拨号器和消息应用供应商使用
BlockedNumberProvider
实现其阻止功能
给 OEM 的建议
如果设备之前从未附带任何额外的来电/消息限制功能,请在所有此类设备上使用 Android 开源项目 (AOSP) 中的号码阻止功能。建议支持合理的阻止入口点,例如直接从通话记录或消息线程中阻止号码。
如果设备之前已附带来电/消息限制功能,请调整这些功能,以便所有被阻止的严格匹配电话号码都存储在 BlockedNumberProvider
中,并且围绕提供程序的行为满足 Android 兼容性定义文档 (CDD) 中概述的此功能的要求。
任何其他高级功能都可以通过自定义提供程序和自定义 UI/控件来实现,只要与阻止严格匹配电话号码相关的 CDD 要求得到满足即可。建议将这些其他功能标记为“高级”功能,以避免与基本号码阻止功能混淆。
API
以下是正在使用的 API
TelecomManager API
Intent createManageBlockedNumbersIntent()
运营商配置
KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT
- 请参阅
BlockedNumberContract
- 由
BlockedNumberContract
提供的 API boolean isBlocked(Context context, String phoneNumber)
int unblock(Context context, String phoneNumber)
boolean canCurrentUserBlockNumbers(Context context)
- 由
用户界面
AOSP 中提供的 BlockedNumbersActivity.java 用户界面可以按原样使用。设备实现者也可以实现他们自己的 UI 版本,只要它满足相关的 CDD 要求。
请注意,可能需要合作伙伴的 PC 应用来进行备份和恢复,以便通过使用 BlockedNumberProvider
来实现阻止列表的恢复。请参阅下面的图片,了解 AOSP 中提供的阻止号码界面。

图 2. 阻止电话号码用户界面
验证
实施者可以通过运行以下 CTS 测试来确保其功能版本按预期工作
android.provider.cts.BlockedNumberContractTest com.android.cts.numberblocking.hostside.NumberBlockingTest android.telecom.cts.ExtendedInCallServiceTest#testIncomingCallFromBlockedNumber_IsRejected android.telephony.cts.SmsManagerTest#testSmsBlocking
在运行 $ adb root
后,可以使用 adb
命令来操作 BlockedNumberProvider
。例如
adb root
adb shell content query --uri content://com.android.blockednumber/blocked
adb shell content insert --uri / content://com.android.blockednumber/blocked --bind / original_number:s:'6501002000'
adb shell content delete --uri / content://com.android.blockednumber/blocked/1