鸿蒙|轻松玩转HarmonyOS分布式应用开发——分布式通讯录

一、背景 996的工作压力巨大,大家为了更好地隔离工作和生活,已经不满足于一机两号,而是直接进行两机两号的物理隔离。
工作的通讯录不想放在生活手机上,但有时确实需要在生活机上查看,这时候使用云同步不大合适,而本应用恰巧能够满足该使用场景。
用户在工作机和生活机上都安装该应用,并在工作机上通过按钮将本地通讯簿读取出来后,存入分布式数据库中,并通过分布式协同操作拉起生活机上的相同应用进行展示。
二、代码实现 本应用主要功能是由本地读取通讯簿,通过分布式数据库传递给远端设备并拉起远端应用展示,从而达到在远端看到数据的效果。
读取联系人 鸿蒙的联系人操作方式要比Android的友好多的多,完全面向对象,屏蔽了那些复杂的表结构,不用时刻想着操作后就要commit,否则不生效。也不用随时随地握这一个_id增删改查,鸿蒙的开发小哥哥们都帮我们把这些事在底层搞定了,所以在鸿蒙系统上使用的十分顺滑。
鸿蒙的联系人操作的核心在于ContactsHelper这个类,通过构造不同的联系人特性来对联系人的不同属性进行查看、插入、修改与删除,具体代码如下。

private List readContacts() { ContactsHelper contactsHelper = new ContactsHelper(getContext()); ContactAttributes contactAttributes = new ContactAttributes(); contactAttributes.add(ContactAttributes.Attribute.ATTR_NAME); contactAttributes.add(ContactAttributes.Attribute.ATTR_PHONE); ContactsCollection contactsCollection = contactsHelper.queryContacts(null, contactAttributes); Contact contact = contactsCollection.next(); List contacts = new ArrayList<>(); StringBuilder datas = new StringBuilder(); String device = KvManagerFactory.getInstance() .createKvManager(new KvManagerConfig(getContext())) .getLocalDeviceInfo().getName(); while (contact != null) { contacts.add(contact); LogUtil.info(TAG, contact.getName().getFullName()); String name = contact.getName().getFullName(); String num = contact.getPhoneNumbers() == null ? "" : contact.getPhoneNumbers().get(0).getPhoneNumber(); StringBuilder sb = new StringBuilder(); sb.append(name).append(SEPARATOR).append(num).append(SEPARATOR).append(device); mContactList.add(new ContactItemViewHolder(name, num, device)); contact = contactsCollection.next(); datas.append(sb.toString()).append(SEPARATOR_DATA); } singleKvStore.putString(CONSTACTS_KEY, datas.toString()); return contacts; }

读取对端联系人
private void readRemoteContacts() { String remoteData = https://www.it610.com/article/singleKvStore.getString(CONSTACTS_KEY); LogUtil.info(TAG,"remote data:" + remoteData); String[] datas = remoteData.split(SEPARATOR_DATA); for (String data : datas) { String[] params = data.split(SEPARATOR); mContactList.add(new ContactItemViewHolder(params[0], params[1], params[2])); } }

分布式操作 本应用主要使用SingleKvStore分布式数据库功能传递联系人信息,由本端存入,再拉起对端,由对端显示。
该部分代码主要参考Codelab的demo,套用了其中分布式的范式代码,具体实现可以见工程代码。
权限管理 权限声明
"reqPermissions": [ { "reason": "多设备协同", "name": "ohos.permission.DISTRIBUTED_DATASYNC", "usedScene": { "ability": [ "com.xlab.xlabtestapp.slice.MainAbilitySlice" ], "when": "always" } }, { "name": "ohos.permission.READ_CONTACTS", "reason": "需要联系人权限", "usedScene": { "ability": [ "com.xlab.xlabtestapp.slice.MainAbilitySlice" ], "when": "always" } }, { "name": "ohos.permission.WRITE_CONTACTS", "reason": "需要联系人权限", "usedScene": { "ability": [ "com.xlab.xlabtestapp.slice.MainAbilitySlice" ], "when": "always" } } ]

动态请求 鸿蒙中高危权限需要动态请求,并且第一次新增时,还要求进行重新签名。
private void requestPermissions() { String[] permissions = { SystemPermission.READ_CONTACTS, SystemPermission.WRITE_CONTACTS, SystemPermission.DISTRIBUTED_DATASYNC }; List permissionsToProcess = new ArrayList<>(); for (String permission : permissions) { if (verifySelfPermission(permission) != IBundleManager.PERMISSION_GRANTED && canRequestPermission(permission)) { permissionsToProcess.add(permission); } } requestPermissionsFromUser(permissionsToProcess.toArray(new String[0]), 0); }

其中联系人是高危权限,不知道为啥远程模拟签名总是显示没有连接鸿蒙设备,但是真机上是没问题的。
四、遇到的坑 本项目开发中遇到了大量机制性的坑。
高危权限申请 联系人权限申请,一直只声明了,但是没有进行动态请求,导致权限一直不生效。具体权限管理方法见上文。
真机签名 实体机安装应用时,需要进行签名,该签名具体设置步骤请参照。
使用真机进行调试
远程模拟机调试 这是我遇到最大的坑了,至今还在坑里蹲着。
a. 首先想用DevEco进行远程模拟调试分布式应用,需要升级到3.0.0;
b. 联系人权限在使用远程模拟调试时,签名一直无法成功,只能在真机上进行调测;
五、夸夸HarmonyOs 开发过安卓的联系人的小伙伴都知道,安卓的联系人操作直接操作provider,虽然功能强大,但是学习成本很高,很多同学都因此劝退。
但这波使用鸿蒙系统进行通讯录开发,使用的鸿蒙联系人接口,都是十分简单易懂联系人对象,十分友好。感谢这个模块开发工作者的辛勤劳动。
当然要是能给一份中文文档,联系人这个模块就更加易于上手了。
六、工程代码 【鸿蒙|轻松玩转HarmonyOS分布式应用开发——分布式通讯录】https://gitee.com/kiba03/HarmonyOSDevelopLab

    推荐阅读