Flutter插件鸿蒙化,flutter_native_contact_picker_plus联系人选择器的跨平台适配实践【下篇】
接上篇:Flutter插件鸿蒙化,flutter_native_contact_picker_plus联系人选择器的跨平台适配实践【上篇】
4.ios侧处理
类似ios侧处理这边的Contact,并返回
var data = Dictionary() data[\"fullName\"] = CNContactFormatter.string(from: contact, style: CNContactFormatterStyle.fullName) let numbers: Array = contact.phoneNumbers.compactMap { $0.value.stringValue as String } data[\"phoneNumbers\"] = numbers result(data)
5.ArkTS处理单选联系人
contact.selectContacts({ isMultiSelect: false }, (err: BusinessError, data) => { if (err) { console.error(`Failed to select Contacts. Code: ${err.code}, message: ${err.message}`); return; } const contactInfo = new Map<string, string | string[]>(); if (data && data.length > 0) { const contact: contact.Contact = data[0]; contactInfo.set(\"fullName\", contact.name?.fullName || \"\"); const phoneNumbers: string[] = contact.phoneNumbers?.map(item => item.phoneNumber) || []; contactInfo.set(\"phoneNumbers\", phoneNumbers); if (contact.emails && contact.emails.length > 0) { const emails: string[] = contact.emails.map(item => item.email); contactInfo.set(\"emails\", emails); } } let jsonObject: Record<string, Object> = {}; contactInfo.forEach((value, key) => { if (key !== undefined && value !== undefined) { jsonObject[key] = value; } }) console.info(`Succeeded in selecting Contacts. data->${JSON.stringify(jsonObject)}`); result.success(jsonObject) });
6.ArkTS处理多选联系人
多选的处理方式
7.完整的代码
import { FlutterPlugin, FlutterPluginBinding, MethodCall, MethodCallHandler, MethodChannel, MethodResult,} from \'@ohos/flutter_ohos\';import { contact } from \'@kit.ContactsKit\';import { BusinessError } from \'@kit.BasicServicesKit\';/** FlutterNativeContactPickerPlusPlugin **/export default class FlutterNativeContactPickerPlusPlugin implements FlutterPlugin, MethodCallHandler { private channel: MethodChannel | null = null; constructor() { } getUniqueClassName(): string { return \"FlutterNativeContactPickerPlusPlugin\" } onAttachedToEngine(binding: FlutterPluginBinding): void { this.channel = new MethodChannel(binding.getBinaryMessenger(), \"flutter_native_contact_picker_plus\"); this.channel.setMethodCallHandler(this) } onDetachedFromEngine(binding: FlutterPluginBinding): void { if (this.channel != null) { this.channel.setMethodCallHandler(null) } } onMethodCall(call: MethodCall, result: MethodResult): void { console.info(\" call.method 被调用\" + JSON.stringify(call.method)); if (call.method == \"getPlatformVersion\") { result.success(\"OpenHarmony ^ ^ \") } else if (call.method == \"selectContact\") { contact.selectContacts({ isMultiSelect: false }, (err: BusinessError, data) => { if (err) { console.error(`Failed to select Contacts. Code: ${err.code}, message: ${err.message}`); return; } const contactInfo = new Map<string, string | string[]>(); if (data && data.length > 0) { const contact: contact.Contact = data[0]; contactInfo.set(\"fullName\", contact.name?.fullName || \"\"); const phoneNumbers: string[] = contact.phoneNumbers?.map(item => item.phoneNumber) || []; contactInfo.set(\"phoneNumbers\", phoneNumbers); if (contact.emails && contact.emails.length > 0) { const emails: string[] = contact.emails.map(item => item.email); contactInfo.set(\"emails\", emails); } } let jsonObject: Record<string, Object> = {}; contactInfo.forEach((value, key) => { if (key !== undefined && value !== undefined) { jsonObject[key] = value; } }) console.info(`Succeeded in selecting Contacts. data->${JSON.stringify(jsonObject)}`); result.success(jsonObject) }); } else if (call.method == \"selectContacts\") { console.info(\" selectContacts 被调用\"); contact.selectContacts({ isMultiSelect: true }, (err: BusinessError, data) => { if (err) { console.error(`Failed to select Contacts. Code: ${err.code}, message: ${err.message}`); result.error(err.code.toString(), err.message, null); return; } console.info(`Succeeded in selecting Contacts. data->${JSON.stringify(data)}`); const selectedContacts: contact.Contact[] = []; if (data && data.length > 0) { for (const contact of data) { const contactInfo = new Map<string, string | string[]>(); contactInfo.set(\"fullName\", contact.name?.fullName || \"\"); const phoneNumbers: string[] = contact.phoneNumbers?.map(item => item.phoneNumber) || []; contactInfo.set(\"phoneNumbers\", phoneNumbers); if (contact.emails && contact.emails.length > 0) { const emails: string[] = contact.emails.map(item => item.email); contactInfo.set(\"emails\", emails); } let jsonObject: Record<string, Object> = {}; contactInfo.forEach((value, key) => { if (key !== undefined && value !== undefined) { jsonObject[key] = value; } }); selectedContacts.push(jsonObject); } } console.info(`Succeeded in selecting Contacts. data->${JSON.stringify(selectedContacts)}`); result.success(selectedContacts); }); } else { result.notImplemented(); } }}
参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-uiabilitycontext#uiabilitycontextterminateself-1和https://gitcode.com/openharmony-sig/flutter_contacts/tree/master/ohos/src/main/ets/components
四、编写 Example
1. 创建 Example 应用
在插件根目录下创建一个名为 example
的文件夹,用于存放示例应用。在 example
文件夹中,创建一个鸿蒙平台的 Flutter 应用,用于验证插件功能。
2. 签名与运行
使用 Deveco Studio
打开 example > ohos
目录,单击 File > Project Structure > Project > Signing Configs
,勾选 Automatically generate signature
,等待自动签名完成。然后运行以下命令:
flutter pub get flutter build hap --debug
如果应用正常启动,说明插件适配成功。如果没有,欢迎大家联系坚果派一起支持。
五、总结
通过以上步骤,我们成功地将 flutter_native_contact_picker 三方库适配到了鸿蒙平台。这个过程涉及到了解插件的基本信息、配置开发环境、创建鸿蒙模块、编写原生代码以及测试验证等多个环节。希望这篇博客能够帮助到需要进行 flutter_native_contact_picker 鸿蒙适配的开发者们,让大家在鸿蒙生态的开发中更加得心应手。
六、参考
- [如何使用Flutter与OpenHarmony通信 FlutterChannel](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/如何使用Flutter与OpenHarmony通信 FlutterChannel.md)
- [开发module](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/如何使用混合开发 module.md)
- 开发package
- 开发plugin
- [开发FFI plugin](https://gitcode.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/开发FFI plugin.md)
- developing-packages
- 适配仓库地址
七、FAQ
如何将Map转换为JSON字符串
可以将Map转成Record后,再通过JSON.stringify()转为JSON字符串。示例如下
const contactInfo = new Map<string, string | string[]>(); if (data && data.length > 0) { const contact: contact.Contact = data[0]; contactInfo.set(\"fullName\", contact.name?.fullName || \"\"); const phoneNumbers: string[] = contact.phoneNumbers?.map(item => item.phoneNumber) || []; contactInfo.set(\"phoneNumbers\", phoneNumbers); if (contact.emails && contact.emails.length > 0) { const emails: string[] = contact.emails.map(item => item.email); contactInfo.set(\"emails\", emails); } } let jsonObject: Record<string, Object> = {}; contactInfo.forEach((value, key) => { if (key !== undefined && value !== undefined) { jsonObject[key] = value; } }) console.info(`Succeeded in selecting Contacts. data->${JSON.stringify(jsonObject)}`);
如何判断是鸿蒙平台
import \'dart:io\'; Platform.operatingSystem == \'ohos\';
八、使用示例
import \'package:flutter/material.dart\';import \'package:flutter_native_contact_picker_plus/flutter_native_contact_picker_plus.dart\';void main() { runApp(const MyApp());}class MyApp extends StatefulWidget { const MyApp({super.key}); @override MyAppState createState() => MyAppState();}class MyAppState extends State<MyApp> { final FlutterContactPickerPlus _contactPicker = FlutterContactPickerPlus(); List<Contact>? _contacts; @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text(\'Contact Picker Example App\'), ), body: Center( child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ MaterialButton( color: Colors.blue, child: const Text(\"Single\"), onPressed: () async { Contact? contact = await _contactPicker.selectContact(); setState(() { _contacts = contact == null ? null : [contact]; }); }, ), MaterialButton( color: Colors.blue, child: const Text(\"Multiple\"), onPressed: () async { final contacts = await _contactPicker.selectContacts(); setState(() { _contacts = contacts; }); }, ), if (_contacts != null) ..._contacts!.map( (e) => Text(e.toString()), ) ], ), ), ), ); }}
九、坚果派
坚果派由坚果等人创建,团队拥有若干华为HDE,以及若干其他领域的三十余位万粉博主运营。专注于分享的技术包括HarmonyOS/OpenHarmony,ArkUI-X,元服务,服务卡片,华为自研语言,BlueOS操作系统、团队成员聚集在北京、上海、广州、深圳、南京、杭州、苏州、宁夏等地。 聚焦“鸿蒙原生应用”、“智能物联”和“AI赋能”、“人工智能”四大技术领域,依托华为开发者专家等强大的技术团队,以及涵盖需求、开发、测试、运维于一体的综合服务体系,赋能文旅、媒体、社交、家居、消费电子等行业客户,帮助开发者实现价值提升。 目前上架鸿蒙原生应用18款,三方库80个。
地址:https://atomgit.com/nutpi
https://gitcode.com/nutpi
官网:https://www.nutpi.net/