自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
实现电话号码屏蔽功能
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
电话是一种开放的通信渠道,任何人都可以随时向任何电话号码致电或者发送短信,因此 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) 中针对此功能列出的要求。
只要满足 CDD 中有关屏蔽严格匹配的电话号码的要求,便可以通过自定义提供程序和自定义界面/控件来实现其他高级功能。建议将其他功能标记为“高级”功能,以避免与基本号码屏蔽功能相混淆。
API
以下是使用的 API:
TelecomManager
API
Intent createManageBlockedNumbersIntent()
Carrier
Config
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 界面可以按原样使用。只要符合相关 CDD 要求,设备实现人员也可以实现自己的界面版本。
请注意,如需使用 BlockedNumberProvider
来实现恢复屏蔽列表的功能,可能需要合作伙伴的用于进行备份和恢复的 PC 应用。如需查看 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
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# Implement phone number blocking\n\nBecause telephony is such an open communications channel - anyone may call or\ntext any number at any time - Android users need the ability to easily block\nunwanted calls and texts.\n\n\nBefore Android 7.0, Android users had to rely on downloaded apps to restrict calls and\ntexts from bothersome phone numbers. Many of those apps either do not work as\ndesired or provide a less-than ideal experience because there are no proper APIs\nfor blocking calls and messages.\n\n\nSome manufacturers might ship their own blocking solutions out-of-the-box, but\nif users switch devices, they may lose the blocked list completely due to lack\nof interoperability. Finally, even if users are employing dialing apps and\nmessaging clients that provide such functionality, they likely still have to\nperform the block action in each app for the block to take effect for both\ncalling and texting.\n\nFeatures\n--------\n\n\nThe Android 7.0 release introduces a `BlockedNumberProvider` content\nprovider that stores a list of phone numbers the user has specified should not\nbe able to contact them via telephony communications (calls, SMS, MMS). The\nsystem will respect the numbers in the blocked list by restricting calls and\ntexts from those numbers. Android 7.0 displays the list of blocked numbers and\nallows the user to add and remove numbers.\n\n\nFurther, the number-blocking feature enables the system and the relevant apps on\nthe platform to work together to help protect the user and to simplify the\nexperience. The default dialer, default messaging client, UICC-privileged app,\nand apps with the same signature as the system can all directly read from and\nwrite to the blocked list. Because the blocked numbers are stored on the system,\nno matter what dialing or messaging apps the user employs, the numbers stay\nblocked. Finally, the blocked numbers list may be restored on any new device,\nregardless of the manufacturer.\n\n- User will be guaranteed to have a blocking feature that works out-of-the-box and will not lose their block list when they switch apps or get a new phone. All relevant apps on the system can share the same list to provide the user with the most streamlined experience.\n- App developers do not need to develop their own way to manage a block list and the calls and messages that come in. They can simply use the platform-provided feature.\n- Dialer / messenger apps that are selected as the default by the user can read and write to the provider. Other apps can launch the block list management user interface by using `createManageBlockedNumbersIntent()`\n- OEMs can use platform provided feature to ship a blocking feature out-of-the-box. OEMs can rest assured that when users switch from another OEM's device that they have a better onboarding experience because the block list will be transferred as well.\n- If carrier has their own dialer or messenger app, they can reuse platform feature for allowing the user to maintain a block list. They can rest assured that the user's block list can stay with the users, even when they get a new device. Finally, all carrier-privileged apps can read the block list, so if the carrier wants to provide some additional more powerful blocking for the user based on the block list, that is now possible with this feature.\n\nData flow\n---------\n\n\n**Figure 1.** Block phone numbers data flow\n\nExamples and source\n-------------------\n\n\nHere are example calls using the number-blocking new feature:\n\n### Launch blocked number manager from app\n\n```text\nContext.startActivity(telecomManager.createManageBlockedNumbersIntent(), null);\n```\n\n### Query blocked numbers\n\n```scdoc\nCursor c = getContentResolver().query(BlockedNumbers.CONTENT_URI,\n new String[]{BlockedNumbers.COLUMN_ID,\n BlockedNumbers.COLUMN_ORIGINAL_NUMBER,\n BlockedNumbers.COLUMN_E164_NUMBER}, null, null, null);\n```\n\n### Put blocked number\n\n```scdoc\nContentValues values = new ContentValues();\nvalues.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, \"1234567890\");\nUri uri = getContentResolver().insert(BlockedNumbers.CONTENT_URI, values);\n```\n\n### Delete blocked number\n\n```scdoc\nContentValues values = new ContentValues();\nvalues.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, \"1234567890\");\nUri uri = getContentResolver().insert(BlockedNumbers.CONTENT_URI, values);\ngetContentResolver().delete(uri, null, null);\n```\n\nImplementation\n--------------\n\n\nThese are the high-level tasks that must be completed to put the number-blocking\nfeature to use:\n\n- OEMs implement call/message-restriction features on their devices by using `BlockedNumberProvider`\n- If carrier has dialer or messenger app, implement call/message restriction features by using `BlockedNumberProvider`\n- Third-party dialer and messenger app vendors use `BlockedNumberProvider` for their blocking features\n\n### Recommendations for OEMs\n\n\nIf the device had previously never shipped with any additional call/message\nrestriction features, use the number-blocking feature in the Android Open Source\nProject (AOSP) on all such devices. It is recommended that reasonable entry\npoints for blocking are supported, such as blocking a number right from the call\nlog or within a message thread.\n\n\nIf the device had previously shipped with call/message restriction features,\nadapt the features so all *strict-match phone numbers* that are blocked\nare stored in the `BlockedNumberProvider,` and that the behavior\naround the provider satisfy the requirements for this feature outlined in the\nAndroid Compatibility Definition Document (CDD).\n\n\nAny other advanced feature can be implemented via custom providers and custom UI\n/ controls, as long as the CDD requirements are satisfied with regards to\nblocking strict-match phone numbers. It is recommended that those other features\nbe labeled as \"advanced\" features to avoid confusion with the basic\nnumber-blocking feature.\n\n### APIs\n\n\nHere are the APIs in use:\n\n- [TelecomManager](http://developer.android.com/reference/android/telecom/TelecomManager.html)`\n API`\n - `Intent createManageBlockedNumbersIntent()`\n- [Carrier\n Config](http://developer.android.com/reference/android/telephony/CarrierConfigManager.html)\n - `KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT`\n- Please refer to `BlockedNumberContract`\n - APIs provided by [BlockedNumberContract](https://developer.android.com/reference/android/provider/BlockedNumberContract.html)\n - `boolean isBlocked(Context context, String phoneNumber)`\n - `int unblock(Context context, String phoneNumber)`\n - `boolean canCurrentUserBlockNumbers(Context context)`\n\n### User interface\n\n\nThe BlockedNumbersActivity.java user interface provided in AOSP can be used as\nis. Device implementers may also implement their own version of the UI, as long as it\nsatisfies related CDD requirements.\n\n\nPlease note, the partner's PC app for backup and restore may be needed\nto implement restoration of the block list by using\n`BlockedNumberProvider`. See the images below for the blocked\nnumbers interface supplied in AOSP.\n\n\n**Figure 2.** Block phone numbers user interface\n\nValidation\n----------\n\n\nImplementers can ensure their version of the feature works as intended by\nrunning the following CTS tests: \n\n```\nandroid.provider.cts.BlockedNumberContractTest\ncom.android.cts.numberblocking.hostside.NumberBlockingTest\nandroid.telecom.cts.ExtendedInCallServiceTest#testIncomingCallFromBlockedNumber_IsRejected\nandroid.telephony.cts.SmsManagerTest#testSmsBlocking\n```\n\n\nThe `BlockedNumberProvider` can be manipulated using `adb` commands\nafter running `$ adb root`. For example: \n\n adb root\n adb shell content query --uri content://com.android.blockednumber/blocked\n adb shell content insert --uri / content://com.android.blockednumber/blocked --bind / original_number:s:'6501002000'\n adb shell content delete --uri / content://com.android.blockednumber/blocked/1"]]