996的工作压力巨大,大家为了更好地隔离工作和生活,已经不满足于一机两号,而是直接进行两机两号的物理隔离。
工作的通讯录不想放在生活手机上,但有时确实需要在生活机上查看,这时候使用云同步不大合适,而本应用恰巧能够满足该使用场景。
用户在工作机和生活机上都安装该应用,并在工作机上通过按钮将本地通讯簿读取出来后,存入分布式数据库中,并通过分布式协同操作拉起生活机上的相同应用进行展示。
本应用主要功能是由本地读取通讯簿,通过分布式数据库传递给远端设备并拉起远端应用展示,从而达到在远端看到数据的效果。
鸿蒙的联系人操作方式要比Android的友好多的多,完全面向对象,屏蔽了那些复杂的表结构,不用时刻想着操作后就要commit,否则不生效。也不用随时随地握这一个_id增删改查,鸿蒙的开发小哥哥们都帮我们把这些事在底层搞定了,所以在鸿蒙系统上使用的十分顺滑。
鸿蒙的联系人操作的核心在于ContactsHelper这个类,通过构造不同的联系人特性来对联系人的不同属性进行查看、插入、修改与删除,具体代码如下。
private List<Contact> 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<Contact> 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 = 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<String> 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. 联系人权限在使用远程模拟调试时,签名一直无法成功,只能在真机上进行调测;
开发过安卓的联系人的小伙伴都知道,安卓的联系人操作直接操作provider,虽然功能强大,但是学习成本很高,很多同学都因此劝退。
但这波使用鸿蒙系统进行通讯录开发,使用的鸿蒙联系人接口,都是十分简单易懂联系人对象,十分友好。感谢这个模块开发工作者的辛勤劳动。
当然要是能给一份中文文档,联系人这个模块就更加易于上手了。
https://gitee.com/kiba03/HarmonyOSDevelopLab