HarmonyOS 项目实战之通讯录Demo(JS)

时间:2022-04-24 02:28:06

HarmonyOS 项目实战之通讯录Demo(JS)

1 简介

通讯录demo主要分为联系人界面、设置紧急联系人、服务卡片3个模块,分为Java和JS两个版本,本篇主要讲解用尽可能的用纯JS去实现,实在无法实现的地方采用JS与Java结合。

1.1 原型

感兴趣的小伙伴,可以自己根据原型效果自己尝试着去实现【通讯录demo简易原型】。

HarmonyOS 项目实战之通讯录Demo(JS)HarmonyOS 项目实战之通讯录Demo(JS)HarmonyOS 项目实战之通讯录Demo(JS)

1.2 场景延伸

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

HarmonyOS 项目实战之通讯录Demo(JS)HarmonyOS 项目实战之通讯录Demo(JS)HarmonyOS 项目实战之通讯录Demo(JS)

2 功能开发

2.1 联系人列表

2.1.1 实现效果

HarmonyOS 项目实战之通讯录Demo(JS)

2.1.2 核心代码

参考:基于JS扩展的类Web开发范式-组件-容器组件-list

关键属性 indexer=“true”

  1. -- list -->
  2. "address_list" class="list-wrapper" indexer="true" indexerbubble="true" shapemode="rect"
  3. initialindex="0">
  4. for="{{ list_data }}">
  5. section="{{ $item.item_section }}" class="todo-item">
  6. "item-wrapper" @click="onItemClick($item)" @longpress="onItemLongPress($item)">
  7. HarmonyOS 项目实战之通讯录Demo(JS)"item-icon" src="{{ $item.item_icon }}">/>
  8. "item-name">{{ $item.item_name }}

2.2 三方跳转

2.2.1 实现效果

HarmonyOS 项目实战之通讯录Demo(JS)

2.2.2 js和java通信

js打开三方应用目前还不知道如何操作,我们通过js调java方法来实现跳转。

JS LocalParticleAbility机制请看官方链接:API 6开始支持

参考:JS LocalParticleAbility机制-概述

通过js 获取到java接口

  1. export default {
  2. data: {
  3. javaInterface: {}
  4. },
  5. onInit() {
  6. console.log(TAG + " ;onInit())");
  7. },
  8. onShow() {
  9. console.log(TAG + " ;onShow())");
  10. // onInit生命周期中Java接口对象还未创建完成,请勿在onInit中调用。
  11. this.javaInterface = createLocalParticleAbility('com.pvj.addresslistdemo.MyLocalParticleAbility');
  12. }
  13. onClickPhone() {
  14. this.javaInterface.doDial(this.item_phone)
  15. },
  16. onClickMail() {
  17. this.javaInterface.doMessage(this.item_phone)
  18. }
  19. }

java实现

  1. public class MyLocalParticleAbility implements LocalParticleAbility {
  2. private static MyLocalParticleAbility instance;
  3. Context applicationContext;
  4. Context context;
  5. private MyLocalParticleAbility(Context context) {
  6. this.context = context;
  7. this.applicationContext = context.getApplicationContext();
  8. }
  9. public static MyLocalParticleAbility getInstance(Context applicationContext) {
  10. if (instance == null) {
  11. instance = new MyLocalParticleAbility(applicationContext);
  12. }
  13. return instance;
  14. }
  15. /**
  16. * 跳转系统拨打电话界面
  17. */
  18. public void doDial(String destinationNum) {
  19. ...
  20. }
  21. public void doMessage(String telephone) {
  22. ....
  23. }
  24. }

LocalParticleAbility 需要 register与 deregister

  1. public class MainAbility extends AceAbility {
  2. @Override
  3. public void onStart(Intent intent) {
  4. super.onStart(intent);
  5. ....
  6. MyLocalParticleAbility.getInstance(getContext()).register(this);
  7. }
  8. @Override
  9. public void onStop() {
  10. super.onStop();
  11. MyLocalParticleAbility.getInstance(getContext()).deregister(this);
  12. }
  13. }

2.2.3 拨打电话与发送短信

  1. /**
  2. * 跳转系统拨打电话界面
  3. */
  4. public void doDial(String destinationNum) {
  5. Intent intent = new Intent();
  6. Operation operation = new Intent.OperationBuilder()
  7. .withAction(IntentConstants.ACTION_DIAL) // 系统应用拨号盘
  8. .withUri(Uri.parse("tel:" + destinationNum)) // 设置号码
  9. .withFlags(2)
  10. .build();
  11. intent.setOperation(operation);
  12. // 启动Ability
  13. context.startAbility(intent, 10);
  14. }
  15. //发送短信
  16. public void doMessage(String telephone) {
  17. Intent intent = new Intent();
  18. Operation operation = new Intent.OperationBuilder()
  19. .withAction(IntentConstants.ACTION_SEND_SMS)
  20. .withUri(Uri.parse("smsto:" + telephone)) // 设置号码
  21. .withFlags(Intent.FLAG_NOT_OHOS_COMPONENT)
  22. .build();
  23. intent.setOperation(operation);
  24. context.startAbility(intent, 11);
  25. }

2.3 紧急联系人

2.3.1 实现效果

HarmonyOS 项目实战之通讯录Demo(JS)

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代码:

  1. public class MyLocalParticleAbility implements LocalParticleAbility {
  2. private static MyLocalParticleAbility instance;
  3. private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG, 0x0, MyLocalParticleAbility.class.getName());
  4. Preferences preferences;
  5. public static final String KEY = "key_list";
  6. Context applicationContext;
  7. Context context;
  8. private MyLocalParticleAbility(Context context) {
  9. this.context = context;
  10. this.applicationContext = context.getApplicationContext();
  11. DatabaseHelper databaseHelper = new DatabaseHelper(applicationContext);
  12. String fileName = "main_list.xml";
  13. // fileName表示文件名,其取值不能为空,也不能包含路径,默认存储目录可以通过context.getPreferencesDir()获取。
  14. preferences = databaseHelper.getPreferences(fileName);
  15. }
  16. public static MyLocalParticleAbility getInstance(Context applicationContext) {
  17. if (instance == null) {
  18. instance = new MyLocalParticleAbility(applicationContext);
  19. }
  20. return instance;
  21. }
  22. public String getContactPersonList() {
  23. // context入参类型为ohos.app.Context。
  24. String preferencesString = preferences.getString(KEY, "");
  25. HiLog.info(TAG, "getContactPersonList preferencesString : " + preferencesString);
  26. return preferencesString;
  27. }
  28. public void addContactPersonList(String content) {
  29. HiLog.info(TAG, "addContactPersonList content : " + content);
  30. preferences.putString(KEY, content);
  31. preferences.flushSync();
  32. }
  33. }

js代码:

  1. import prompt from '@system.prompt';
  2. onItemLongPress(item) {
  3. console.log(TAG + " ;onItemLongPress:" + item.item_name);
  4. let THIS = this;
  5. //点击删除时弹出对话框
  6. prompt.showDialog({
  7. title: "操作提示",
  8. message: "添加" + item.item_name + "为紧急联系人吗?",
  9. buttons: [{
  10. "text": "确定",
  11. "color": ""
  12. },
  13. {
  14. "text": "取消",
  15. "color": ""
  16. }],
  17. success: function (data) {
  18. if (data.index == 0) {
  19. THIS.addContactPersonList(item);
  20. }
  21. }
  22. });
  23. }
  24. async addContactPersonList(item) {
  25. let content = await this.getContactPersonList();
  26. console.info(TAG + "addContactPersonList content: " + content);
  27. let list = []
  28. if(content != ""){
  29. list = JSON.parse(content);
  30. }
  31. list.push(item);
  32. let temp = JSON.stringify(list);
  33. console.info(TAG + "addContactPersonList temp: " + temp);
  34. this.javaInterface.addContactPersonList(temp).then();
  35. return true
  36. // store.putSync(key, temp);
  37. },
  38. async getContactPersonList() {
  39. let ret = await this.javaInterface.getContactPersonList()
  40. console.info(TAG + "getContactPersonList ret:" + ret);
  41. return ret
  42. }

2.4 js服务卡片

2.4.1 实现效果

HarmonyOS 项目实战之通讯录Demo(JS)

2.4.2 创建卡片模板

HarmonyOS 项目实战之通讯录Demo(JS)

2.4.3 卡片数据绑定

  1. public ProviderFormInfo bindFormData(long formId) {
  2. HiLog.info(TAG, "bind form data");
  3. ZSONObject zsonObject = new ZSONObject();
  4. String contactPersonList = MyLocalParticleAbility.getInstance(context.getApplicationContext()).getContactPersonList();
  5. JSONArray jsonArray = JSON.parseArray(contactPersonList);
  6. for (int i = 0; i < jsonArray.size(); i++) {
  7. String name = jsonArray.getJSONObject(i).getString("item_name");
  8. String phone = jsonArray.getJSONObject(i).getString("item_phone");
  9. if (i == 0) {
  10. zsonObject.put("titleText", name);
  11. zsonObject.put("contentText", phone);
  12. } else if (i == 1) {
  13. zsonObject.put("titleText1", name);
  14. zsonObject.put("contentText1", phone); //传递的是string;是否支持其他类型?比如数组
  15. } else {
  16. break;
  17. }
  18. HiLog.info(TAG, "bind form data :" + jsonArray.getJSONObject(i).get("item_name"));
  19. HiLog.info(TAG, "bind form data :" + jsonArray.getJSONObject(i).get("item_phone"));
  20. }
  21. ProviderFormInfo providerFormInfo = new ProviderFormInfo();
  22. providerFormInfo.setJsBindingData(new FormBindingData(zsonObject));
  23. return providerFormInfo;
  24. }

2.4.4 事件处理

  1. {
  2. "data": {
  3. "appName": "紧急联系人",
  4. "contactPersonList": "",
  5. "titleText": "Title",
  6. "contentText": "Introduction",
  7. "titleText1": "",
  8. "contentText1": "",
  9. "actionName1": "Action 1",
  10. "actionName2": "Action 2"
  11. },
  12. "actions": {
  13. "routerEvent": {
  14. "action": "router",
  15. "abilityName": "com.pvj.addresslistdemo.MainAbility",
  16. "params": {
  17. "message": "weather"
  18. }
  19. },
  20. "callEvent1": {
  21. "action": "message",
  22. "params": {
  23. "mAction": "callEvent1"
  24. }
  25. },
  26. "callEvent2": {
  27. "action": "message",
  28. "params": {
  29. "mAction": "callEvent2" //
  30. }
  31. }
  32. }
  33. }

call 就是前面的播打电话的方法

  1. @Override
  2. public void onTriggerFormEvent(long formId, String message) {
  3. HiLog.info(TAG, "handle card click event." + message);
  4. ZSONObject zsonObject = ZSONObject.stringToZSON(message);
  5. // Do something here after receive the message from js card
  6. ZSONObject result = new ZSONObject();
  7. switch (zsonObject.getString("mAction")) {
  8. case "callEvent1":
  9. call(0);
  10. break;
  11. case "callEvent2":
  12. call(1);
  13. break;
  14. }
  15. }

3 注意事项

Demo还有很多需要完善的地方

删除时,索引不会被删除;

HarmonyOS 项目实战之通讯录Demo(JS)

索引想要自定义样式,目前实现不了;

运行在api为7的手机的bug,一开始莫名的#显示;

HarmonyOS 项目实战之通讯录Demo(JS)

纯js实现一个应用,目前还是行不通;

js官方文档上,有些不是很完善和稳定,对入门选手极其不友好。

原文链接:https://harmonyos.51cto.com