#星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS) 原创 精华

中软国际AIoT开发者社区
发布于 2021-12-8 09:16
浏览
6收藏

作者:彭为杰
【本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0】

1 简介

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

1.1 原型

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

#星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区 #星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区 #星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

1.2 场景延伸

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

#星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区 #星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区 #星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

2 功能开发

2.1 联系人列表

2.1.1 实现效果

#星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

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.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

2.2.2 js和java通信

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

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 需要 registerderegister

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.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

2.3.2 js数据存储

js关系型数据库: 优先用关系型数据库,发现 JSAPI Version 7开始支持。

js轻量级存储:

① 它是key-value的存储的方法,从 API Version 6 开始支持;
参考:数据管理-轻量级存储
② 麻烦的是:每次存数据前,需要取一次,再新增数据;

在实现服务卡片更新信息时,需要动态的更新数据,而java的轻量级存储与JS存储的不是同一目录,目录改成一致程序出错,最终只能采用jsjava通信,由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.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

2.4.2 创建卡片模板

#星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

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还有很多需要完善的地方

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

#星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

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

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

#星光计划2.0# HarmonyOS 项目实战之通讯录Demo(JS)-鸿蒙开发者社区

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

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

4 总结

有不对或者更优的处理技术方案请多多指教,共同学习,共同进步。

代码地址: https://gitee.com/guangdong-wangduoyu/addresslistdemo

更多原创内容请关注:开鸿 HarmonyOS 学院

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2021-12-8 14:18:53修改
6
收藏 6
回复
举报
2条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

开鸿老师对鸿蒙的热情还是一如既往的高,感谢老师分享

1
回复
2021-12-8 10:28:42
中软国际AIoT开发者社区
中软国际AIoT开发者社区 回复了 红叶亦知秋
开鸿老师对鸿蒙的热情还是一如既往的高,感谢老师分享

哈哈哈,还有更多的内容,感谢关注。

回复
2021-12-8 14:11:38
回复
    相关推荐