Flutter名片APP开发:扫码后自动填充至新建联系人
解决方案:扫码提取数据并自动填充系统新建联系人界面
1. 补充扫码与系统交互依赖
qr_flutter仅负责生成二维码,扫码和系统联系人交互需要额外依赖,在pubspec.yaml中添加:
dependencies: qr_code_scanner: ^1.0.1 # 实现扫码功能 url_launcher: ^6.2.1 # 调用系统应用 contacts_service: ^0.6.3 # 处理联系人数据
2. 实现扫码并解析二维码数据
创建扫码页面,监听扫码结果并解析JSON格式的联系人数据:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; class QRScanPage extends StatefulWidget { const QRScanPage({super.key}); @override State<QRScanPage> createState() => _QRScanPageState(); } class _QRScanPageState extends State<QRScanPage> { final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); QRViewController? controller; @override void dispose() { controller?.dispose(); super.dispose(); } void _onQRViewCreated(QRViewController controller) { this.controller = controller; controller.scannedDataStream.listen((scanData) { controller.pauseCamera(); // 解析二维码中的JSON数据 try { Map<String, dynamic> contactData = jsonDecode(scanData.code!); _fillContactForm(contactData); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('二维码数据格式错误')), ); controller.resumeCamera(); } }); } void _fillContactForm(Map<String, dynamic> data) { // 后续实现填充逻辑 } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('扫码识别名片')), body: QRView( key: qrKey, onQRViewCreated: _onQRViewCreated, overlay: QrScannerOverlayShape( borderColor: Colors.blue, borderRadius: 10, borderLength: 30, borderWidth: 10, cutOutSize: MediaQuery.of(context).size.width * 0.8, ), ), ); } }
3. 自动填充系统新建联系人界面
提供两种实现方式,按需选择:
方式一:用url_launcher调用系统URI(无需权限)
构造联系人跳转URI,直接打开系统新建联系人界面并填充字段:
import 'package:url_launcher/url_launcher.dart'; void _fillContactForm(Map<String, dynamic> data) async { final Uri contactUri = Uri.parse( 'content://com.android.contacts/contacts/new' '?name=${Uri.encodeComponent(data['fname'] ?? '')}' '&phone=${Uri.encodeComponent(data['phone'] ?? '')}' '&email=${Uri.encodeComponent(data['email'] ?? '')}' '&company=${Uri.encodeComponent(data['job'] ?? '')}' '&address=${Uri.encodeComponent(data['adr'] ?? '')}', ); if (await canLaunchUrl(contactUri)) { await launchUrl(contactUri); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('无法打开联系人界面')), ); } Navigator.pop(context); }
方式二:用contacts_service创建并打开编辑界面(需权限)
适合需要稳定交互的场景,需先申请权限:
- 在
AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
- 实现代码:
import 'package:contacts_service/contacts_service.dart'; import 'package:flutter/services.dart'; void _fillContactForm(Map<String, dynamic> data) async { try { Contact newContact = Contact() ..givenName = data['fname'] ?? '' ..phones = [Item(label: 'mobile', value: data['phone'] ?? '')] ..emails = [Item(label: 'work', value: data['email'] ?? '')] ..jobTitle = data['job'] ?? '' ..postalAddresses = [Item(label: 'work', value: data['adr'] ?? '')]; await ContactsService.addContact(newContact); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('联系人已添加,可前往通讯录编辑')), ); } on PlatformException catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('添加失败:${e.message}')), ); } Navigator.pop(context); }
4. 优化二维码生成(可选)
将JSON转为vCard格式生成二维码,多数扫码工具可直接识别并提示添加联系人:
// 生成vCard字符串 String generateVCard(Map<String, dynamic> data) { return '''BEGIN:VCARD VERSION:3.0 FN:${data['fname']} TEL;TYPE=CELL:${data['phone']} EMAIL;TYPE=WORK:${data['email']} TITLE:${data['job']} ADR;TYPE=WORK:;;${data['adr']};;; END:VCARD'''; } // 使用vCard生成二维码 QrImageView( data: generateVCard(qrData), // qrData为原始联系人Map数据 size: 200, backgroundColor: Colors.white, version: QrVersions.auto, ),
内容的提问来源于stack exchange,提问作者Aouiche Redouane
相关产品推荐
相关产品推荐

