如何用Flutter读取手机联系人详情并保存到应用内
Flutter 调取系统联系人实现自动填充方案
第一步:引入依赖包
我们用两个成熟的官方维护包实现功能:
contacts_service:专门用于读取系统通讯录数据permission_handler:用于处理通讯录权限申请
先在pubspec.yaml里添加依赖:
dependencies: flutter: sdk: flutter contacts_service: ^0.6.3 permission_handler: ^10.2.0
添加后执行flutter pub get安装依赖。
第二步:配置平台权限
安卓端配置
打开android/app/src/main/AndroidManifest.xml,在<manifest>标签下添加读取联系人权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
iOS端配置
打开ios/Runner/Info.plist,在<dict>标签下添加权限申请说明:
<key>NSContactsUsageDescription</key> <string>需要访问通讯录以快速填充客户信息</string>
第三步:权限申请逻辑
先判断用户是否授予了通讯录读取权限,未授权时先发起授权申请:
import 'package:permission_handler/permission_handler.dart'; // 返回是否获得通讯录权限 Future<bool> checkContactsPermission() async { var status = await Permission.contacts.status; if (status.isDenied) { status = await Permission.contacts.request(); } return status.isGranted; }
如果权限被永久拒绝,可自行加提示引导用户到系统设置页开启权限。
第四步:核心功能实现
1. 读取全部联系人数据
获得权限后调用方法获取所有系统联系人:
import 'package:contacts_service/contacts_service.dart'; Future<List<Contact>> getAllSystemContacts() async { // 带头像的话可以把withThumbnails设为true,不需要的话关了性能更好 return await ContactsService.getContacts(withThumbnails: false); }
2. 联系人搜索功能
拿到全量联系人后,根据输入的关键词做本地过滤即可:
List<Contact> filterContactList(List<Contact> fullList, String searchKey) { if (searchKey.trim().isEmpty) return fullList; final lowerKey = searchKey.toLowerCase(); return fullList.where((contact) { // 匹配姓名 bool matchName = contact.displayName?.toLowerCase().contains(lowerKey) ?? false; // 匹配手机号 bool matchPhone = false; if (contact.phones?.isNotEmpty == true) { matchPhone = contact.phones!.any((phone) => phone.value?.contains(lowerKey) ?? false); } return matchName || matchPhone; }).toList(); }
你可以自己写列表页展示过滤后的联系人,也可以直接用全量列表展示。
3. 选中联系人后提取字段
用户点击对应联系人后,直接提取你需要的字段填充到表单即可:
Map<String, String> extractCustomerInfo(Contact selectedContact) { // 提取姓名 String name = selectedContact.displayName ?? ''; // 提取手机号,取第一条即可,有多个号码需求可以自己遍历 String phone = selectedContact.phones?.isNotEmpty == true ? selectedContact.phones!.first.value?.replaceAll(' ', '') ?? '' : ''; // 提取邮箱 String email = selectedContact.emails?.isNotEmpty == true ? selectedContact.emails!.first.value ?? '' : ''; // 提取地址,拼接完整地址 String address = ''; if (selectedContact.postalAddresses?.isNotEmpty == true) { final addr = selectedContact.postalAddresses!.first; address = '${addr.street ?? ''} ${addr.city ?? ''} ${addr.region ?? ''} ${addr.postalCode ?? ''}'; } // 提取公司名称 String company = selectedContact.company ?? ''; return { 'name': name, 'phone': phone, 'email': email, 'address': address, 'company': company }; }
拿到返回的Map后直接赋值给你的客户信息表单字段就完成了自动填充。
注意事项
- 联系人数量较多时,读取操作建议加loading动画,避免页面卡顿
- 安卓13及以上版本的通讯录权限已经被
permission_handler适配,不需要额外处理 - 如果不需要展示全量联系人列表只想调系统原生联系人选择器,可以自己封装原生通道实现,或使用其他支持原生选择器的社区包
内容的提问来源于stack exchange,提问作者Fathima Shafana
相关产品推荐
相关产品推荐

