From 14c079710edac1dd415e7219fe74ace1039d82e2 Mon Sep 17 00:00:00 2001 From: zhangqing <1770666340@qq.com> Date: Wed, 24 Dec 2025 00:05:31 +0800 Subject: [PATCH] 1 --- .../net/micode/notes/gtask/data/MetaData.java | 92 +--- .../src/net/micode/notes/gtask/data/Node.java | 117 +--- .../net/micode/notes/gtask/data/SqlData.java | 231 +++----- .../net/micode/notes/gtask/data/SqlNote.java | 519 +++++++----------- .../src/net/micode/notes/gtask/data/Task.java | 271 ++++----- .../net/micode/notes/gtask/data/TaskList.java | 335 ++++------- 6 files changed, 558 insertions(+), 1007 deletions(-) diff --git a/src/小米标签代码/src/net/micode/notes/gtask/data/MetaData.java b/src/小米标签代码/src/net/micode/notes/gtask/data/MetaData.java index 24a28b1..3460d42 100644 --- a/src/小米标签代码/src/net/micode/notes/gtask/data/MetaData.java +++ b/src/小米标签代码/src/net/micode/notes/gtask/data/MetaData.java @@ -24,105 +24,65 @@ import net.micode.notes.tool.GTaskStringUtils; import org.json.JSONException; import org.json.JSONObject; -/** - * MetaData类 - * 元数据任务,用于存储与Google Task相关的元信息 - * 继承自Task类,但仅用于存储元数据,不直接显示给用户 - */ -public class MetaData extends Task { - // 日志标签 - private final static String TAG = MetaData.class.getSimpleName(); - // 关联的Google Task ID - private String mRelatedGid = null; +public class MetaData extends Task { // 元数据类,继承自Task + private final static String TAG = MetaData.class.getSimpleName(); // 日志标签 + + private String mRelatedGid = null; // 关联的Google任务ID - /** - * 设置元数据 - * 将Google Task ID和元信息存储在笔记内容中 - * @param gid Google Task ID - * @param metaInfo 元信息JSON对象 - */ + // 设置元数据 public void setMeta(String gid, JSONObject metaInfo) { try { - // 将Google Task ID添加到元信息中 - metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); + metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); // 在元数据中添加Google任务ID } catch (JSONException e) { - Log.e(TAG, "failed to put related gid"); + Log.e(TAG, "failed to put related gid"); // 添加失败 } - // 将元信息JSON字符串设置为笔记内容 - setNotes(metaInfo.toString()); - // 设置任务名称为元数据笔记的特定名称 - setName(GTaskStringUtils.META_NOTE_NAME); + setNotes(metaInfo.toString()); // 将元数据JSON字符串设为备注 + setName(GTaskStringUtils.META_NOTE_NAME); // 设置名称为元数据笔记名称 } - /** - * 获取关联的Google Task ID - * @return Google Task ID - */ + // 获取关联的Google任务ID public String getRelatedGid() { return mRelatedGid; } - /** - * 检查是否值得保存 - * 只有当笔记内容不为空时才值得保存 - * @return 是否值得保存 - */ + // 重写:检查是否值得保存(只要有备注就值得保存) @Override public boolean isWorthSaving() { - return getNotes() != null; + return getNotes() != null; // 只要有备注就值得保存 } - /** - * 从远程JSON设置内容 - * 解析远程JSON数据,提取关联的Google Task ID - * @param js 远程JSON对象 - */ + // 重写:从远程JSON设置内容 @Override public void setContentByRemoteJSON(JSONObject js) { - super.setContentByRemoteJSON(js); // 调用父类方法设置基础内容 - if (getNotes() != null) { + super.setContentByRemoteJSON(js); // 调用父类方法 + if (getNotes() != null) { // 如果有备注 try { - // 从笔记内容中解析元信息JSON - JSONObject metaInfo = new JSONObject(getNotes().trim()); - // 提取关联的Google Task ID - mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); + JSONObject metaInfo = new JSONObject(getNotes().trim()); // 解析备注为JSON + mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); // 获取关联的Google任务ID } catch (JSONException e) { - Log.w(TAG, "failed to get related gid"); - mRelatedGid = null; // 解析失败时设置为null + Log.w(TAG, "failed to get related gid"); // 获取失败 + mRelatedGid = null; // 设为null } } } - /** - * 从本地JSON设置内容 - * MetaData不应通过本地JSON设置内容,因此抛出异常 - * @param js 本地JSON对象 - */ + // 重写:从本地JSON设置内容(不应该被调用) @Override public void setContentByLocalJSON(JSONObject js) { - // 此函数不应被调用,因为MetaData不应从本地JSON加载 - throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); + // 这个函数不应该被调用 + throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); // 抛出异常 } - /** - * 从内容获取本地JSON - * MetaData不应生成本地JSON,因此抛出异常 - * @return 本地JSON对象 - */ + // 重写:从内容生成本地JSON(不应该被调用) @Override public JSONObject getLocalJSONFromContent() { - throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); + throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); // 抛出异常 } - /** - * 获取同步动作 - * MetaData不应进行同步操作,因此抛出异常 - * @param c 数据库游标 - * @return 同步动作类型 - */ + // 重写:获取同步操作(不应该被调用) @Override public int getSyncAction(Cursor c) { - throw new IllegalAccessError("MetaData:getSyncAction should not be called"); + throw new IllegalAccessError("MetaData:getSyncAction should not be called"); // 抛出异常 } } \ No newline at end of file diff --git a/src/小米标签代码/src/net/micode/notes/gtask/data/Node.java b/src/小米标签代码/src/net/micode/notes/gtask/data/Node.java index fc741d0..bea3a0a 100644 --- a/src/小米标签代码/src/net/micode/notes/gtask/data/Node.java +++ b/src/小米标签代码/src/net/micode/notes/gtask/data/Node.java @@ -20,13 +20,8 @@ import android.database.Cursor; import org.json.JSONObject; -/** - * Node抽象类 - * 所有同步节点(任务、任务列表等)的基类 - * 定义了同步节点的基本属性和方法 - */ -public abstract class Node { - // 同步动作常量定义 +public abstract class Node { // 抽象节点类,所有数据节点的基类 + // 同步操作类型常量 public static final int SYNC_ACTION_NONE = 0; // 无需同步 public static final int SYNC_ACTION_ADD_REMOTE = 1; // 添加到远程 public static final int SYNC_ACTION_ADD_LOCAL = 2; // 添加到本地 @@ -34,134 +29,76 @@ public abstract class Node { public static final int SYNC_ACTION_DEL_LOCAL = 4; // 从本地删除 public static final int SYNC_ACTION_UPDATE_REMOTE = 5; // 更新远程 public static final int SYNC_ACTION_UPDATE_LOCAL = 6; // 更新本地 - public static final int SYNC_ACTION_UPDATE_CONFLICT = 7; // 更新冲突 + public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;// 更新冲突 public static final int SYNC_ACTION_ERROR = 8; // 同步错误 - // Google Task ID - private String mGid; - // 节点名称 - private String mName; - // 最后修改时间戳 - private long mLastModified; - // 是否已删除 - private boolean mDeleted; - - /** - * 构造函数 - * 初始化节点的默认值 - */ + private String mGid; // Google任务ID + private String mName; // 节点名称 + private long mLastModified; // 最后修改时间 + private boolean mDeleted; // 删除标记 + + // 构造函数 public Node() { - mGid = null; // Google Task ID初始为null - mName = ""; // 名称初始为空字符串 - mLastModified = 0; // 最后修改时间初始为0 - mDeleted = false; // 删除标志初始为false + mGid = null; // Google任务ID为空 + mName = ""; // 名称为空字符串 + mLastModified = 0; // 最后修改时间为0 + mDeleted = false; // 未删除 } - /** - * 获取创建动作的JSON对象 - * 抽象方法,由子类实现 - * @param actionId 动作ID - * @return 创建动作的JSON对象 - */ + // 抽象方法:获取创建操作的JSON对象 public abstract JSONObject getCreateAction(int actionId); - /** - * 获取更新动作的JSON对象 - * 抽象方法,由子类实现 - * @param actionId 动作ID - * @return 更新动作的JSON对象 - */ + // 抽象方法:获取更新操作的JSON对象 public abstract JSONObject getUpdateAction(int actionId); - /** - * 从远程JSON设置内容 - * 抽象方法,由子类实现 - * @param js 远程JSON对象 - */ + // 抽象方法:从远程JSON设置内容 public abstract void setContentByRemoteJSON(JSONObject js); - /** - * 从本地JSON设置内容 - * 抽象方法,由子类实现 - * @param js 本地JSON对象 - */ + // 抽象方法:从本地JSON设置内容 public abstract void setContentByLocalJSON(JSONObject js); - /** - * 从内容获取本地JSON - * 抽象方法,由子类实现 - * @return 本地JSON对象 - */ + // 抽象方法:从内容生成本地JSON public abstract JSONObject getLocalJSONFromContent(); - /** - * 获取同步动作 - * 抽象方法,由子类实现 - * @param c 数据库游标 - * @return 同步动作类型 - */ + // 抽象方法:根据游标获取同步操作类型 public abstract int getSyncAction(Cursor c); - /** - * 设置Google Task ID - * @param gid Google Task ID - */ + // 设置Google任务ID public void setGid(String gid) { this.mGid = gid; } - /** - * 设置节点名称 - * @param name 节点名称 - */ + // 设置节点名称 public void setName(String name) { this.mName = name; } - /** - * 设置最后修改时间 - * @param lastModified 最后修改时间戳 - */ + // 设置最后修改时间 public void setLastModified(long lastModified) { this.mLastModified = lastModified; } - /** - * 设置删除标志 - * @param deleted 是否已删除 - */ + // 设置删除标记 public void setDeleted(boolean deleted) { this.mDeleted = deleted; } - /** - * 获取Google Task ID - * @return Google Task ID - */ + // 获取Google任务ID public String getGid() { return this.mGid; } - /** - * 获取节点名称 - * @return 节点名称 - */ + // 获取节点名称 public String getName() { return this.mName; } - /** - * 获取最后修改时间 - * @return 最后修改时间戳 - */ + // 获取最后修改时间 public long getLastModified() { return this.mLastModified; } - /** - * 获取删除标志 - * @return 是否已删除 - */ + // 获取删除标记 public boolean getDeleted() { return this.mDeleted; } diff --git a/src/小米标签代码/src/net/micode/notes/gtask/data/SqlData.java b/src/小米标签代码/src/net/micode/notes/gtask/data/SqlData.java index 904f1e0..5844ec6 100644 --- a/src/小米标签代码/src/net/micode/notes/gtask/data/SqlData.java +++ b/src/小米标签代码/src/net/micode/notes/gtask/data/SqlData.java @@ -34,200 +34,135 @@ import net.micode.notes.gtask.exception.ActionFailureException; import org.json.JSONException; import org.json.JSONObject; -/** - * SqlData类 - * 用于表示数据库中的一条数据记录,负责在SQLite数据库和JSON对象之间进行数据转换 - * 主要处理笔记内容、通话记录等数据 - */ + public class SqlData { - // 日志标签 - private static final String TAG = SqlData.class.getSimpleName(); + private static final String TAG = SqlData.class.getSimpleName(); // 日志标签,使用类名 - // 无效ID常量 - private static final int INVALID_ID = -99999; + private static final int INVALID_ID = -99999; // 无效ID标识 - /** - * 数据查询投影列 - * 定义从数据库查询数据时需要返回的列 - */ + // 查询数据库时使用的列投影(需要查询的列) public static final String[] PROJECTION_DATA = new String[] { - DataColumns.ID, // 数据ID - DataColumns.MIME_TYPE, // MIME类型 - DataColumns.CONTENT, // 内容 - DataColumns.DATA1, // 数据列1 - DataColumns.DATA3 // 数据列3 + DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, + DataColumns.DATA3 }; - // 数据ID列索引 - public static final int DATA_ID_COLUMN = 0; - // MIME类型列索引 - public static final int DATA_MIME_TYPE_COLUMN = 1; - // 内容列索引 - public static final int DATA_CONTENT_COLUMN = 2; - // 数据列1索引 - public static final int DATA_CONTENT_DATA_1_COLUMN = 3; - // 数据列3索引 - public static final int DATA_CONTENT_DATA_3_COLUMN = 4; - - // 内容解析器,用于访问ContentProvider - private ContentResolver mContentResolver; - - // 是否为新建数据记录 - private boolean mIsCreate; - - // 数据ID - private long mDataId; - - // MIME类型 - private String mDataMimeType; - - // 内容 - private String mDataContent; - - // 数据列1的值 - private long mDataContentData1; - - // 数据列3的值 - private String mDataContentData3; - - // 存储有变动的数据值的ContentValues对象 - private ContentValues mDiffDataValues; - - /** - * 构造函数 - 用于创建新数据记录 - * @param context 上下文对象 - */ + public static final int DATA_ID_COLUMN = 0; // ID列在游标中的索引 + public static final int DATA_MIME_TYPE_COLUMN = 1; // MIME类型列索引 + public static final int DATA_CONTENT_COLUMN = 2; // 内容列索引 + public static final int DATA_CONTENT_DATA_1_COLUMN = 3; // DATA1列索引 + public static final int DATA_CONTENT_DATA_3_COLUMN = 4; // DATA3列索引 + + private ContentResolver mContentResolver; // 内容解析器,用于数据库操作 + private boolean mIsCreate; // 是否为新建数据记录 + private long mDataId; // 数据记录ID + private String mDataMimeType; // MIME类型 + private String mDataContent; // 数据内容 + private long mDataContentData1; // 数据字段1(长整型) + private String mDataContentData3; // 数据字段3(字符串) + private ContentValues mDiffDataValues; // 存储需要更新的字段差异值 + + // 构造函数:创建新的SqlData对象(未存入数据库) public SqlData(Context context) { - mContentResolver = context.getContentResolver(); - mIsCreate = true; // 标记为新记录 - mDataId = INVALID_ID; // 初始化为无效ID - mDataMimeType = DataConstants.NOTE; // 默认MIME类型为笔记 - mDataContent = ""; // 内容初始化为空字符串 - mDataContentData1 = 0; // 数据列1初始化为0 - mDataContentData3 = ""; // 数据列3初始化为空字符串 - mDiffDataValues = new ContentValues(); // 初始化差异值容器 + mContentResolver = context.getContentResolver(); // 获取内容解析器 + mIsCreate = true; // 标记为新创建 + mDataId = INVALID_ID; // 初始化为无效ID + mDataMimeType = DataConstants.NOTE; // 默认MIME类型为笔记 + mDataContent = ""; // 内容初始化为空 + mDataContentData1 = 0; // 数据字段1初始化为0 + mDataContentData3 = ""; // 数据字段3初始化为空 + mDiffDataValues = new ContentValues(); // 初始化差异值容器 } - /** - * 构造函数 - 从数据库游标加载现有数据记录 - * @param context 上下文对象 - * @param c 数据库游标 - */ + // 构造函数:从数据库游标创建SqlData对象 public SqlData(Context context, Cursor c) { - mContentResolver = context.getContentResolver(); - mIsCreate = false; // 标记为现有记录 - loadFromCursor(c); // 从游标加载数据 - mDiffDataValues = new ContentValues(); // 初始化差异值容器 + mContentResolver = context.getContentResolver(); // 获取内容解析器 + mIsCreate = false; // 标记为已存在数据库 + loadFromCursor(c); // 从游标加载数据 + mDiffDataValues = new ContentValues(); // 初始化差异值容器 } - /** - * 从数据库游标加载数据 - * @param c 数据库游标 - */ + // 从数据库游标加载数据到对象字段 private void loadFromCursor(Cursor c) { - mDataId = c.getLong(DATA_ID_COLUMN); // 加载数据ID - mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); // 加载MIME类型 - mDataContent = c.getString(DATA_CONTENT_COLUMN); // 加载内容 - mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); // 加载数据列1 - mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); // 加载数据列3 + mDataId = c.getLong(DATA_ID_COLUMN); // 获取ID + mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); // 获取MIME类型 + mDataContent = c.getString(DATA_CONTENT_COLUMN); // 获取内容 + mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); // 获取DATA1 + mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); // 获取DATA3 } - /** - * 从JSON对象设置数据内容 - * 比较JSON中的值与当前值,记录有变化的字段 - * @param js JSON对象,包含数据内容 - * @throws JSONException JSON解析异常 - */ + // 从JSON对象设置数据内容,并记录差异值 public void setContent(JSONObject js) throws JSONException { - // 处理数据ID long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; - if (mIsCreate || mDataId != dataId) { - mDiffDataValues.put(DataColumns.ID, dataId); // 记录变化 + if (mIsCreate || mDataId != dataId) { // 如果是新建或ID不同 + mDiffDataValues.put(DataColumns.ID, dataId); // 记录ID差异 } - mDataId = dataId; // 更新当前值 + mDataId = dataId; // 更新当前ID - // 处理MIME类型 String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE) : DataConstants.NOTE; - if (mIsCreate || !mDataMimeType.equals(dataMimeType)) { - mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); // 记录变化 + if (mIsCreate || !mDataMimeType.equals(dataMimeType)) { // 如果是新建或MIME类型不同 + mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); // 记录MIME类型差异 } - mDataMimeType = dataMimeType; // 更新当前值 + mDataMimeType = dataMimeType; // 更新MIME类型 - // 处理内容 String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : ""; - if (mIsCreate || !mDataContent.equals(dataContent)) { - mDiffDataValues.put(DataColumns.CONTENT, dataContent); // 记录变化 + if (mIsCreate || !mDataContent.equals(dataContent)) { // 如果是新建或内容不同 + mDiffDataValues.put(DataColumns.CONTENT, dataContent); // 记录内容差异 } - mDataContent = dataContent; // 更新当前值 + mDataContent = dataContent; // 更新内容 - // 处理数据列1 long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0; - if (mIsCreate || mDataContentData1 != dataContentData1) { - mDiffDataValues.put(DataColumns.DATA1, dataContentData1); // 记录变化 + if (mIsCreate || mDataContentData1 != dataContentData1) { // 如果是新建或DATA1不同 + mDiffDataValues.put(DataColumns.DATA1, dataContentData1); // 记录DATA1差异 } - mDataContentData1 = dataContentData1; // 更新当前值 + mDataContentData1 = dataContentData1; // 更新DATA1 - // 处理数据列3 String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : ""; - if (mIsCreate || !mDataContentData3.equals(dataContentData3)) { - mDiffDataValues.put(DataColumns.DATA3, dataContentData3); // 记录变化 + if (mIsCreate || !mDataContentData3.equals(dataContentData3)) { // 如果是新建或DATA3不同 + mDiffDataValues.put(DataColumns.DATA3, dataContentData3); // 记录DATA3差异 } - mDataContentData3 = dataContentData3; // 更新当前值 + mDataContentData3 = dataContentData3; // 更新DATA3 } - /** - * 获取数据的JSON表示 - * @return JSON对象,包含所有数据字段 - * @throws JSONException JSON创建异常 - */ + // 将对象内容转换为JSON格式 public JSONObject getContent() throws JSONException { - if (mIsCreate) { + if (mIsCreate) { // 如果对象是新建的(未保存到数据库) Log.e(TAG, "it seems that we haven't created this in database yet"); - return null; + return null; // 返回null,因为数据不存在 } - JSONObject js = new JSONObject(); - js.put(DataColumns.ID, mDataId); // 添加数据ID - js.put(DataColumns.MIME_TYPE, mDataMimeType); // 添加MIME类型 - js.put(DataColumns.CONTENT, mDataContent); // 添加内容 - js.put(DataColumns.DATA1, mDataContentData1); // 添加数据列1 - js.put(DataColumns.DATA3, mDataContentData3); // 添加数据列3 - return js; + JSONObject js = new JSONObject(); // 创建JSON对象 + js.put(DataColumns.ID, mDataId); // 添加ID字段 + js.put(DataColumns.MIME_TYPE, mDataMimeType); // 添加MIME类型字段 + js.put(DataColumns.CONTENT, mDataContent); // 添加内容字段 + js.put(DataColumns.DATA1, mDataContentData1); // 添加DATA1字段 + js.put(DataColumns.DATA3, mDataContentData3); // 添加DATA3字段 + return js; // 返回JSON对象 } - /** - * 提交数据到数据库 - * 如果是新记录则插入,否则更新现有记录 - * @param noteId 关联的笔记ID - * @param validateVersion 是否验证版本号 - * @param version 版本号 - */ + // 提交数据到数据库(插入或更新) public void commit(long noteId, boolean validateVersion, long version) { - if (mIsCreate) { - // 新记录:插入操作 + if (mIsCreate) { // 如果是新建数据 if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { mDiffDataValues.remove(DataColumns.ID); // 移除无效ID } mDiffDataValues.put(DataColumns.NOTE_ID, noteId); // 添加笔记ID - Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); // 插入数据 + Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); // 插入数据库 try { - // 从返回的URI中提取新记录的ID - mDataId = Long.valueOf(uri.getPathSegments().get(1)); + mDataId = Long.valueOf(uri.getPathSegments().get(1)); // 从URI获取新生成的ID } catch (NumberFormatException e) { Log.e(TAG, "Get note id error :" + e.toString()); - throw new ActionFailureException("create note failed"); + throw new ActionFailureException("create note failed"); // 抛出异常 } - } else { - // 现有记录:更新操作 - if (mDiffDataValues.size() > 0) { + } else { // 如果是更新数据 + if (mDiffDataValues.size() > 0) { // 如果有需要更新的字段 int result = 0; - if (!validateVersion) { - // 不验证版本号:直接更新 + if (!validateVersion) { // 如果不验证版本 + // 直接更新数据 result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); - } else { - // 验证版本号:确保版本匹配 + } else { // 如果需要验证版本 + // 带版本控制的更新(防止同步冲突) result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE @@ -235,21 +170,17 @@ public class SqlData { String.valueOf(noteId), String.valueOf(version) }); } - if (result == 0) { + if (result == 0) { // 如果没有更新任何行 Log.w(TAG, "there is no update. maybe user updates note when syncing"); } } } - // 重置状态 mDiffDataValues.clear(); // 清空差异值 - mIsCreate = false; // 标记为现有记录 + mIsCreate = false; // 标记为已创建 } - /** - * 获取数据ID - * @return 数据ID - */ + // 获取数据ID public long getId() { return mDataId; } diff --git a/src/小米标签代码/src/net/micode/notes/gtask/data/SqlNote.java b/src/小米标签代码/src/net/micode/notes/gtask/data/SqlNote.java index d256e6f..72cd211 100644 --- a/src/小米标签代码/src/net/micode/notes/gtask/data/SqlNote.java +++ b/src/小米标签代码/src/net/micode/notes/gtask/data/SqlNote.java @@ -37,390 +37,303 @@ import org.json.JSONObject; import java.util.ArrayList; -/** - * SqlNote类 - * 表示数据库中的一个笔记(或文件夹),负责在SQLite数据库和JSON对象之间进行转换 - * 处理笔记的完整信息,包括笔记属性和关联的数据内容 - */ + public class SqlNote { - // 日志标签 - private static final String TAG = SqlNote.class.getSimpleName(); + private static final String TAG = SqlNote.class.getSimpleName(); // 日志标签 - // 无效ID常量 - private static final int INVALID_ID = -99999; + private static final int INVALID_ID = -99999; // 无效ID标识 - /** - * 笔记查询投影列 - * 定义从数据库查询笔记时需要返回的列 - */ + // 笔记查询的列投影 public static final String[] PROJECTION_NOTE = new String[] { - NoteColumns.ID, // 笔记ID - NoteColumns.ALERTED_DATE, // 提醒日期 - NoteColumns.BG_COLOR_ID, // 背景颜色ID - NoteColumns.CREATED_DATE, // 创建日期 - NoteColumns.HAS_ATTACHMENT, // 是否有附件 - NoteColumns.MODIFIED_DATE, // 修改日期 - NoteColumns.NOTES_COUNT, // 笔记数量(文件夹用) - NoteColumns.PARENT_ID, // 父节点ID - NoteColumns.SNIPPET, // 内容摘要 - NoteColumns.TYPE, // 类型(笔记/文件夹/系统) - NoteColumns.WIDGET_ID, // 小部件ID - NoteColumns.WIDGET_TYPE, // 小部件类型 - NoteColumns.SYNC_ID, // 同步ID - NoteColumns.LOCAL_MODIFIED, // 本地修改标志 - NoteColumns.ORIGIN_PARENT_ID, // 原始父节点ID - NoteColumns.GTASK_ID, // Google Task ID - NoteColumns.VERSION // 版本号 + NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID, + NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE, + NoteColumns.NOTES_COUNT, NoteColumns.PARENT_ID, NoteColumns.SNIPPET, NoteColumns.TYPE, + NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, NoteColumns.SYNC_ID, + NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID, + NoteColumns.VERSION }; - // 笔记ID列索引 + // 各列在游标中的索引 public static final int ID_COLUMN = 0; - // 提醒日期列索引 public static final int ALERTED_DATE_COLUMN = 1; - // 背景颜色ID列索引 public static final int BG_COLOR_ID_COLUMN = 2; - // 创建日期列索引 public static final int CREATED_DATE_COLUMN = 3; - // 是否有附件列索引 public static final int HAS_ATTACHMENT_COLUMN = 4; - // 修改日期列索引 public static final int MODIFIED_DATE_COLUMN = 5; - // 笔记数量列索引 public static final int NOTES_COUNT_COLUMN = 6; - // 父节点ID列索引 public static final int PARENT_ID_COLUMN = 7; - // 内容摘要列索引 public static final int SNIPPET_COLUMN = 8; - // 类型列索引 public static final int TYPE_COLUMN = 9; - // 小部件ID列索引 public static final int WIDGET_ID_COLUMN = 10; - // 小部件类型列索引 public static final int WIDGET_TYPE_COLUMN = 11; - // 同步ID列索引 public static final int SYNC_ID_COLUMN = 12; - // 本地修改标志列索引 public static final int LOCAL_MODIFIED_COLUMN = 13; - // 原始父节点ID列索引 public static final int ORIGIN_PARENT_ID_COLUMN = 14; - // Google Task ID列索引 public static final int GTASK_ID_COLUMN = 15; - // 版本号列索引 public static final int VERSION_COLUMN = 16; - // 上下文对象 - private Context mContext; - // 内容解析器 - private ContentResolver mContentResolver; - // 是否为新建笔记 - private boolean mIsCreate; - // 笔记ID - private long mId; - // 提醒日期 - private long mAlertDate; - // 背景颜色ID - private int mBgColorId; - // 创建日期 - private long mCreatedDate; - // 是否有附件(0:无, 1:有) - private int mHasAttachment; - // 修改日期 - private long mModifiedDate; - // 父节点ID - private long mParentId; - // 内容摘要 - private String mSnippet; - // 笔记类型 - private int mType; - // 小部件ID - private int mWidgetId; - // 小部件类型 - private int mWidgetType; - // 原始父节点ID(用于恢复) - private long mOriginParent; - // 版本号 - private long mVersion; - // 存储有变动的笔记值的ContentValues对象 - private ContentValues mDiffNoteValues; - // 关联的数据列表 - private ArrayList mDataList; - - /** - * 构造函数 - 用于创建新笔记 - * @param context 上下文对象 - */ + private Context mContext; // 上下文 + private ContentResolver mContentResolver; // 内容解析器 + private boolean mIsCreate; // 是否为新建笔记 + private long mId; // 笔记ID + private long mAlertDate; // 提醒日期 + private int mBgColorId; // 背景颜色ID + private long mCreatedDate; // 创建日期 + private int mHasAttachment; // 是否有附件 + private long mModifiedDate; // 修改日期 + private long mParentId; // 父笔记ID + private String mSnippet; // 内容摘要 + private int mType; // 笔记类型(笔记/文件夹/系统) + private int mWidgetId; // 小部件ID + private int mWidgetType; // 小部件类型 + private long mOriginParent; // 原始父笔记ID + private long mVersion; // 版本号 + private ContentValues mDiffNoteValues; // 笔记差异值 + private ArrayList mDataList; // 笔记关联的数据列表 + + // 构造函数:创建新笔记 public SqlNote(Context context) { mContext = context; mContentResolver = context.getContentResolver(); - mIsCreate = true; // 标记为新笔记 + mIsCreate = true; // 标记为新创建 mId = INVALID_ID; // 初始化为无效ID - mAlertDate = 0; // 默认无提醒 - mBgColorId = ResourceParser.getDefaultBgId(context); // 默认背景颜色 + mAlertDate = 0; // 提醒日期为0 + mBgColorId = ResourceParser.getDefaultBgId(context); // 获取默认背景颜色 mCreatedDate = System.currentTimeMillis(); // 创建时间为当前时间 mHasAttachment = 0; // 默认无附件 mModifiedDate = System.currentTimeMillis(); // 修改时间为当前时间 - mParentId = 0; // 默认父节点为根节点 - mSnippet = ""; // 内容摘要为空 - mType = Notes.TYPE_NOTE; // 默认为笔记类型 - mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; // 默认无效小部件ID - mWidgetType = Notes.TYPE_WIDGET_INVALIDE; // 默认无效小部件类型 - mOriginParent = 0; // 默认无原始父节点 - mVersion = 0; // 初始版本号为0 + mParentId = 0; // 父笔记ID为0(根目录) + mSnippet = ""; // 摘要为空 + mType = Notes.TYPE_NOTE; // 类型为普通笔记 + mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; // 小部件ID无效 + mWidgetType = Notes.TYPE_WIDGET_INVALIDE; // 小部件类型无效 + mOriginParent = 0; // 原始父笔记ID为0 + mVersion = 0; // 版本号为0 mDiffNoteValues = new ContentValues(); // 初始化差异值容器 mDataList = new ArrayList(); // 初始化数据列表 } - /** - * 构造函数 - 从数据库游标加载现有笔记 - * @param context 上下文对象 - * @param c 数据库游标 - */ + // 构造函数:从数据库游标创建笔记对象 public SqlNote(Context context, Cursor c) { mContext = context; mContentResolver = context.getContentResolver(); - mIsCreate = false; // 标记为现有笔记 + mIsCreate = false; // 标记为已存在 loadFromCursor(c); // 从游标加载笔记信息 mDataList = new ArrayList(); // 初始化数据列表 - if (mType == Notes.TYPE_NOTE) - loadDataContent(); // 如果是笔记类型,加载关联的数据内容 + if (mType == Notes.TYPE_NOTE) // 如果是普通笔记类型 + loadDataContent(); // 加载关联的数据内容 mDiffNoteValues = new ContentValues(); // 初始化差异值容器 } - /** - * 构造函数 - 根据笔记ID加载现有笔记 - * @param context 上下文对象 - * @param id 笔记ID - */ + // 构造函数:从笔记ID创建笔记对象 public SqlNote(Context context, long id) { mContext = context; mContentResolver = context.getContentResolver(); - mIsCreate = false; // 标记为现有笔记 - loadFromCursor(id); // 根据ID加载笔记信息 + mIsCreate = false; // 标记为已存在 + loadFromCursor(id); // 从ID加载笔记信息 mDataList = new ArrayList(); // 初始化数据列表 - if (mType == Notes.TYPE_NOTE) - loadDataContent(); // 如果是笔记类型,加载关联的数据内容 + if (mType == Notes.TYPE_NOTE) // 如果是普通笔记类型 + loadDataContent(); // 加载关联的数据内容 mDiffNoteValues = new ContentValues(); // 初始化差异值容器 } - /** - * 根据笔记ID从数据库加载笔记信息 - * @param id 笔记ID - */ + // 从笔记ID加载笔记信息 private void loadFromCursor(long id) { Cursor c = null; try { // 查询指定ID的笔记 c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)", - new String[] { - String.valueOf(id) - }, null); + new String[] { String.valueOf(id) }, null); if (c != null) { - c.moveToNext(); // 移动到第一条记录 + c.moveToNext(); // 移动到第一行 loadFromCursor(c); // 从游标加载数据 } else { Log.w(TAG, "loadFromCursor: cursor = null"); } } finally { if (c != null) - c.close(); // 确保关闭游标 + c.close(); // 关闭游标 } } - /** - * 从数据库游标加载笔记信息 - * @param c 数据库游标 - */ + // 从数据库游标加载笔记信息到对象字段 private void loadFromCursor(Cursor c) { - mId = c.getLong(ID_COLUMN); // 加载笔记ID - mAlertDate = c.getLong(ALERTED_DATE_COLUMN); // 加载提醒日期 - mBgColorId = c.getInt(BG_COLOR_ID_COLUMN); // 加载背景颜色ID - mCreatedDate = c.getLong(CREATED_DATE_COLUMN); // 加载创建日期 - mHasAttachment = c.getInt(HAS_ATTACHMENT_COLUMN); // 加载附件标志 - mModifiedDate = c.getLong(MODIFIED_DATE_COLUMN); // 加载修改日期 - mParentId = c.getLong(PARENT_ID_COLUMN); // 加载父节点ID - mSnippet = c.getString(SNIPPET_COLUMN); // 加载内容摘要 - mType = c.getInt(TYPE_COLUMN); // 加载笔记类型 - mWidgetId = c.getInt(WIDGET_ID_COLUMN); // 加载小部件ID - mWidgetType = c.getInt(WIDGET_TYPE_COLUMN); // 加载小部件类型 - mVersion = c.getLong(VERSION_COLUMN); // 加载版本号 + mId = c.getLong(ID_COLUMN); // 获取笔记ID + mAlertDate = c.getLong(ALERTED_DATE_COLUMN); // 获取提醒日期 + mBgColorId = c.getInt(BG_COLOR_ID_COLUMN); // 获取背景颜色ID + mCreatedDate = c.getLong(CREATED_DATE_COLUMN); // 获取创建日期 + mHasAttachment = c.getInt(HAS_ATTACHMENT_COLUMN); // 获取附件标记 + mModifiedDate = c.getLong(MODIFIED_DATE_COLUMN); // 获取修改日期 + mParentId = c.getLong(PARENT_ID_COLUMN); // 获取父笔记ID + mSnippet = c.getString(SNIPPET_COLUMN); // 获取内容摘要 + mType = c.getInt(TYPE_COLUMN); // 获取笔记类型 + mWidgetId = c.getInt(WIDGET_ID_COLUMN); // 获取小部件ID + mWidgetType = c.getInt(WIDGET_TYPE_COLUMN); // 获取小部件类型 + mVersion = c.getLong(VERSION_COLUMN); // 获取版本号 } - /** - * 加载笔记关联的数据内容 - * 查询数据表,加载与当前笔记关联的所有数据 - */ + // 加载笔记关联的数据内容 private void loadDataContent() { Cursor c = null; - mDataList.clear(); // 清空现有数据列表 + mDataList.clear(); // 清空数据列表 try { - // 查询关联的数据记录 + // 查询该笔记的所有关联数据 c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA, - "(note_id=?)", new String[] { - String.valueOf(mId) - }, null); + "(note_id=?)", new String[] { String.valueOf(mId) }, null); if (c != null) { - if (c.getCount() == 0) { + if (c.getCount() == 0) { // 如果没有数据 Log.w(TAG, "it seems that the note has not data"); return; } - // 遍历所有数据记录 - while (c.moveToNext()) { + while (c.moveToNext()) { // 遍历所有数据行 SqlData data = new SqlData(mContext, c); // 创建SqlData对象 - mDataList.add(data); // 添加到数据列表 + mDataList.add(data); // 添加到列表 } } else { Log.w(TAG, "loadDataContent: cursor = null"); } } finally { if (c != null) - c.close(); // 确保关闭游标 + c.close(); // 关闭游标 } } - /** - * 从JSON对象设置笔记内容 - * 比较JSON中的值与当前值,记录有变化的字段 - * @param js JSON对象,包含笔记内容和数据 - * @return 是否设置成功 - */ + // 从JSON对象设置笔记内容 public boolean setContent(JSONObject js) { try { - JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取笔记信息 - if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { - Log.w(TAG, "cannot set system folder"); // 不能设置系统文件夹 - } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { - // 处理文件夹:只能更新摘要和类型 + JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取笔记元数据 + if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { // 如果是系统文件夹 + Log.w(TAG, "cannot set system folder"); // 系统文件夹不能修改 + } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { // 如果是普通文件夹 + // 对于文件夹,只能更新摘要和类型 String snippet = note.has(NoteColumns.SNIPPET) ? note .getString(NoteColumns.SNIPPET) : ""; - if (mIsCreate || !mSnippet.equals(snippet)) { - mDiffNoteValues.put(NoteColumns.SNIPPET, snippet); // 记录变化 + if (mIsCreate || !mSnippet.equals(snippet)) { // 如果是新建或摘要不同 + mDiffNoteValues.put(NoteColumns.SNIPPET, snippet); // 记录摘要差异 } - mSnippet = snippet; // 更新当前值 + mSnippet = snippet; // 更新摘要 int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE) : Notes.TYPE_NOTE; - if (mIsCreate || mType != type) { - mDiffNoteValues.put(NoteColumns.TYPE, type); // 记录变化 + if (mIsCreate || mType != type) { // 如果是新建或类型不同 + mDiffNoteValues.put(NoteColumns.TYPE, type); // 记录类型差异 } - mType = type; // 更新当前值 - } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) { - // 处理笔记:更新所有字段 + mType = type; // 更新类型 + } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) { // 如果是普通笔记 JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); // 获取数据数组 - // 处理笔记ID + // 更新笔记ID long id = note.has(NoteColumns.ID) ? note.getLong(NoteColumns.ID) : INVALID_ID; if (mIsCreate || mId != id) { - mDiffNoteValues.put(NoteColumns.ID, id); // 记录变化 + mDiffNoteValues.put(NoteColumns.ID, id); } - mId = id; // 更新当前值 + mId = id; - // 处理提醒日期 + // 更新提醒日期 long alertDate = note.has(NoteColumns.ALERTED_DATE) ? note .getLong(NoteColumns.ALERTED_DATE) : 0; if (mIsCreate || mAlertDate != alertDate) { - mDiffNoteValues.put(NoteColumns.ALERTED_DATE, alertDate); // 记录变化 + mDiffNoteValues.put(NoteColumns.ALERTED_DATE, alertDate); } - mAlertDate = alertDate; // 更新当前值 + mAlertDate = alertDate; - // 处理背景颜色ID + // 更新背景颜色ID int bgColorId = note.has(NoteColumns.BG_COLOR_ID) ? note .getInt(NoteColumns.BG_COLOR_ID) : ResourceParser.getDefaultBgId(mContext); if (mIsCreate || mBgColorId != bgColorId) { - mDiffNoteValues.put(NoteColumns.BG_COLOR_ID, bgColorId); // 记录变化 + mDiffNoteValues.put(NoteColumns.BG_COLOR_ID, bgColorId); } - mBgColorId = bgColorId; // 更新当前值 + mBgColorId = bgColorId; - // 处理创建日期 + // 更新创建日期 long createDate = note.has(NoteColumns.CREATED_DATE) ? note .getLong(NoteColumns.CREATED_DATE) : System.currentTimeMillis(); if (mIsCreate || mCreatedDate != createDate) { - mDiffNoteValues.put(NoteColumns.CREATED_DATE, createDate); // 记录变化 + mDiffNoteValues.put(NoteColumns.CREATED_DATE, createDate); } - mCreatedDate = createDate; // 更新当前值 + mCreatedDate = createDate; - // 处理附件标志 + // 更新附件标记 int hasAttachment = note.has(NoteColumns.HAS_ATTACHMENT) ? note .getInt(NoteColumns.HAS_ATTACHMENT) : 0; if (mIsCreate || mHasAttachment != hasAttachment) { - mDiffNoteValues.put(NoteColumns.HAS_ATTACHMENT, hasAttachment); // 记录变化 + mDiffNoteValues.put(NoteColumns.HAS_ATTACHMENT, hasAttachment); } - mHasAttachment = hasAttachment; // 更新当前值 + mHasAttachment = hasAttachment; - // 处理修改日期 + // 更新修改日期 long modifiedDate = note.has(NoteColumns.MODIFIED_DATE) ? note .getLong(NoteColumns.MODIFIED_DATE) : System.currentTimeMillis(); if (mIsCreate || mModifiedDate != modifiedDate) { - mDiffNoteValues.put(NoteColumns.MODIFIED_DATE, modifiedDate); // 记录变化 + mDiffNoteValues.put(NoteColumns.MODIFIED_DATE, modifiedDate); } - mModifiedDate = modifiedDate; // 更新当前值 + mModifiedDate = modifiedDate; - // 处理父节点ID + // 更新父笔记ID long parentId = note.has(NoteColumns.PARENT_ID) ? note .getLong(NoteColumns.PARENT_ID) : 0; if (mIsCreate || mParentId != parentId) { - mDiffNoteValues.put(NoteColumns.PARENT_ID, parentId); // 记录变化 + mDiffNoteValues.put(NoteColumns.PARENT_ID, parentId); } - mParentId = parentId; // 更新当前值 + mParentId = parentId; - // 处理内容摘要 + // 更新内容摘要 String snippet = note.has(NoteColumns.SNIPPET) ? note .getString(NoteColumns.SNIPPET) : ""; if (mIsCreate || !mSnippet.equals(snippet)) { - mDiffNoteValues.put(NoteColumns.SNIPPET, snippet); // 记录变化 + mDiffNoteValues.put(NoteColumns.SNIPPET, snippet); } - mSnippet = snippet; // 更新当前值 + mSnippet = snippet; - // 处理笔记类型 + // 更新笔记类型 int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE) : Notes.TYPE_NOTE; if (mIsCreate || mType != type) { - mDiffNoteValues.put(NoteColumns.TYPE, type); // 记录变化 + mDiffNoteValues.put(NoteColumns.TYPE, type); } - mType = type; // 更新当前值 + mType = type; - // 处理小部件ID + // 更新小部件ID int widgetId = note.has(NoteColumns.WIDGET_ID) ? note.getInt(NoteColumns.WIDGET_ID) : AppWidgetManager.INVALID_APPWIDGET_ID; if (mIsCreate || mWidgetId != widgetId) { - mDiffNoteValues.put(NoteColumns.WIDGET_ID, widgetId); // 记录变化 + mDiffNoteValues.put(NoteColumns.WIDGET_ID, widgetId); } - mWidgetId = widgetId; // 更新当前值 + mWidgetId = widgetId; - // 处理小部件类型 + // 更新小部件类型 int widgetType = note.has(NoteColumns.WIDGET_TYPE) ? note .getInt(NoteColumns.WIDGET_TYPE) : Notes.TYPE_WIDGET_INVALIDE; if (mIsCreate || mWidgetType != widgetType) { - mDiffNoteValues.put(NoteColumns.WIDGET_TYPE, widgetType); // 记录变化 + mDiffNoteValues.put(NoteColumns.WIDGET_TYPE, widgetType); } - mWidgetType = widgetType; // 更新当前值 + mWidgetType = widgetType; - // 处理原始父节点ID + // 更新原始父笔记ID long originParent = note.has(NoteColumns.ORIGIN_PARENT_ID) ? note .getLong(NoteColumns.ORIGIN_PARENT_ID) : 0; if (mIsCreate || mOriginParent != originParent) { - mDiffNoteValues.put(NoteColumns.ORIGIN_PARENT_ID, originParent); // 记录变化 + mDiffNoteValues.put(NoteColumns.ORIGIN_PARENT_ID, originParent); } - mOriginParent = originParent; // 更新当前值 + mOriginParent = originParent; - // 处理关联的数据 + // 处理关联的数据内容 for (int i = 0; i < dataArray.length(); i++) { - JSONObject data = dataArray.getJSONObject(i); // 获取数据对象 + JSONObject data = dataArray.getJSONObject(i); // 获取单个数据对象 SqlData sqlData = null; - - // 根据数据ID查找现有的SqlData对象 - if (data.has(DataColumns.ID)) { + if (data.has(DataColumns.ID)) { // 如果数据有ID long dataId = data.getLong(DataColumns.ID); + // 在现有数据列表中查找匹配的数据 for (SqlData temp : mDataList) { if (dataId == temp.getId()) { - sqlData = temp; // 找到现有对象 + sqlData = temp; // 找到匹配的数据 break; } } } - // 如果没找到,创建新的SqlData对象 - if (sqlData == null) { - sqlData = new SqlData(mContext); + if (sqlData == null) { // 如果没有找到匹配的数据 + sqlData = new SqlData(mContext); // 创建新数据对象 mDataList.add(sqlData); // 添加到数据列表 } @@ -430,27 +343,24 @@ public class SqlNote { } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - return false; + return false; // 返回失败 } - return true; + return true; // 返回成功 } - /** - * 获取笔记内容的JSON表示 - * @return JSON对象,包含笔记信息和关联数据 - */ + // 将笔记内容转换为JSON格式 public JSONObject getContent() { try { - JSONObject js = new JSONObject(); + JSONObject js = new JSONObject(); // 创建JSON对象 - if (mIsCreate) { + if (mIsCreate) { // 如果是新建笔记(未保存) Log.e(TAG, "it seems that we haven't created this in database yet"); - return null; + return null; // 返回null } - JSONObject note = new JSONObject(); - if (mType == Notes.TYPE_NOTE) { - // 处理笔记类型:包含所有字段 + JSONObject note = new JSONObject(); // 创建笔记对象 + if (mType == Notes.TYPE_NOTE) { // 如果是普通笔记 + // 添加所有笔记字段到JSON note.put(NoteColumns.ID, mId); note.put(NoteColumns.ALERTED_DATE, mAlertDate); note.put(NoteColumns.BG_COLOR_ID, mBgColorId); @@ -463,173 +373,134 @@ public class SqlNote { note.put(NoteColumns.WIDGET_ID, mWidgetId); note.put(NoteColumns.WIDGET_TYPE, mWidgetType); note.put(NoteColumns.ORIGIN_PARENT_ID, mOriginParent); - js.put(GTaskStringUtils.META_HEAD_NOTE, note); // 添加笔记信息 - - // 添加关联数据 - JSONArray dataArray = new JSONArray(); - for (SqlData sqlData : mDataList) { - JSONObject data = sqlData.getContent(); - if (data != null) { - dataArray.put(data); // 添加到数据数组 + js.put(GTaskStringUtils.META_HEAD_NOTE, note); // 添加笔记元数据 + + // 处理关联的数据 + JSONArray dataArray = new JSONArray(); // 创建数据数组 + for (SqlData sqlData : mDataList) { // 遍历所有关联数据 + JSONObject data = sqlData.getContent(); // 获取数据JSON + if (data != null) { // 如果数据不为空 + dataArray.put(data); // 添加到数组 } } - js.put(GTaskStringUtils.META_HEAD_DATA, dataArray); // 添加数据信息 - } else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) { - // 处理文件夹或系统类型:只包含必要字段 + js.put(GTaskStringUtils.META_HEAD_DATA, dataArray); // 添加数据数组 + } else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) { // 如果是文件夹 + // 文件夹只有ID、类型和摘要字段 note.put(NoteColumns.ID, mId); note.put(NoteColumns.TYPE, mType); note.put(NoteColumns.SNIPPET, mSnippet); - js.put(GTaskStringUtils.META_HEAD_NOTE, note); // 添加笔记信息 + js.put(GTaskStringUtils.META_HEAD_NOTE, note); // 添加笔记元数据 } - return js; + return js; // 返回JSON对象 } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); } - return null; + return null; // 返回null } - /** - * 设置父节点ID - * @param id 父节点ID - */ + // 设置父笔记ID public void setParentId(long id) { - mParentId = id; - mDiffNoteValues.put(NoteColumns.PARENT_ID, id); // 记录变化 + mParentId = id; // 更新父笔记ID + mDiffNoteValues.put(NoteColumns.PARENT_ID, id); // 记录差异 } - /** - * 设置Google Task ID - * @param gid Google Task ID - */ + // 设置Google任务ID public void setGtaskId(String gid) { - mDiffNoteValues.put(NoteColumns.GTASK_ID, gid); // 记录变化 + mDiffNoteValues.put(NoteColumns.GTASK_ID, gid); // 记录Google任务ID差异 } - /** - * 设置同步ID - * @param syncId 同步ID - */ + // 设置同步ID public void setSyncId(long syncId) { - mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId); // 记录变化 + mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId); // 记录同步ID差异 } - /** - * 重置本地修改标志 - * 将本地修改标志设置为0(未修改) - */ + // 重置本地修改标记 public void resetLocalModified() { - mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0); // 记录变化 + mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0); // 将本地修改标记设为0 } - /** - * 获取笔记ID - * @return 笔记ID - */ + // 获取笔记ID public long getId() { return mId; } - /** - * 获取父节点ID - * @return 父节点ID - */ + // 获取父笔记ID public long getParentId() { return mParentId; } - /** - * 获取内容摘要 - * @return 内容摘要 - */ + // 获取内容摘要 public String getSnippet() { return mSnippet; } - /** - * 检查是否为笔记类型 - * @return 是否为笔记类型 - */ + // 检查是否为普通笔记类型 public boolean isNoteType() { return mType == Notes.TYPE_NOTE; } - /** - * 提交笔记到数据库 - * 如果是新笔记则插入,否则更新现有笔记 - * @param validateVersion 是否验证版本号 - */ + // 提交笔记到数据库(插入或更新) public void commit(boolean validateVersion) { - if (mIsCreate) { - // 新笔记:插入操作 + if (mIsCreate) { // 如果是新建笔记 if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) { mDiffNoteValues.remove(NoteColumns.ID); // 移除无效ID } - Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues); // 插入笔记 + Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues); // 插入数据库 try { - // 从返回的URI中提取新笔记的ID - mId = Long.valueOf(uri.getPathSegments().get(1)); + mId = Long.valueOf(uri.getPathSegments().get(1)); // 从URI获取新生成的ID } catch (NumberFormatException e) { Log.e(TAG, "Get note id error :" + e.toString()); - throw new ActionFailureException("create note failed"); + throw new ActionFailureException("create note failed"); // 抛出异常 } - if (mId == 0) { - throw new IllegalStateException("Create thread id failed"); + if (mId == 0) { // 如果ID为0(创建失败) + throw new IllegalStateException("Create thread id failed"); // 抛出异常 } - // 如果是笔记类型,提交关联的数据 - if (mType == Notes.TYPE_NOTE) { - for (SqlData sqlData : mDataList) { - sqlData.commit(mId, false, -1); // 提交数据,不验证版本 + if (mType == Notes.TYPE_NOTE) { // 如果是普通笔记 + for (SqlData sqlData : mDataList) { // 遍历所有关联数据 + sqlData.commit(mId, false, -1); // 提交数据到数据库 } } - } else { - // 现有笔记:更新操作 - // 验证笔记ID(系统文件夹除外) + } else { // 如果是更新笔记 + // 验证笔记ID有效性 if (mId <= 0 && mId != Notes.ID_ROOT_FOLDER && mId != Notes.ID_CALL_RECORD_FOLDER) { Log.e(TAG, "No such note"); - throw new IllegalStateException("Try to update note with invalid id"); + throw new IllegalStateException("Try to update note with invalid id"); // 抛出异常 } - - if (mDiffNoteValues.size() > 0) { - mVersion ++; // 增加版本号 + if (mDiffNoteValues.size() > 0) { // 如果有需要更新的字段 + mVersion++; // 增加版本号 int result = 0; - if (!validateVersion) { - // 不验证版本号:直接更新 + if (!validateVersion) { // 如果不验证版本 + // 直接更新笔记 result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "(" - + NoteColumns.ID + "=?)", new String[] { - String.valueOf(mId) - }); - } else { - // 验证版本号:确保版本匹配 + + NoteColumns.ID + "=?)", new String[] { String.valueOf(mId) }); + } else { // 如果需要验证版本 + // 带版本控制的更新(防止同步冲突) result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "(" + NoteColumns.ID + "=?) AND (" + NoteColumns.VERSION + "<=?)", - new String[] { - String.valueOf(mId), String.valueOf(mVersion) - }); + new String[] { String.valueOf(mId), String.valueOf(mVersion) }); } - if (result == 0) { + if (result == 0) { // 如果没有更新任何行 Log.w(TAG, "there is no update. maybe user updates note when syncing"); } } - // 如果是笔记类型,提交关联的数据 - if (mType == Notes.TYPE_NOTE) { - for (SqlData sqlData : mDataList) { - sqlData.commit(mId, validateVersion, mVersion); // 提交数据,验证版本 + if (mType == Notes.TYPE_NOTE) { // 如果是普通笔记 + for (SqlData sqlData : mDataList) { // 遍历所有关联数据 + sqlData.commit(mId, validateVersion, mVersion); // 提交数据到数据库 } } } // 刷新本地信息 - loadFromCursor(mId); // 重新从数据库加载笔记信息 - if (mType == Notes.TYPE_NOTE) + loadFromCursor(mId); // 重新加载笔记信息 + if (mType == Notes.TYPE_NOTE) // 如果是普通笔记 loadDataContent(); // 重新加载关联数据 - // 重置状态 mDiffNoteValues.clear(); // 清空差异值 - mIsCreate = false; // 标记为现有笔记 + mIsCreate = false; // 标记为已创建 } } \ No newline at end of file diff --git a/src/小米标签代码/src/net/micode/notes/gtask/data/Task.java b/src/小米标签代码/src/net/micode/notes/gtask/data/Task.java index 6a5a578..7146cda 100644 --- a/src/小米标签代码/src/net/micode/notes/gtask/data/Task.java +++ b/src/小米标签代码/src/net/micode/notes/gtask/data/Task.java @@ -31,81 +31,63 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -/** - * Task类 - * 表示Google Task中的一个任务(对应笔记应用中的一个笔记) - * 继承自Node类,增加了任务特有的属性和方法 - */ + public class Task extends Node { - // 日志标签 - private static final String TAG = Task.class.getSimpleName(); - - // 任务是否已完成 - private boolean mCompleted; - // 任务备注/笔记内容 - private String mNotes; - // 元信息JSON对象(包含本地数据库信息) - private JSONObject mMetaInfo; - // 前一个兄弟任务(用于保持任务顺序) - private Task mPriorSibling; - // 父任务列表 - private TaskList mParent; - - /** - * 构造函数 - * 初始化任务的默认值 - */ + private static final String TAG = Task.class.getSimpleName(); // 日志标签 + + private boolean mCompleted; // 任务是否完成 + private String mNotes; // 任务备注 + private JSONObject mMetaInfo; // 元数据信息(存储笔记的完整信息) + private Task mPriorSibling; // 前一个兄弟任务(用于排序) + private TaskList mParent; // 父任务列表 + + // 构造函数 public Task() { - super(); - mCompleted = false; // 默认未完成 - mNotes = null; // 默认无备注 - mPriorSibling = null; // 默认无前兄弟 - mParent = null; // 默认无父列表 - mMetaInfo = null; // 默认无元信息 + super(); // 调用父类构造函数 + mCompleted = false; // 默认未完成 + mNotes = null; // 备注为空 + mPriorSibling = null; // 前兄弟任务为空 + mParent = null; // 父任务列表为空 + mMetaInfo = null; // 元数据为空 } - /** - * 获取创建动作的JSON对象 - * 用于将任务创建到Google Tasks服务器 - * @param actionId 动作ID - * @return 创建动作的JSON对象 - */ + // 获取创建任务的JSON操作对象 public JSONObject getCreateAction(int actionId) { - JSONObject js = new JSONObject(); + JSONObject js = new JSONObject(); // 创建JSON对象 try { - // 动作类型:创建 + // 设置操作类型为创建 js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); - // 动作ID + // 设置操作ID js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); - // 索引位置(在父列表中的位置) + // 设置任务在列表中的索引位置 js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this)); - // 实体增量(包含任务信息) + // 创建实体数据 JSONObject entity = new JSONObject(); entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 任务名称 entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); // 创建者ID entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, - GTaskStringUtils.GTASK_JSON_TYPE_TASK); // 实体类型:任务 - if (getNotes() != null) { - entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); // 任务备注 + GTaskStringUtils.GTASK_JSON_TYPE_TASK); // 实体类型为任务 + if (getNotes() != null) { // 如果有备注 + entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); // 添加备注 } - js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); // 添加实体数据 - // 父节点ID + // 设置父任务列表ID js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid()); - // 目标父节点类型 + // 设置目标父类型为组(任务列表) js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE, GTaskStringUtils.GTASK_JSON_TYPE_GROUP); - // 列表ID + // 设置列表ID js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid()); - // 前兄弟节点ID(用于确定插入位置) + // 如果有前兄弟任务,设置前兄弟任务ID if (mPriorSibling != null) { js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid()); } @@ -113,123 +95,108 @@ public class Task extends Node { } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - throw new ActionFailureException("fail to generate task-create jsonobject"); + throw new ActionFailureException("fail to generate task-create jsonobject"); // 抛出异常 } - return js; + return js; // 返回JSON对象 } - /** - * 获取更新动作的JSON对象 - * 用于更新Google Tasks服务器上的任务 - * @param actionId 动作ID - * @return 更新动作的JSON对象 - */ + // 获取更新任务的JSON操作对象 public JSONObject getUpdateAction(int actionId) { - JSONObject js = new JSONObject(); + JSONObject js = new JSONObject(); // 创建JSON对象 try { - // 动作类型:更新 + // 设置操作类型为更新 js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE); - // 动作ID + // 设置操作ID js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); - // 任务ID + // 设置任务ID js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); - // 实体增量(包含更新的任务信息) + // 创建实体数据 JSONObject entity = new JSONObject(); entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 任务名称 - if (getNotes() != null) { - entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); // 任务备注 + if (getNotes() != null) { // 如果有备注 + entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); // 添加备注 } - entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); // 删除标志 - js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); // 删除状态 + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); // 添加实体数据 } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - throw new ActionFailureException("fail to generate task-update jsonobject"); + throw new ActionFailureException("fail to generate task-update jsonobject"); // 抛出异常 } - return js; + return js; // 返回JSON对象 } - /** - * 从远程JSON设置内容 - * 将从Google Tasks服务器获取的JSON数据解析到任务对象中 - * @param js 远程JSON对象 - */ + // 从远程JSON设置任务内容(从Google Tasks API获取的数据) public void setContentByRemoteJSON(JSONObject js) { if (js != null) { try { - // 任务ID + // 设置任务ID if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); } - // 最后修改时间 + // 设置最后修改时间 if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); } - // 任务名称 + // 设置任务名称 if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); } - // 任务备注 + // 设置任务备注 if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) { setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES)); } - // 删除标志 + // 设置删除状态 if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) { setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED)); } - // 完成状态 + // 设置完成状态 if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) { setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED)); } } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - throw new ActionFailureException("fail to get task content from jsonobject"); + throw new ActionFailureException("fail to get task content from jsonobject"); // 抛出异常 } } } - /** - * 从本地JSON设置内容 - * 将本地数据库中的JSON数据解析到任务对象中 - * @param js 本地JSON对象 - */ + // 从本地JSON设置任务内容(从数据库获取的数据) public void setContentByLocalJSON(JSONObject js) { if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE) || !js.has(GTaskStringUtils.META_HEAD_DATA)) { - Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); + Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); // 没有可用数据 + return; } try { - // 解析笔记信息 - JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); - JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); + JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取笔记元数据 + JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); // 获取数据数组 - // 验证笔记类型 - if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) { + if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) { // 如果不是普通笔记类型 Log.e(TAG, "invalid type"); return; } - // 遍历数据数组,查找笔记内容 + // 遍历数据数组,找到类型为NOTE的数据作为任务名称 for (int i = 0; i < dataArray.length(); i++) { JSONObject data = dataArray.getJSONObject(i); if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) { - // 将笔记内容设置为任务名称 - setName(data.getString(DataColumns.CONTENT)); + setName(data.getString(DataColumns.CONTENT)); // 设置任务名称 break; } } @@ -240,19 +207,14 @@ public class Task extends Node { } } - /** - * 从内容获取本地JSON - * 将任务对象转换为本地数据库存储的JSON格式 - * @return 本地JSON对象 - */ + // 从任务内容生成本地JSON(用于保存到数据库) public JSONObject getLocalJSONFromContent() { - String name = getName(); + String name = getName(); // 获取任务名称 try { - if (mMetaInfo == null) { - // 从Web创建的新任务(无元信息) - if (name == null) { + if (mMetaInfo == null) { // 如果没有元数据信息(从网页创建的新任务) + if (name == null) { // 如果名称为空 Log.w(TAG, "the note seems to be an empty one"); - return null; + return null; // 返回null } // 创建新的JSON结构 @@ -260,75 +222,63 @@ public class Task extends Node { JSONObject note = new JSONObject(); JSONArray dataArray = new JSONArray(); JSONObject data = new JSONObject(); - data.put(DataColumns.CONTENT, name); // 笔记内容 - dataArray.put(data); - js.put(GTaskStringUtils.META_HEAD_DATA, dataArray); // 数据部分 - note.put(NoteColumns.TYPE, Notes.TYPE_NOTE); // 笔记类型 - js.put(GTaskStringUtils.META_HEAD_NOTE, note); // 笔记信息 - return js; - } else { - // 已同步的任务(有元信息) - JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); - JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA); - - // 更新笔记内容 + data.put(DataColumns.CONTENT, name); // 设置内容为任务名称 + dataArray.put(data); // 添加数据到数组 + js.put(GTaskStringUtils.META_HEAD_DATA, dataArray); // 添加数据数组 + note.put(NoteColumns.TYPE, Notes.TYPE_NOTE); // 设置类型为笔记 + js.put(GTaskStringUtils.META_HEAD_NOTE, note); // 添加笔记元数据 + return js; // 返回JSON对象 + } else { // 如果已有元数据信息(已同步的任务) + JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取笔记元数据 + JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA); // 获取数据数组 + + // 更新数据数组中的任务名称 for (int i = 0; i < dataArray.length(); i++) { JSONObject data = dataArray.getJSONObject(i); if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) { - data.put(DataColumns.CONTENT, getName()); // 更新笔记内容 + data.put(DataColumns.CONTENT, getName()); // 更新任务名称 break; } } - note.put(NoteColumns.TYPE, Notes.TYPE_NOTE); // 更新笔记类型 - return mMetaInfo; // 返回更新后的元信息 + note.put(NoteColumns.TYPE, Notes.TYPE_NOTE); // 确保类型为笔记 + return mMetaInfo; // 返回更新后的元数据 } } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - return null; + return null; // 返回null } } - /** - * 设置元信息 - * 从MetaData对象中提取并解析元信息 - * @param metaData MetaData对象 - */ + // 设置元数据信息 public void setMetaInfo(MetaData metaData) { if (metaData != null && metaData.getNotes() != null) { try { - // 从备注中解析元信息JSON - mMetaInfo = new JSONObject(metaData.getNotes()); + mMetaInfo = new JSONObject(metaData.getNotes()); // 从备注解析JSON } catch (JSONException e) { Log.w(TAG, e.toString()); - mMetaInfo = null; // 解析失败时设置为null + mMetaInfo = null; // 解析失败则设为null } } } - /** - * 获取同步动作 - * 根据本地数据库和远程状态确定需要的同步动作 - * @param c 数据库游标 - * @return 同步动作类型 - */ + // 根据数据库游标确定同步操作类型 public int getSyncAction(Cursor c) { try { JSONObject noteInfo = null; if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) { - // 从元信息中获取笔记信息 - noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取笔记信息 } - if (noteInfo == null) { + if (noteInfo == null) { // 如果没有笔记信息 Log.w(TAG, "it seems that note meta has been deleted"); - return SYNC_ACTION_UPDATE_REMOTE; // 元信息被删除,需要更新远程 + return SYNC_ACTION_UPDATE_REMOTE; // 需要更新远程 } - if (!noteInfo.has(NoteColumns.ID)) { + if (!noteInfo.has(NoteColumns.ID)) { // 如果没有笔记ID Log.w(TAG, "remote note id seems to be deleted"); - return SYNC_ACTION_UPDATE_LOCAL; // 远程笔记ID被删除,需要更新本地 + return SYNC_ACTION_UPDATE_LOCAL; // 需要更新本地 } // 验证笔记ID是否匹配 @@ -337,29 +287,22 @@ public class Task extends Node { return SYNC_ACTION_UPDATE_LOCAL; // ID不匹配,需要更新本地 } - // 检查本地修改标志 - if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { - // 无本地更新 - if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { - // 两端均无更新 - return SYNC_ACTION_NONE; + if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { // 如果本地没有修改 + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { // 如果同步ID等于最后修改时间 + return SYNC_ACTION_NONE; // 无需同步 } else { - // 将远程更新应用到本地 - return SYNC_ACTION_UPDATE_LOCAL; + return SYNC_ACTION_UPDATE_LOCAL; // 需要更新本地 } - } else { - // 有本地更新 - // 验证Google Task ID是否匹配 + } else { // 如果本地有修改 + // 验证Google任务ID是否匹配 if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) { Log.e(TAG, "gtask id doesn't match"); return SYNC_ACTION_ERROR; // ID不匹配,返回错误 } - if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { - // 只有本地有修改 - return SYNC_ACTION_UPDATE_REMOTE; + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { // 如果同步ID等于最后修改时间 + return SYNC_ACTION_UPDATE_REMOTE; // 只需要更新远程 } else { - // 两端都有修改,发生冲突 - return SYNC_ACTION_UPDATE_CONFLICT; + return SYNC_ACTION_UPDATE_CONFLICT; // 有冲突 } } } catch (Exception e) { @@ -367,49 +310,51 @@ public class Task extends Node { e.printStackTrace(); } - return SYNC_ACTION_ERROR; // 发生异常,返回错误 + return SYNC_ACTION_ERROR; // 返回错误 } - /** - * 检查是否值得保存 - * 判断任务是否有足够的信息值得保存到本地数据库 - * @return 是否值得保存 - */ + // 检查任务是否值得保存(有名称或备注) public boolean isWorthSaving() { return mMetaInfo != null || (getName() != null && getName().trim().length() > 0) || (getNotes() != null && getNotes().trim().length() > 0); } - // 以下为属性的getter和setter方法 - + // 设置任务完成状态 public void setCompleted(boolean completed) { this.mCompleted = completed; } + // 设置任务备注 public void setNotes(String notes) { this.mNotes = notes; } + // 设置前兄弟任务 public void setPriorSibling(Task priorSibling) { this.mPriorSibling = priorSibling; } + // 设置父任务列表 public void setParent(TaskList parent) { this.mParent = parent; } + // 获取任务完成状态 public boolean getCompleted() { return this.mCompleted; } + // 获取任务备注 public String getNotes() { return this.mNotes; } + // 获取前兄弟任务 public Task getPriorSibling() { return this.mPriorSibling; } + // 获取父任务列表 public TaskList getParent() { return this.mParent; } diff --git a/src/小米标签代码/src/net/micode/notes/gtask/data/TaskList.java b/src/小米标签代码/src/net/micode/notes/gtask/data/TaskList.java index 802f619..ef4671f 100644 --- a/src/小米标签代码/src/net/micode/notes/gtask/data/TaskList.java +++ b/src/小米标签代码/src/net/micode/notes/gtask/data/TaskList.java @@ -29,121 +29,97 @@ import org.json.JSONObject; import java.util.ArrayList; -/** - * TaskList类 - * 表示Google Task中的一个任务列表(对应笔记应用中的一个文件夹) - * 继承自Node类,可以包含多个Task子任务 - */ -public class TaskList extends Node { - // 日志标签 - private static final String TAG = TaskList.class.getSimpleName(); - - // 索引位置(在父节点中的位置) - private int mIndex; - // 子任务列表 - private ArrayList mChildren; - - /** - * 构造函数 - * 初始化任务列表 - */ + +public class TaskList extends Node { // 任务列表类,继承自Node + private static final String TAG = TaskList.class.getSimpleName(); // 日志标签 + + private int mIndex; // 列表索引 + private ArrayList mChildren; // 子任务列表 + + // 构造函数 public TaskList() { - super(); + super(); // 调用父类构造函数 mChildren = new ArrayList(); // 初始化子任务列表 mIndex = 1; // 默认索引为1 } - /** - * 获取创建动作的JSON对象 - * 用于将任务列表创建到Google Tasks服务器 - * @param actionId 动作ID - * @return 创建动作的JSON对象 - */ + // 获取创建任务列表的JSON操作对象 public JSONObject getCreateAction(int actionId) { - JSONObject js = new JSONObject(); + JSONObject js = new JSONObject(); // 创建JSON对象 try { - // 动作类型:创建 + // 设置操作类型为创建 js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); - // 动作ID + // 设置操作ID js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); - // 索引位置 + // 设置列表索引 js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex); - // 实体增量(包含任务列表信息) + // 创建实体数据 JSONObject entity = new JSONObject(); entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 列表名称 entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); // 创建者ID entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, - GTaskStringUtils.GTASK_JSON_TYPE_GROUP); // 实体类型:组/列表 - js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + GTaskStringUtils.GTASK_JSON_TYPE_GROUP); // 实体类型为组 + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); // 添加实体数据 } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - throw new ActionFailureException("fail to generate tasklist-create jsonobject"); + throw new ActionFailureException("fail to generate tasklist-create jsonobject"); // 抛出异常 } - return js; + return js; // 返回JSON对象 } - /** - * 获取更新动作的JSON对象 - * 用于更新Google Tasks服务器上的任务列表 - * @param actionId 动作ID - * @return 更新动作的JSON对象 - */ + // 获取更新任务列表的JSON操作对象 public JSONObject getUpdateAction(int actionId) { - JSONObject js = new JSONObject(); + JSONObject js = new JSONObject(); // 创建JSON对象 try { - // 动作类型:更新 + // 设置操作类型为更新 js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE); - // 动作ID + // 设置操作ID js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); - // 列表ID + // 设置任务列表ID js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); - // 实体增量(包含更新的列表信息) + // 创建实体数据 JSONObject entity = new JSONObject(); entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 列表名称 - entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); // 删除标志 - js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); // 删除状态 + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); // 添加实体数据 } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - throw new ActionFailureException("fail to generate tasklist-update jsonobject"); + throw new ActionFailureException("fail to generate tasklist-update jsonobject"); // 抛出异常 } - return js; + return js; // 返回JSON对象 } - /** - * 从远程JSON设置内容 - * 将从Google Tasks服务器获取的JSON数据解析到任务列表对象中 - * @param js 远程JSON对象 - */ + // 从远程JSON设置任务列表内容 public void setContentByRemoteJSON(JSONObject js) { if (js != null) { try { - // 列表ID + // 设置任务列表ID if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); } - // 最后修改时间 + // 设置最后修改时间 if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); } - // 列表名称 + // 设置任务列表名称 if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); } @@ -151,41 +127,34 @@ public class TaskList extends Node { } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - throw new ActionFailureException("fail to get tasklist content from jsonobject"); + throw new ActionFailureException("fail to get tasklist content from jsonobject"); // 抛出异常 } } } - /** - * 从本地JSON设置内容 - * 将本地数据库中的JSON数据解析到任务列表对象中 - * @param js 本地JSON对象 - */ + // 从本地JSON设置任务列表内容 public void setContentByLocalJSON(JSONObject js) { if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) { - Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); + Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); // 没有可用数据 + return; } try { - // 解析文件夹信息 - JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取文件夹信息 - // 根据文件夹类型设置名称 - if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { - // 普通文件夹 - String name = folder.getString(NoteColumns.SNIPPET); + if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { // 如果是普通文件夹 + String name = folder.getString(NoteColumns.SNIPPET); // 获取文件夹名称 setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name); // 添加MIUI前缀 - } else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { - // 系统文件夹 - if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER) - setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT); // 默认文件夹 - else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER) + } else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { // 如果是系统文件夹 + if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER) // 根文件夹 + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT); + else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER) // 通话记录文件夹 setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX - + GTaskStringUtils.FOLDER_CALL_NOTE); // 通话记录文件夹 + + GTaskStringUtils.FOLDER_CALL_NOTE); else Log.e(TAG, "invalid system folder"); // 无效的系统文件夹 } else { - Log.e(TAG, "error type"); // 错误类型 + Log.e(TAG, "error type"); // 错误的类型 } } catch (JSONException e) { Log.e(TAG, e.toString()); @@ -193,71 +162,52 @@ public class TaskList extends Node { } } - /** - * 从内容获取本地JSON - * 将任务列表对象转换为本地数据库存储的JSON格式 - * @return 本地JSON对象 - */ + // 从任务列表内容生成本地JSON public JSONObject getLocalJSONFromContent() { try { - JSONObject js = new JSONObject(); - JSONObject folder = new JSONObject(); + JSONObject js = new JSONObject(); // 创建JSON对象 + JSONObject folder = new JSONObject(); // 创建文件夹对象 - // 处理文件夹名称(移除MIUI前缀) - String folderName = getName(); - if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX)) + String folderName = getName(); // 获取文件夹名称 + if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX)) // 如果以MIUI前缀开头 folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(), - folderName.length()); - - folder.put(NoteColumns.SNIPPET, folderName); // 文件夹名称 - - // 设置文件夹类型 - if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT) - || folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE)) - folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); // 系统文件夹 + folderName.length()); // 去除前缀 + folder.put(NoteColumns.SNIPPET, folderName); // 设置文件夹摘要 + if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT) // 默认文件夹 + || folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE)) // 通话记录文件夹 + folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); // 类型为系统文件夹 else - folder.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); // 普通文件夹 + folder.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); // 类型为普通文件夹 - js.put(GTaskStringUtils.META_HEAD_NOTE, folder); // 添加到JSON + js.put(GTaskStringUtils.META_HEAD_NOTE, folder); // 添加文件夹信息 - return js; + return js; // 返回JSON对象 } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); - return null; + return null; // 返回null } } - /** - * 获取同步动作 - * 根据本地数据库和远程状态确定需要的同步动作 - * @param c 数据库游标 - * @return 同步动作类型 - */ + // 根据数据库游标确定同步操作类型 public int getSyncAction(Cursor c) { try { - // 检查本地修改标志 - if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { - // 无本地更新 - if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { - // 两端均无更新 - return SYNC_ACTION_NONE; + if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { // 如果本地没有修改 + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { // 如果同步ID等于最后修改时间 + return SYNC_ACTION_NONE; // 无需同步 } else { - // 将远程更新应用到本地 - return SYNC_ACTION_UPDATE_LOCAL; + return SYNC_ACTION_UPDATE_LOCAL; // 需要更新本地 } - } else { - // 有本地更新 - // 验证Google Task ID是否匹配 + } else { // 如果本地有修改 + // 验证Google任务ID是否匹配 if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) { Log.e(TAG, "gtask id doesn't match"); return SYNC_ACTION_ERROR; // ID不匹配,返回错误 } - if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { - // 只有本地有修改 - return SYNC_ACTION_UPDATE_REMOTE; + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { // 如果同步ID等于最后修改时间 + return SYNC_ACTION_UPDATE_REMOTE; // 只需要更新远程 } else { - // 对于文件夹冲突,优先应用本地修改 + // 对于文件夹冲突,直接应用本地修改 return SYNC_ACTION_UPDATE_REMOTE; } } @@ -266,184 +216,141 @@ public class TaskList extends Node { e.printStackTrace(); } - return SYNC_ACTION_ERROR; // 发生异常,返回错误 + return SYNC_ACTION_ERROR; // 返回错误 } - /** - * 获取子任务数量 - * @return 子任务数量 - */ + // 获取子任务数量 public int getChildTaskCount() { return mChildren.size(); } - /** - * 添加子任务(添加到末尾) - * @param task 要添加的子任务 - * @return 是否添加成功 - */ + // 添加子任务到列表末尾 public boolean addChildTask(Task task) { boolean ret = false; - if (task != null && !mChildren.contains(task)) { - ret = mChildren.add(task); // 添加到列表末尾 + if (task != null && !mChildren.contains(task)) { // 如果任务不为空且不在列表中 + ret = mChildren.add(task); // 添加到列表 if (ret) { - // 设置前兄弟节点和父节点 + // 需要设置前兄弟任务和父任务列表 task.setPriorSibling(mChildren.isEmpty() ? null : mChildren - .get(mChildren.size() - 1)); // 前兄弟为前一个元素(如果存在) - task.setParent(this); // 设置父节点为当前列表 + .get(mChildren.size() - 1)); // 前兄弟任务为列表最后一个 + task.setParent(this); // 父任务列表为当前列表 } } return ret; } - /** - * 添加子任务到指定位置 - * @param task 要添加的子任务 - * @param index 插入位置 - * @return 是否添加成功 - */ + // 在指定位置添加子任务 public boolean addChildTask(Task task, int index) { - if (index < 0 || index > mChildren.size()) { + if (index < 0 || index > mChildren.size()) { // 检查索引有效性 Log.e(TAG, "add child task: invalid index"); return false; } - int pos = mChildren.indexOf(task); - if (task != null && pos == -1) { - mChildren.add(index, task); // 插入到指定位置 + int pos = mChildren.indexOf(task); // 获取任务位置 + if (task != null && pos == -1) { // 如果任务不为空且不在列表中 + mChildren.add(index, task); // 在指定位置添加 - // 更新任务列表的前兄弟关系 + // 更新任务列表关系 Task preTask = null; Task afterTask = null; - if (index != 0) + if (index != 0) // 如果不是第一个 preTask = mChildren.get(index - 1); // 前一个任务 - if (index != mChildren.size() - 1) + if (index != mChildren.size() - 1) // 如果不是最后一个 afterTask = mChildren.get(index + 1); // 后一个任务 - task.setPriorSibling(preTask); // 设置前兄弟节点 - if (afterTask != null) - afterTask.setPriorSibling(task); // 更新后一个任务的前兄弟节点 + task.setPriorSibling(preTask); // 设置前兄弟任务 + if (afterTask != null) // 如果有后一个任务 + afterTask.setPriorSibling(task); // 更新后一个任务的前兄弟任务 } return true; } - /** - * 移除子任务 - * @param task 要移除的子任务 - * @return 是否移除成功 - */ + // 移除子任务 public boolean removeChildTask(Task task) { boolean ret = false; - int index = mChildren.indexOf(task); - if (index != -1) { + int index = mChildren.indexOf(task); // 获取任务索引 + if (index != -1) { // 如果任务在列表中 ret = mChildren.remove(task); // 移除任务 if (ret) { - // 重置任务的前兄弟节点和父节点 - task.setPriorSibling(null); - task.setParent(null); + // 重置前兄弟任务和父任务列表 + task.setPriorSibling(null); // 前兄弟任务设为null + task.setParent(null); // 父任务列表设为null // 更新任务列表 - if (index != mChildren.size()) { - // 更新被移除任务后一个任务的前兄弟节点 + if (index != mChildren.size()) { // 如果不是最后一个 mChildren.get(index).setPriorSibling( - index == 0 ? null : mChildren.get(index - 1)); + index == 0 ? null : mChildren.get(index - 1)); // 更新前兄弟任务 } } } return ret; } - /** - * 移动子任务到新位置 - * @param task 要移动的子任务 - * @param index 目标位置 - * @return 是否移动成功 - */ + // 移动子任务到新位置 public boolean moveChildTask(Task task, int index) { - if (index < 0 || index >= mChildren.size()) { + if (index < 0 || index >= mChildren.size()) { // 检查索引有效性 Log.e(TAG, "move child task: invalid index"); return false; } - int pos = mChildren.indexOf(task); - if (pos == -1) { + int pos = mChildren.indexOf(task); // 获取任务当前位置 + if (pos == -1) { // 如果任务不在列表中 Log.e(TAG, "move child task: the task should in the list"); return false; } - if (pos == index) // 位置未变 + if (pos == index) // 如果位置相同 return true; - - // 先移除再添加到新位置 - return (removeChildTask(task) && addChildTask(task, index)); + return (removeChildTask(task) && addChildTask(task, index)); // 先移除再添加 } - /** - * 根据Google Task ID查找子任务 - * @param gid Google Task ID - * @return 找到的任务,未找到返回null - */ + // 根据Google任务ID查找子任务 public Task findChildTaskByGid(String gid) { for (int i = 0; i < mChildren.size(); i++) { Task t = mChildren.get(i); - if (t.getGid().equals(gid)) { - return t; + if (t.getGid().equals(gid)) { // 如果ID匹配 + return t; // 返回任务 } } - return null; + return null; // 没找到返回null } - /** - * 获取子任务的索引位置 - * @param task 子任务 - * @return 索引位置,未找到返回-1 - */ + // 获取子任务在列表中的索引 public int getChildTaskIndex(Task task) { - return mChildren.indexOf(task); + return mChildren.indexOf(task); // 返回任务索引 } - /** - * 根据索引获取子任务 - * @param index 索引位置 - * @return 子任务,索引无效返回null - */ + // 根据索引获取子任务 public Task getChildTaskByIndex(int index) { - if (index < 0 || index >= mChildren.size()) { + if (index < 0 || index >= mChildren.size()) { // 检查索引有效性 Log.e(TAG, "getTaskByIndex: invalid index"); - return null; + return null; // 返回null } - return mChildren.get(index); + return mChildren.get(index); // 返回任务 } - /** - * 根据Google Task ID获取子任务 - * @param gid Google Task ID - * @return 子任务,未找到返回null - */ + // 根据Google任务ID获取子任务 public Task getChilTaskByGid(String gid) { - for (Task task : mChildren) { - if (task.getGid().equals(gid)) - return task; + for (Task task : mChildren) { // 遍历所有任务 + if (task.getGid().equals(gid)) // 如果ID匹配 + return task; // 返回任务 } - return null; + return null; // 没找到返回null } - /** - * 获取子任务列表 - * @return 子任务列表 - */ + // 获取子任务列表 public ArrayList getChildTaskList() { return this.mChildren; } - // 以下为属性的getter和setter方法 - + // 设置列表索引 public void setIndex(int index) { this.mIndex = index; } + // 获取列表索引 public int getIndex() { return this.mIndex; }