您现在的位置是:亿华云 > 应用开发
HarmonyOS 项目实战之通讯录Demo(JS)
亿华云2025-10-02 16:33:30【应用开发】3人已围观
简介想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com1 简介通讯录demo主要分为联系人界面、设置紧急联系人、服务卡片3个模块,分为Java和
想了解更多内容,目实请访问:
和华为官方合作共建的通讯鸿蒙技术社区
https://harmonyos.51cto.com
1 简介
通讯录demo主要分为联系人界面、设置紧急联系人、目实服务卡片3个模块,通讯分为Java和JS两个版本,目实本篇主要讲解用尽可能的通讯用纯JS去实现,实在无法实现的目实地方采用JS与Java结合。
1.1 原型
感兴趣的通讯小伙伴,可以自己根据原型效果自己尝试着去实现【通讯录demo简易原型】。目实



1.2 场景延伸
通过学习与练习本demo,通讯可以延伸至以下场景。目实



2 功能开发
2.1 联系人列表
2.1.1 实现效果

2.1.2 核心代码
参考:基于JS扩展的通讯类Web开发范式-组件-容器组件-list
关键属性 indexer=“true”
<!-- list --> <list id="address_list" class="list-wrapper" indexer="true" indexerbubble="true" shapemode="rect" initialindex="0"> <block for="{ { list_data }}"> <list-item section="{ { $item.item_section }}" class="todo-item"> <div class="item-wrapper" @click="onItemClick($item)" @longpress="onItemLongPress($item)"> <image class="item-icon" src="{ { $item.item_icon }}"></image> <text class="item-name">{ { $item.item_name }}</text> </div> </list-item> </block> </list>2.2 三方跳转
2.2.1 实现效果

2.2.2 js和java通信
js打开三方应用目前还不知道如何操作,我们通过js调java方法来实现跳转。目实
JS LocalParticleAbility机制请看官方链接:API 6开始支持
参考:JS LocalParticleAbility机制-概述
通过js 获取到java接口
export default { data: { javaInterface: { } },通讯 onInit() { console.log(TAG + " ;onInit())"); }, onShow() { console.log(TAG + " ;onShow())"); // onInit生命周期中Java接口对象还未创建完成,请勿在onInit中调用。目实 this.javaInterface = createLocalParticleAbility(com.pvj.addresslistdemo.MyLocalParticleAbility); } onClickPhone() { this.javaInterface.doDial(this.item_phone) }, onClickMail() { this.javaInterface.doMessage(this.item_phone) } }java实现
public class MyLocalParticleAbility implements LocalParticleAbility { private static MyLocalParticleAbility instance; Context applicationContext; Context context; private MyLocalParticleAbility(Context context) { this.context = context; this.applicationContext = context.getApplicationContext(); } public static MyLocalParticleAbility getInstance(Context applicationContext) { if (instance == null) { instance = new MyLocalParticleAbility(applicationContext); } return instance; } /** * 跳转系统拨打电话界面 */ public void doDial(String destinationNum) { ... } public void doMessage(String telephone) { .... } }LocalParticleAbility 需要 register与 deregister
public class MainAbility extends AceAbility { @Override public void onStart(Intent intent) { super.onStart(intent); .... MyLocalParticleAbility.getInstance(getContext()).register(this); } @Override public void onStop() { super.onStop(); MyLocalParticleAbility.getInstance(getContext()).deregister(this); } }2.2.3 拨打电话与发送短信
/** * 跳转系统拨打电话界面 */ public void doDial(String destinationNum) { Intent intent = new Intent(); Operation operation = new Intent.OperationBuilder() .withAction(IntentConstants.ACTION_DIAL) // 系统应用拨号盘 .withUri(Uri.parse("tel:" + destinationNum)) // 设置号码 .withFlags(2) .build(); intent.setOperation(operation); // 启动Ability context.startAbility(intent, 10); } //发送短信 public void doMessage(String telephone) { Intent intent = new Intent(); Operation operation = new Intent.OperationBuilder() .withAction(IntentConstants.ACTION_SEND_SMS) .withUri(Uri.parse("smsto:" + telephone)) // 设置号码 .withFlags(Intent.FLAG_NOT_OHOS_COMPONENT) .build(); intent.setOperation(operation); context.startAbility(intent, 11); }2.3 紧急联系人
2.3.1 实现效果

2.3.2 js数据存储
js关系型数据库: 优先用关系型数据库,发现 JS从API Version 7开始支持。
js轻量级存储:
① 它是网站模板key-value的存储的方法,从 API Version 6 开始支持;
参考:数据管理-轻量级存储
② 麻烦的是:每次存数据前,需要取一次,再新增数据;
在实现服务卡片更新信息时,需要动态的更新数据,而java的轻量级存储与JS存储的不是同一目录,目录改成一致程序出错,最终只能采用js与java通信,由java侧统一完成数据新增与插入。
2.3.3 java数据存储实现
java代码:
public class MyLocalParticleAbility implements LocalParticleAbility { private static MyLocalParticleAbility instance; private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG, 0x0, MyLocalParticleAbility.class.getName()); Preferences preferences; public static final String KEY = "key_list"; Context applicationContext; Context context; private MyLocalParticleAbility(Context context) { this.context = context; this.applicationContext = context.getApplicationContext(); DatabaseHelper databaseHelper = new DatabaseHelper(applicationContext); String fileName = "main_list.xml"; // fileName表示文件名,其取值不能为空,也不能包含路径,默认存储目录可以通过context.getPreferencesDir()获取。 preferences = databaseHelper.getPreferences(fileName); } public static MyLocalParticleAbility getInstance(Context applicationContext) { if (instance == null) { instance = new MyLocalParticleAbility(applicationContext); } return instance; } public String getContactPersonList() { // context入参类型为ohos.app.Context。亿华云 String preferencesString = preferences.getString(KEY, ""); HiLog.info(TAG, "getContactPersonList preferencesString : " + preferencesString); return preferencesString; } public void addContactPersonList(String content) { HiLog.info(TAG, "addContactPersonList content : " + content); preferences.putString(KEY, content); preferences.flushSync(); } }js代码:
import prompt from @system.prompt; onItemLongPress(item) { console.log(TAG + " ;onItemLongPress:" + item.item_name); let THIS = this; //点击删除时弹出对话框 prompt.showDialog({ title: "操作提示", message: "添加" + item.item_name + "为紧急联系人吗?", buttons: [{ "text": "确定", "color": "" }, { "text": "取消", "color": "" }], success: function (data) { if (data.index == 0) { THIS.addContactPersonList(item); } } }); } async addContactPersonList(item) { let content = await this.getContactPersonList(); console.info(TAG + "addContactPersonList content: " + content); let list = [] if(content != ""){ list = JSON.parse(content); } list.push(item); let temp = JSON.stringify(list); console.info(TAG + "addContactPersonList temp: " + temp); this.javaInterface.addContactPersonList(temp).then(); return true // store.putSync(key, temp); }, async getContactPersonList() { let ret = await this.javaInterface.getContactPersonList() console.info(TAG + "getContactPersonList ret:" + ret); return ret }2.4 js服务卡片
2.4.1 实现效果
2.4.2 创建卡片模板
2.4.3 卡片数据绑定
public ProviderFormInfo bindFormData(long formId) { HiLog.info(TAG, "bind form data"); ZSONObject zsonObject = new ZSONObject(); String contactPersonList = MyLocalParticleAbility.getInstance(context.getApplicationContext()).getContactPersonList(); JSONArray jsonArray = JSON.parseArray(contactPersonList); for (int i = 0; i < jsonArray.size(); i++) { String name = jsonArray.getJSONObject(i).getString("item_name"); String phone = jsonArray.getJSONObject(i).getString("item_phone"); if (i == 0) { zsonObject.put("titleText", name); zsonObject.put("contentText", phone); } else if (i == 1) { zsonObject.put("titleText1", name); zsonObject.put("contentText1", phone); //传递的是string;是否支持其他类型?比如数组 } else { break; } HiLog.info(TAG, "bind form data :" + jsonArray.getJSONObject(i).get("item_name")); HiLog.info(TAG, "bind form data :" + jsonArray.getJSONObject(i).get("item_phone")); } ProviderFormInfo providerFormInfo = new ProviderFormInfo(); providerFormInfo.setJsBindingData(new FormBindingData(zsonObject)); return providerFormInfo; }2.4.4 事件处理
{ "data": { "appName": "紧急联系人", "contactPersonList": "", "titleText": "Title", "contentText": "Introduction", "titleText1": "", "contentText1": "", "actionName1": "Action 1", "actionName2": "Action 2" }, "actions": { "routerEvent": { "action": "router", "abilityName": "com.pvj.addresslistdemo.MainAbility", "params": { "message": "weather" } }, "callEvent1": { "action": "message", "params": { "mAction": "callEvent1" } }, "callEvent2": { "action": "message", "params": { "mAction": "callEvent2" // } } } }call 就是前面的播打电话的方法
@Override public void onTriggerFormEvent(long formId, String message) { HiLog.info(TAG, "handle card click event." + message); ZSONObject zsonObject = ZSONObject.stringToZSON(message); // Do something here after receive the message from js card ZSONObject result = new ZSONObject(); switch (zsonObject.getString("mAction")) { case "callEvent1": call(0); break; case "callEvent2": call(1); break; } }3 注意事项
Demo还有很多需要完善的地方
删除时,索引不会被删除;
索引想要自定义样式,目前实现不了;
运行在api为7的手机的bug,一开始莫名的#显示;
纯js实现一个应用,目前还是行不通;
js官方文档上,有些不是很完善和稳定,对入门选手极其不友好。
想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com
很赞哦!(51)