React Native自定义原生模块获取联系人在Android 11及以上失效如何解决
故障根因
Android 11(API 30)新增了应用包可见性过滤规则,即使你已经正确申请了READ_CONTACTS权限,只要没有在清单文件中声明需要查询通讯录应用的规则,调用系统通讯录的请求就会被系统拦截,导致原生模块无法拿到返回的联系人数据。
修复方案
- 第一步:在安卓项目的
AndroidManifest.xml中添加包可见性声明,注意要写在manifest根节点下,和application节点平级:
<queries> <intent> <action android:name="android.intent.action.PICK" /> <data android:mimeType="vnd.android.cursor.dir/phone_v2" /> </intent> </queries>
- 第二步:检查原生模块中启动通讯录选择页的代码,使用官方推荐的标准写法:
// 原生模块Java示例代码 private static final int REQUEST_CODE_PICK_CONTACT = 1001; public void launchContactPicker() { Intent pickContactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI); if (pickContactIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(pickContactIntent, REQUEST_CODE_PICK_CONTACT); } }
- 第三步:如果你的项目
compileSdkVersion低于30,添加上述queries标签会触发编译报错,可以在gradle.properties中添加以下配置临时兼容:
android.jetifier.ignorelist=androidx.core:core
可选校验项
- 确认原生模块的
onActivityResult回调中,是通过系统返回的uri查询联系人数据,而非硬编码的联系人表uri,Android 11之后限制了直接访问全量联系人表的权限 - 可以在你现有JS代码的catch回调中打印完整错误信息,确认是否是原生层返回的「没有找到处理该intent的应用」类错误
内容的提问来源于stack exchange,提问作者zainal abidin
相关产品推荐
相关产品推荐

