uni-app 无法直接获取手机通讯录好友列表,因该能力在app端原生未实现;uni.getcontact仅支持微信小程序,app端调用静默失败或返回空;全量读取须自研原生插件并妥善处理权限、字段兼容与性能问题。

uni-app 无法直接获取手机通讯录好友列表——这不是权限没开或代码写错的问题,而是平台能力根本不存在。所谓“好友列表”,在原生系统里就是“全部联系人”,而 uni-app 的 JS 层 API(如 uni.getContact、uni.chooseContact)在 App 端(iOS/Android)压根不支持全量读取。
为什么 uni.getContact 在 App 上调用失败或返回空
这个 API 仅存在于微信小程序环境,App 平台(包括 H5、快应用等)根本没有实现。你在真机上执行 uni.getContact({ type: 'addressBook' }),结果只会是静默失败、回调不触发,或返回 { contactList: [] }。这不是 bug,是 uni-app 官方明确不提供的能力。HBuilderX 文档里没写支持,源码里也找不到对应桥接逻辑。
-
uni.getContact是微信小程序专属 API,App 端无对应 native 实现 - 即使 manifest.json 配了权限、plus.contacts 初始化成功,JS 层调用仍会直接跳过或报
undefined is not a function - 部分开发者误以为“H5+ 的 plus.contacts 已废弃”是旧资料,实际上它在 Android 12+ 和 iOS 16+ 上已严重不可靠,字段缺失、崩溃率高、权限校验失败是常态
真正能读全量联系人的唯一路径:自研原生插件
必须绕过 uni.* 封装,用 Java/Kotlin(Android)和 Objective-C/Swift(iOS)分别实现,再通过 JSCallback 暴露给 JS 层。plus.contacts 不再推荐,尤其对新系统版本。
- Android 端需动态申请
android.permission.READ_CONTACTS,且从 Android 11 开始还需声明android.permission.GET_ACCOUNTS才能枚举账户来源 - iOS 端必须在 Info.plist 中配置
NSContactsUsageDescription,否则首次调用直接 crash;且不能用 CNContactStore 的同步枚举(阻塞主线程),得用异步 fetch + 分页处理 - 返回数据结构不能硬编码字段名:比如
displayName在 Android 可能为空,要 fallback 到contactName;phoneNumbers在 iOS 是对象数组含.value,Android 是字符串数组,需统一清洗 - 联系人超 300 条时,不做线程隔离会导致白屏卡顿——务必用
AsyncTask(Android)或dispatch_async(iOS)搬运数据
别硬刚全量读取:先确认你真的需要“全部列表”
90% 的实际场景(填收货人、选紧急联系人、邀请好友)根本不需要拉取全部联系人。强行走全量路径,等于主动踩进权限拒绝率高、审核被拒(尤其 iOS)、机型兼容差、性能差四大坑。
- 优先用
uni.chooseContact:它跨平台稳定,只唤起原生选择器,用户点一个就返回一个{ name, mobile },不申请 READ_CONTACTS,也不触发隐私弹窗 - 若需搜索或分组展示,建议把联系人导出到云数据库(如 uniCloud),由服务端做模糊匹配和索引,前端只查接口——既规避原生权限,又支持全文检索、拼音首字母排序等复杂功能
- 用户首次拒绝权限后,
uni.openSetting必须在uni.getAuthSetting明确返回scope.contact: false后才能调用,否则 iOS 静默失败,Android 可能闪退
最常被忽略的一点:manifest.json 里勾选的权限只是 UI 提示,最终是否注入到原生包,要看生成的 android/app/src/main/AndroidManifest.xml 和 iOS/Info.plist 是否真实存在对应条目。真机调试前,务必打开打包后的原生工程手动核对——很多“权限已开却没反应”的问题,根源都在这里漏了一行配置。











