当前位置:   article > 正文

『牛角书』鸿蒙简易备忘录_鸿蒙备忘录开发

鸿蒙备忘录开发

前言

鸿蒙移动应用开发作为本学期的一门选修课,让我第一次了解了手机app的开发过程同时也清楚了鸿蒙应用的开发步骤,自己也试着开发了一个简单的鸿蒙app——备忘录。

项目运行

功能介绍

  1. 基本的备忘录功能
  2. 时间截止警告
  3. 搜索功能

项目截图

初始界面
输入备忘录内容以及截止时间界面
选择截止日期
关键字搜索

项目开发

项目创建

1、选择空项目
在这里插入图片描述
2、确认项目名称、存储路径、包名、开发SDK以及语言
在这里插入图片描述
3、完成创建
项目结构

编写程序

1、前端index.html

<div class="container">
    <div class="title-box">
        <text class="title" onclick="onShow"> {{ title }}</text>
        <text class="number"> {{ number }} </text>
    </div>

    <div class="search-box">
        <search onchange="getTodos()" onblur="getTodos()">
        </search>
    </div>

    <div class="text-box">
        <list>
            <list-item for="{{todoList}}" class="todo-item" onlongpress="LongPressToChoose" onclick="ClickToEdit($idx)">
                <div style="width: 10px;">
                    <button if="{{$item.color==3}}" style="height: 100%; width: 100%; background-color: red;"></button>
                    <button if="{{$item.color==2}}" style="height: 100%; width: 100%; background-color: indianred;"></button>
                    <button if="{{$item.color==1}}" style="height: 100%; width: 100%; background-color: blue;"></button>
                    <button if="{{$item.color==0}}" style="height: 100%; width: 100%; background-color: skyblue;"></button>
                </div>
                <div class="div-item">
                    <text class="title-text" > {{$item.title}} </text>

                    <text if="{{$item.ddl}}" class="date-text" > DDL:{{$item.ddl}} </text>
                    <text else class="date-text"> {{$item.date}} </text>

                    <div class="delete-choose">
                        <input type="checkbox" value="{{$idx}}" disabled="{{!choose_delete}}" show="{{choose_delete}}" onchange="ChooseToDelete($idx)">
                        </input>
                    </div>
                </div>

            </list-item>
        </list>
    </div>

    <button class="addButton" type="circle" onclick="AddOrDelete">
        {{add_delete}}
    </button>
</div>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

edit.html

<div class="container">
    <div class="nav-bar">
        <button style="right: 0px;" onclick="ClickToBack"> {{ BACK }} </button>
        <button style="left: 0px;" onclick="InsertTodos"> {{ SAVE }}</button>
    </div>

    <div class="content">
        <textarea class="title" onchange="PassTitle">
            {{title}}
        </textarea>

        <textarea class="text" onchange="PassText">
            {{text}}
        </textarea>
    </div>

    <button class="addButton" type="circle" onclick="AddDdl">
        +
    </button>

    <dialog id="ddl_dialog" class="dialog-main">
        <div class="dialog-div">
            <div class="inner-txt">
                <text class="txt">{{ddl_text}}</text>
                <picker type="date" value="{{ddl}}" onchange="PassDdl"> </picker>
            </div>
            <div class="inner-txt">
                <text class="txt" >{{ddl1_text}}</text>
                <slider class="slide" value="{{ddls[0]}}" onchange="PassDdls(0)"></slider>
            </div>
            <div class="inner-txt">
                <text class="txt">{{ddl2_text}}</text>
                <slider class="slide" value="{{ddls[1]}}" onchange="PassDdls(1)"></slider>
            </div>
            <div class="inner-txt">
                <text class="txt">{{ddl3_text}}</text>
                <slider class="slide" value="{{ddls[2]}}" onchange="PassDdls(2)"></slider>
            </div>
            <div class="inner-btn">
                <button type="capsule" value="{{ CANCEL }}" onclick="CancelDdl" class="btn-txt"></button>
                <button type="capsule" value="{{ CONFIRM }}" onclick="SaveDdl" class="btn-txt"></button>
            </div>
        </div>
    </dialog>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

2、JS端携带的操作请求业务码以及业务数据,业务执行完后,返回响应给JS端。

package com.example.backup;

import ohos.ace.ability.AceInternalAbility;
import ohos.data.distributed.common.*;
import ohos.data.distributed.user.SingleKvStore;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.utils.zson.ZSONObject;

import java.lang.reflect.Array;
import java.util.*;

public class TodoServiceAbility extends AceInternalAbility {
    // 常量
    private static final String BUNDLE_NAME = "com.example.backup";
    private static final String ABILITY_NAME = "com.example.backup.TodoServiceAbility";
    public static final int SUCCESS = 0;
    public static final int ERROR = 1;
    public static final int SELECT_TODOS = 1001;
    public static final int DELETE_TODOS = 1002;
    public static final int UPDATE_TODOS = 1003;
    public static final int INSERT_TODOS = 1004;
    public static final int SELECT_TODO = 1005;
    // 定义日志标签
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "TodoDatabase");
    // TodoServiceAbility 类的一个实例,所以从语义上他只能被初始化一次
    private static TodoServiceAbility instance;
    // Context
    private MainAbility abilityContext;

    /**
     * 如果多个Ability实例都需要注册当前InternalAbility实例,需要更改构造函数,设定自己的bundleName和abilityName
     * 但是在这里我们的InternalAbility只会实例化一次
     */
    public TodoServiceAbility() {
        super(BUNDLE_NAME, ABILITY_NAME);
    }

    /**
     * 关键的接口,JS端携带的操作请求业务码以及业务数据,业务执行完后,返回响应给JS端。开发者需要继承RemoteObject类并重写该方法
     * @param code Js端发送的业务请求编码 PA端定义需要与Js端业务请求码保持一致
     * @param data Js端发送的MessageParcel对象,当前仅支持String格式
     * @param reply 将本地业务响应返回给Js端的MessageParcel对象,当前仅支持String格式
     * @param option 指示操作是同步还是异步的方式,但是我这里只有同步处理方式
     * @return 
     */
    public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
        SingleKvStore db = abilityContext.getSingleKvStore();

        Map<String, String> result = new HashMap<>();
        Map<String, String> ret = new HashMap<>();
        HiLog.debug(LABEL, "onRemoteRequest");

        // 基本思路-解析code-解析data-业务逻辑-构造reply
        switch (code) {
            case DELETE_TODOS: {
                String dataStr = data.readString();
                TodoRequestParam param = new TodoRequestParam();
                try {
                    param = ZSONObject.stringToClass(dataStr, TodoRequestParam.class);
                } catch (RuntimeException e) {
                    HiLog.error(LABEL, "convert failed.");
                }
                try {
                    db.delete(param.id + " title");
                } catch (KvStoreException k){
                    HiLog.debug(LABEL,"no");
                };
                try {
                    db.delete(param.id + " text");
                } catch (KvStoreException k){
                    HiLog.debug(LABEL,"no");
                };
                try {
                    db.delete(param.id + " date");
                } catch (KvStoreException k){
                    HiLog.debug(LABEL,"no");
                };
                try {
                    db.delete(param.id + " ddl");
                } catch (KvStoreException k){
                    HiLog.debug(LABEL,"no");
                };
                HiLog.debug(LABEL, "insert or update success");
                break;
            }
            case UPDATE_TODOS:
            case INSERT_TODOS:{
                String dataStr = data.readString();
                TodoRequestParam param = new TodoRequestParam();
                try {
                    param = ZSONObject.stringToClass(dataStr, TodoRequestParam.class);
                } catch (RuntimeException e) {
                    HiLog.error(LABEL, "convert failed.");
                }
                if (param.title!=null) db.putString(param.id+" title",param.title);
                if (param.date!=null) db.putString(param.id+" date",param.date);
                if (param.text!=null) db.putString(param.id+" text",param.text);
                if (param.ddl!=null) db.putString(param.id+" ddl",param.ddl);
                HiLog.debug(LABEL, "insert or update success");
                break;
            }
            case SELECT_TODOS:{
                // 返回结果当前仅支持String,对于复杂结构可以序列化为ZSON字符串上报
                HiLog.debug(LABEL, "Database Return All Result");
                String condition = data.readString();
                HiLog.debug(LABEL, "condition="+condition);
                Set<String> indexes = new HashSet<>();
                for (Entry i: db.getEntries("")){
                    indexes.add(i.getKey().split(" ")[0]);
                }

                for (String i: indexes){
                    String title,date,ddl;
                    try {
                        title = db.getString(i+" title");
                        if (title.contains(condition))
                            result.put("title",title);
                        else
                            continue;
                    }
                    catch (KvStoreException k){
                        title = "";
                    };
                    try {
                        date = db.getString(i+" date");
                        result.put("date",date);
                    }
                    catch (KvStoreException k){
                        date = "";
                    };
                    try {
                        ddl = db.getString(i+" ddl");
                        result.put("ddl",ddl);
                    }
                    catch (KvStoreException k){
                        ddl = "";
                    };
//                    HiLog.debug(LABEL, String.valueOf(result));
                    String rString = ZSONObject.toZSONString(result);
                    ret.put(i,rString);
                }
                reply.writeString(ZSONObject.toZSONString(ret));
                HiLog.debug(LABEL, "select all success");
                break;
            }
            case SELECT_TODO: {
                String dataStr = data.readString();
                TodoRequestParam param = new TodoRequestParam();
                try {
                    param = ZSONObject.stringToClass(dataStr, TodoRequestParam.class);
                } catch (RuntimeException e) {
                    HiLog.error(LABEL, "convert failed.");
                }
                String r;
                try {
                    r = db.getString(param.id+" text");
                } catch (KvStoreException k) {
                    r = "";
                }
                reply.writeString(r);
                HiLog.debug(LABEL, "select one text success");
                break;
            }
            default: {
                HiLog.debug(LABEL, "unknown code");
                return false;
            }
        };
        // 分布式数据库的同步
        abilityContext.syncContact();
        return true;
    }

    /**
     * Internal ability 注册接口
     */
    public static void register(MainAbility abilityContext) {
        instance = new TodoServiceAbility();
        instance.onRegister(abilityContext);
    }

    private void onRegister(MainAbility abilityContext) {
        this.abilityContext = abilityContext;
        this.setInternalAbilityHandler(this::onRemoteRequest);
        HiLog.info(LABEL, "jgq TodoServiceAbility onRegister");
    }

    /**
     * Internal ability 注销接口。
     */
    public static void unregister() {
        instance.onUnregister();
    }

    private void onUnregister() {
        abilityContext = null;
        this.setInternalAbilityHandler(null);
        HiLog.info(LABEL, "jgq TodoServiceAbility onUnregister");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203

3、系统主程序

package com.example.backup;

import ohos.aafwk.ability.IAbilityContinuation;
import ohos.ace.ability.AceAbility;
import ohos.aafwk.content.Intent;
import ohos.app.Context;
import ohos.data.DatabaseHelper;
import ohos.data.distributed.common.*;
import ohos.data.distributed.device.DeviceFilterStrategy;
import ohos.data.distributed.device.DeviceInfo;
import ohos.data.distributed.user.SingleKvStore;
import ohos.data.preferences.Preferences;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MainAbility extends AceAbility implements IAbilityContinuation {
//    static public Preferences preferences;
    static public String storeID = "TodoDistributeDatabase";
    private SingleKvStore singleKvStore;
    private KvManager kvManager;
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MainAbility");

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        HiLog.info(LABEL,"jgq onStart");

        // 开发者显示声明需要使用的权限
        requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
        Context context = this.getContext();
//        DatabaseHelper databaseHelper = new DatabaseHelper(context);
//        String filename = "todoDB";
//        preferences = databaseHelper.getPreferences(filename);

        // 需要注册
        TodoServiceAbility.register(this);
        // 分布式数据库,不知道是不是写在这里,注册
        KvManagerConfig config = new KvManagerConfig(context);
        kvManager = KvManagerFactory.getInstance().createKvManager(config);
        // 创建数据库
        Options CREATE = new Options();
        CREATE.setCreateIfMissing(true).setEncrypt(false).setKvStoreType(KvStoreType.SINGLE_VERSION);
        singleKvStore = kvManager.getKvStore(CREATE, storeID);
        // 订阅
        KvStoreObserver kvStoreObserverClient = new KvStoreObserverClient();
        singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, kvStoreObserverClient);
    }

    public SingleKvStore getSingleKvStore() {
        return singleKvStore;
    }

    @Override
    public void onStop() {
        // 取消注册
        HiLog.info(LABEL,"jgq onStop");
        TodoServiceAbility.unregister();
        super.onStop();
    }

    public void syncContact() {
        List<DeviceInfo> deviceInfoList = kvManager.getConnectedDevicesInfo(DeviceFilterStrategy.NO_FILTER);
        List<String> deviceIdList = new ArrayList<>();
        for (DeviceInfo deviceInfo : deviceInfoList) {
            deviceIdList.add(deviceInfo.getId());
        }

        if (deviceIdList.size() == 0) {
//            showTip("组网失败");
            HiLog.info(LABEL,"同步失败");
            return;
        }
        singleKvStore.registerSyncCallback(new SyncCallback() {
            @Override
            public void syncCompleted(Map<String, Integer> map) {
                getUITaskDispatcher().asyncDispatch(new Runnable() {
                    @Override
                    public void run() {
//                        queryContact();
//                        showTip("同步成功");
                        HiLog.info(LABEL,"同步成功");
                    }
                });
                singleKvStore.unRegisterSyncCallback();
            }
        });
        singleKvStore.sync(deviceIdList, SyncMode.PUSH_PULL);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/231895?site
推荐阅读
  

闽ICP备14008679号