API 31+下无需READ_PHONE_NUMBERS权限获取自定义PhoneAccount的方法
解决API31+下调用TelecomManager.getPhoneAccount()无需READ_PHONE_NUMBERS权限的方案
核心原因
API 31(Android 12)起,TelecomManager.getPhoneAccount()要求READ_PHONE_NUMBERS权限,哪怕是你自己应用创建并注册的PhoneAccount——这是系统权限机制的限制,和是否访问真实手机号无关。
方案1:直接复用自己构建的PhoneAccount实例
你已经通过PhoneAccount.builder()创建并完成了注册,完全不需要再调用getPhoneAccount()去获取。直接使用你build好的phoneAccount对象即可:
// 构建并注册 val builder = PhoneAccount.builder( phoneAccountHandle, this.resources.getText(R.string.app_name) ) val uri = Uri.parse("tel:1236547") builder.setSubscriptionAddress(uri) builder.setAddress(uri) builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) val phoneAccount = builder.build() manager.registerPhoneAccount(phoneAccount) // 直接使用这个phoneAccount,无需再调用getPhoneAccount() // 后续逻辑直接用phoneAccount变量即可
方案2:获取当前应用注册的所有PhoneAccount(无权限要求)
如果需要在注册后(比如应用重启后)重新获取自己的PhoneAccount,使用TelecomManager.getPhoneAccountsForPackage()方法——这个方法从API26开始支持,不需要任何权限,只会返回当前应用注册的PhoneAccount列表:
val manager = getSystemService(Context.TELECOM_SERVICE) as TelecomManager val myPhoneAccounts = manager.getPhoneAccountsForPackage(packageName) // 筛选出匹配自己的PhoneAccountHandle的项 val targetAccount = myPhoneAccounts.firstOrNull { it.accountHandle == phoneAccountHandle }
为什么这两个方案可行?
- 方案1:你手动构建的
PhoneAccount是完整的实例,和系统中注册的内容完全一致,直接复用就不会触发权限检查。 - 方案2:
getPhoneAccountsForPackage()是系统为应用提供的、仅访问自身注册账号的方法,设计上就不需要权限,完美避开了READ_PHONE_NUMBERS的限制。
内容的提问来源于stack exchange,提问作者Mohammad Taqi
相关产品推荐
相关产品推荐

