冯一安 2 weeks ago
parent 8828ec4899
commit 7ed71fe5ba

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,125 +0,0 @@
//开源许可证声明
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//声明了当前Java文件所属的包名。包名用于组织和管理Java类避免命名冲突。
package net.micode.notes.gtask.data;
//导入Android系统提供的Cursor类用于数据库查询操作。
import android.database.Cursor;
import android.util.Log;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
//定义了一个名为MetaData的类它继承自Task类。
//这个类主要用于处理与任务相关的元数据包括设置元数据、获取相关任务ID、判断是否需要保存以及根据远程JSON和本地JSON设置内容等操作。
public class MetaData extends Task {
// 定义一个常量,用于日志输出
private final static String TAG = MetaData.class.getSimpleName();
// 定义一个私有变量用于存储相关任务ID
private String mRelatedGid = null;
// 设置元数据
public void setMeta(String gid, JSONObject metaInfo) {
try {
// 将相关任务ID添加到元数据中添加到JSON对象中用于存储元数据
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
} catch (JSONException e) {
// 日志输出错误信息
Log.e(TAG, "failed to put related gid");
}
// 设置备注
setNotes(metaInfo.toString());
// 设置名称
setName(GTaskStringUtils.META_NOTE_NAME);
}
// 获取相关任务的全局唯一标识符GID
public String getRelatedGid() {
// 返回存储的相关任务ID
return mRelatedGid;
}
// 判断是否需要保存
//重写父类方法,用于判断当前元数据是否值得保存。
@Override
public boolean isWorthSaving() {
//如果备注信息不为 null则认为该元数据有保存的价值返回 true
// 反之,如果备注信息为 null则返回 false
return getNotes() != null;
}
// 根据远程JSONObject设置对象的内容
//重写父类方法用于根据远程JSON设置内容。
//该方法首先调用父类的方法然后尝试解析备注信息提取相关任务ID。
@Override//此注解表明该方法重写了父类 Task 中的 setContentByRemoteJSON 方法。
//Java 编译器会检查父类是否存在同名同参数的方法,若不存在则会报错。
//参数js远程JSON对象包含任务的元数据信息。
public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js);
// 调用父类 Task 的 setContentByRemoteJSON 方法,先让父类处理远程的 JSONObject完成一些基础的内容设置操作。
if (getNotes() != null) {
//检查当前对象的备注信息是否不为 null。只有备注信息存在时才会尝试从中提取相关任务的 GID。
// 这是因为在 Google Task 中,元数据通常存储在备注信息中,而不是单独的字段。
try {
// 将备注转换为JSON对象
JSONObject metaInfo = new JSONObject(getNotes().trim());
//把备注信息去除首尾空格后转换为 JSONObject 对象。这样做是为了确保备注信息格式正确,能被 JSONObject 解析。
//trim() 方法用于去除字符串两端的空白字符(包括空格、制表符、换行符等)。
//getNotes() 方法返回当前对象的备注信息字符串。
//new JSONObject(getNotes().trim()) 将备注信息转换为 JSON 对象。
// 获取相关任务ID
mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID);
//从 JSON 对象中获取相关任务的 GID。
//metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID):从 JSON 对象中获取名为 META_HEAD_GTASK_ID 的键值。
//GTaskStringUtils.META_HEAD_GTASK_ID一个常量字符串表示 JSON 对象中存储相关任务 ID 的键名。
//mRelatedGid一个字符串变量用于存储从 JSON 对象中获取到的相关任务 ID。
} catch (JSONException e) {
// 日志输出警告信息
Log.w(TAG, "failed to get related gid");
// 将相关任务ID设置为null
mRelatedGid = null;
}
}
}
// 根据本地JSON设置内容
@Override//注解,表明当前方法重写了父类中的同名方法
public void setContentByLocalJSON(JSONObject js) {
// this function should not be called
// 抛出一个IllegalAccessError异常提示该方法不应该被调用。
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
}
// 从内容中获取本地JSON
@Override
public JSONObject getLocalJSONFromContent() {
// 抛出一个IllegalAccessError异常提示该方法不应该被调用。
throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called");
}
// 获取同步操作
@Override
public int getSyncAction(Cursor c) {
// 抛出一个IllegalAccessError异常提示该方法不应该被调用。
throw new IllegalAccessError("MetaData:getSyncAction should not be called");
}
}

@ -1,101 +0,0 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
import android.database.Cursor;
import org.json.JSONObject;
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;
public static final int SYNC_ACTION_DEL_REMOTE = 3;
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_ERROR = 8;
private String mGid;
private String mName;
private long mLastModified;
private boolean mDeleted;
public Node() {
mGid = null;
mName = "";
mLastModified = 0;
mDeleted = false;
}
public abstract JSONObject getCreateAction(int actionId);
public abstract JSONObject getUpdateAction(int actionId);
public abstract void setContentByRemoteJSON(JSONObject js);
public abstract void setContentByLocalJSON(JSONObject js);
public abstract JSONObject getLocalJSONFromContent();
public abstract int getSyncAction(Cursor c);
public void setGid(String gid) {
this.mGid = gid;
}
public void setName(String name) {
this.mName = name;
}
public void setLastModified(long lastModified) {
this.mLastModified = lastModified;
}
public void setDeleted(boolean deleted) {
this.mDeleted = deleted;
}
public String getGid() {
return this.mGid;
}
public String getName() {
return this.mName;
}
public long getLastModified() {
return this.mLastModified;
}
public boolean getDeleted() {
return this.mDeleted;
}
}

@ -1,270 +0,0 @@
//开源许可证声明
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//声明了当前Java文件所属的包名。包名用于组织和管理Java类避免命名冲突。
package net.micode.notes.gtask.data;
//
import android.content.ContentResolver;//用于与内容提供者进行交互执行CRUD创建、读取、更新、删除操作。
import android.content.ContentUris;//用于构建URI支持通过URI访问和操作数据。
import android.content.ContentValues;//用于存储和操作键值对数据。
import android.content.Context;//提供应用程序上下文信息,用于访问系统服务和资源。
import android.database.Cursor;//用于遍历和操作数据库中的数据行。
import android.net.Uri;//用于表示URI支持通过URI访问和操作数据。
import android.util.Log;//用于输出日志信息,方便调试和跟踪。
import net.micode.notes.data.Notes;//表示小米便签应用中的Notes类用于访问和操作便签数据。
import net.micode.notes.data.Notes.DataColumns;//定义了Notes类中的数据列用于访问和操作便签数据。
import net.micode.notes.data.Notes.DataConstants;//定义了Notes类中的常量用于访问和操作便签数据。
import net.micode.notes.data.Notes.NoteColumns;//定义了Notes类中的数据列用于访问和操作便签数据。
import net.micode.notes.data.NotesDatabaseHelper.TABLE;//表示小米便签应用中的NotesDatabaseHelper类用于访问和操作便签数据。
import net.micode.notes.gtask.exception.ActionFailureException;//表示小米便签应用中的ActionFailureException类用于处理操作失败的情况。
import org.json.JSONException;//用于处理JSON解析和操作中的异常。
import org.json.JSONObject;//用于表示JSON对象支持通过键值对存储和操作数据。
public class SqlData {
// 定义一个常量TAG用于标识类的简单名称
private static final String TAG = SqlData.class.getSimpleName();
// 定义一个常量INVALID_ID用于标识无效的ID
private static final int INVALID_ID = -99999;
// 定义一个常量PROJECTION_DATA用于存储数据的列名
public static final String[] PROJECTION_DATA = new String[] {//列名常量列表
DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
DataColumns.DATA3
};
// 定义一个常量DATA_ID_COLUMN用于标识数据的ID列
public static final int DATA_ID_COLUMN = 0;
// 定义一个常量DATA_MIME_TYPE_COLUMN用于标识数据的MIME类型列
public static final int DATA_MIME_TYPE_COLUMN = 1;
// 定义一个常量DATA_CONTENT_COLUMN用于标识数据的CONTENT列
public static final int DATA_CONTENT_COLUMN = 2;
// 定义一个常量DATA_CONTENT_DATA_1_COLUMN用于标识数据的DATA1列
public static final int DATA_CONTENT_DATA_1_COLUMN = 3;
// 定义一个常量DATA_CONTENT_DATA_3_COLUMN用于标识数据的DATA3列
public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
// 定义一个ContentResolver对象mContentResolver用于访问内容提供者
private ContentResolver mContentResolver;
// 定义一个布尔值mIsCreate用于标识是否创建
private boolean mIsCreate;
// 定义一个长整型变量mDataId用于存储数据的ID
private long mDataId;
// 定义一个字符串变量mDataMimeType用于存储数据的MIME类型
private String mDataMimeType;
// 定义一个字符串变量mDataContent用于存储数据的CONTENT
private String mDataContent;
// 定义一个长整型变量mDataContentData1用于存储数据的DATA1
private long mDataContentData1;
// 定义一个字符串变量mDataContentData3用于存储数据的DATA3
private String mDataContentData3;
// 定义一个ContentValues对象mDiffDataValues用于存储数据的差异
private ContentValues mDiffDataValues;
// 构造函数创建并初始化SqlData对象
public SqlData(Context context) {
// 获取ContentResolver对象ContentResolver用于访问Android系统中的内容提供者
mContentResolver = context.getContentResolver();
// 设置mIsCreate为true表示正在创建新的数据
mIsCreate = true;
// 设置mDataId为INVALID_ID表示数据ID无效
mDataId = INVALID_ID;
// 设置mDataMimeType为DataConstants.NOTE表示数据类型为Note
mDataMimeType = DataConstants.NOTE;
// 设置mDataContent为空字符串可能用于存储数据内容。
mDataContent = "";
// 设置mDataContentData1为0可能用于存储数据的其他信息。
mDataContentData1 = 0;
// 设置mDataContentData3为空字符串可能用于存储数据的其他信息。
mDataContentData3 = "";
// 初始化mDiffDataValues为ContentValues对象用于存储数据的变化。
mDiffDataValues = new ContentValues();
}
// 构造函数用于从Cursor中加载数据
public SqlData(Context context, Cursor c) {
// 获取ContentResolver对象ContentResolver用于访问Android系统中的内容提供者
mContentResolver = context.getContentResolver();
// 设置mIsCreate为false表示数据已经存在
mIsCreate = false;
// 从Cursor中加载数据
loadFromCursor(c);
// 初始化mDiffDataValues为ContentValues对象用于存储数据的变化。
mDiffDataValues = new ContentValues();
}
// 从Cursor中加载数据
private void loadFromCursor(Cursor c) {
// 从 Cursor 中获取数据的 ID 列的值,并赋值给成员变量 mDataId
mDataId = c.getLong(DATA_ID_COLUMN);
// 获取数据类型 从 Cursor 中获取数据的 MIME 类型列的值,并赋值给成员变量 mDataMimeType
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
// 获取数据内容 从 Cursor 中获取数据的 CONTENT 列的值,并赋值给成员变量 mDataContent
mDataContent = c.getString(DATA_CONTENT_COLUMN);
// 获取数据的其他信息 从 Cursor 中获取数据的 DATA1 列的值,并赋值给成员变量 mDataContentData1
mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN);
// 获取数据的其他信息 从 Cursor 中获取数据的 DATA3 列的值,并赋值给成员变量 mDataContentData3
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
// 设置数据
//根据传入的 JSON 对象设置 SqlData 实例的内容,并记录数据的差异。
//该方法会从 JSON 对象中提取数据的各个字段(如 ID、MIME 类型、内容等),
// 并将其赋值给当前实例的成员变量。如果数据正在创建或者与当前值不同,则将这些差异记录到 mDiffDataValues 中,以便后续提交到数据库。
public void setContent(JSONObject js) throws JSONException {
// 获取数据ID 从 JSON 对象中获取数据的 ID 列的值,并赋值给变量 dataId
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
// 如果正在创建数据或者数据ID不匹配则将数据ID添加到 mDiffDataValues 中
if (mIsCreate || mDataId != dataId) {
mDiffDataValues.put(DataColumns.ID, dataId);
}
// 更新当前实例数据ID 将变量 dataId 的值赋值给成员变量 mDataId
mDataId = dataId;
// 获取数据类型 从 JSON 对象中获取数据的 MIME 类型列的值,并赋值给变量 dataMimeType
String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE)
: DataConstants.NOTE;
// 如果正在创建数据或者数据类型不匹配,则将数据类型添加到 mDiffDataValues 中
if (mIsCreate || !mDataMimeType.equals(dataMimeType)) {
mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType);
}
// 更新当前实例数据类型 将变量 dataMimeType 的值赋值给成员变量 mDataMimeType
mDataMimeType = dataMimeType;
// 获取数据内容 从 JSON 对象中获取数据的 CONTENT 列的值,并赋值给变量 dataContent
String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : "";
// 如果正在创建数据或者数据内容不匹配,则将数据内容添加到 mDiffDataValues 中
if (mIsCreate || !mDataContent.equals(dataContent)) {
mDiffDataValues.put(DataColumns.CONTENT, dataContent);
}
// 更新数据内容 将变量 dataContent 的值赋值给成员变量 mDataContent
mDataContent = dataContent;
// 获取数据的其他信息 从 JSON 对象中获取数据的 DATA1 列的值,并赋值给变量 dataContentData1
long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0;
// 如果正在创建数据或者数据的其他信息不匹配,则将数据的其他信息添加到 mDiffDataValues 中
if (mIsCreate || mDataContentData1 != dataContentData1) {
mDiffDataValues.put(DataColumns.DATA1, dataContentData1);
}
// 更新当前实例数据的其他信息 将变量 dataContentData1 的值赋值给成员变量 mDataContentData1
mDataContentData1 = dataContentData1;
// 获取数据的其他信息 从 JSON 对象中获取数据的 DATA3 列的值,并赋值给变量 dataContentData3
String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : "";
// 如果正在创建数据或者数据的其他信息不匹配,则将数据的其他信息添加到 mDiffDataValues 中
if (mIsCreate || !mDataContentData3.equals(dataContentData3)) {
mDiffDataValues.put(DataColumns.DATA3, dataContentData3);
}
// 更新当前实例数据的其他信息 将变量 dataContentData3 的值赋值给成员变量 mDataContentData3
mDataContentData3 = dataContentData3;
}
// 获取内容
public JSONObject getContent() throws JSONException {
// 如果mIsCreate为true说明还没有在数据库中创建
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
// 创建一个JSONObject对象并填充数据
JSONObject js = new JSONObject();
// 将mDataId放入JSONObject中
js.put(DataColumns.ID, mDataId);
// 将mDataMimeType放入JSONObject中
js.put(DataColumns.MIME_TYPE, mDataMimeType);
// 将mDataContent放入JSONObject中
js.put(DataColumns.CONTENT, mDataContent);
// 将mDataContentData1放入JSONObject中
js.put(DataColumns.DATA1, mDataContentData1);
// 将mDataContentData3放入JSONObject中
js.put(DataColumns.DATA3, mDataContentData3);
// 返回JSONObject对象
return js;
}
// 提交数据
public void commit(long noteId, boolean validateVersion, long version) {
// 如果是创建
if (mIsCreate) {
// 如果数据ID无效且数据值中包含ID列
if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
// 移除ID列
mDiffDataValues.remove(DataColumns.ID);
}
// 添加NOTE_ID列
mDiffDataValues.put(DataColumns.NOTE_ID, noteId);
// 插入数据
Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);
try {
// 获取数据ID
mDataId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
// 打印错误日志
Log.e(TAG, "Get note id error :" + e.toString());
// 抛出异常
throw new ActionFailureException("create note failed");
}
} else {
// 如果数据值不为空
if (mDiffDataValues.size() > 0) {
// 更新结果
int result = 0;
// 如果不验证版本
if (!validateVersion) {
// 更新数据
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);
} else {
// 更新数据,验证版本
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues,
" ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.VERSION + "=?)", new String[] {
String.valueOf(noteId), String.valueOf(version)
});
}
// 如果更新结果为0
if (result == 0) {
// 打印警告日志
Log.w(TAG, "there is no update. maybe user updates note when syncing");
}
}
}
// 清空数据值
mDiffDataValues.clear();
// 设置为非创建
mIsCreate = false;
}
// 获取数据ID
public long getId() {
return mDataId;
}
}

@ -1,672 +0,0 @@
//开源许可证
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import net.micode.notes.tool.ResourceParser;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
// 该类用于表示一个便签,并提供便签的创建、更新、提交等操作。
public class SqlNote {
// 定义日志标签
private static final String TAG = SqlNote.class.getSimpleName();
// 定义无效ID
private static final int INVALID_ID = -99999;
// 定义Note表的列名
public static final String[] PROJECTION_NOTE = new String[] {
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
};
// 定义Note表的列索引
public static final int ID_COLUMN = 0;
public static final int ALERTED_DATE_COLUMN = 1;
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;
public static final int PARENT_ID_COLUMN = 7;
public static final int SNIPPET_COLUMN = 8;
public static final int TYPE_COLUMN = 9;
public static final int WIDGET_ID_COLUMN = 10;
public static final int WIDGET_TYPE_COLUMN = 11;
public static final int SYNC_ID_COLUMN = 12;
public static final int LOCAL_MODIFIED_COLUMN = 13;
public static final int ORIGIN_PARENT_ID_COLUMN = 14;
public static final int GTASK_ID_COLUMN = 15;
public static final int VERSION_COLUMN = 16;
private Context mContext;
private ContentResolver mContentResolver;
private boolean mIsCreate;
private long mId;
private long mAlertDate;
private int mBgColorId;
private long mCreatedDate;
private int mHasAttachment;
private long mModifiedDate;
private long mParentId;
private String mSnippet;
private int mType;
private int mWidgetId;
private int mWidgetType;
private long mOriginParent;
private long mVersion;
private ContentValues mDiffNoteValues;
private ArrayList<SqlData> mDataList;
// 构造函数初始化SqlNote对象
public SqlNote(Context context) {
// 保存上下文
mContext = context;
// 获取ContentResolver
mContentResolver = context.getContentResolver();
// 标记为创建
mIsCreate = true;
// 初始化ID为无效ID
mId = INVALID_ID;
// 初始化提醒日期为0
mAlertDate = 0;
// 获取默认背景颜色ID
mBgColorId = ResourceParser.getDefaultBgId(context);
// 获取当前时间作为创建日期
mCreatedDate = System.currentTimeMillis();
// 初始化是否有附件为0
mHasAttachment = 0;
// 获取当前时间作为修改日期
mModifiedDate = System.currentTimeMillis();
// 初始化父ID为0
mParentId = 0;
// 初始化片段为空字符串
mSnippet = "";
// 初始化类型为笔记
mType = Notes.TYPE_NOTE;
// 初始化小部件ID为无效ID
mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
// 初始化小部件类型为无效类型
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
// 初始化原始父ID为0
mOriginParent = 0;
// 初始化版本号为0
mVersion = 0;
// 初始化ContentValues对象
mDiffNoteValues = new ContentValues();
// 初始化数据列表
mDataList = new ArrayList<SqlData>();
}
// 构造函数用于从Cursor中加载SqlNote对象
public SqlNote(Context context, Cursor c) {
// 保存上下文
mContext = context;
// 获取ContentResolver
mContentResolver = context.getContentResolver();
// 标记为未创建
mIsCreate = false;
// 从Cursor中加载SqlNote对象
loadFromCursor(c);
// 初始化数据列表
mDataList = new ArrayList<SqlData>();
// 如果类型为Notes.TYPE_NOTE则加载内容
if (mType == Notes.TYPE_NOTE)
loadDataContent();
// 初始化ContentValues
mDiffNoteValues = new ContentValues();
}
// 构造函数传入上下文和id
public SqlNote(Context context, long id) {
// 保存上下文
mContext = context;
// 获取内容解析器
mContentResolver = context.getContentResolver();
// 标记为未创建
mIsCreate = false;
// 从游标中加载
loadFromCursor(id);
// 创建数据列表
mDataList = new ArrayList<SqlData>();
// 如果类型为笔记,加载内容
if (mType == Notes.TYPE_NOTE)
loadDataContent();
// 创建内容值
mDiffNoteValues = new ContentValues();
}
// 从游标中加载数据
private void loadFromCursor(long id) {
// 声明游标变量
Cursor c = null;
try {
// 从ContentResolver中查询数据
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)",
new String[] {
String.valueOf(id)
}, null);
// 如果游标不为空
if (c != null) {
// 将游标移动到下一行
c.moveToNext();
// 从游标中加载数据
loadFromCursor(c);
} else {
// 如果游标为空,则输出警告日志
Log.w(TAG, "loadFromCursor: cursor = null");
}
} finally {
// 关闭游标
if (c != null)
c.close();
}
}
// 从游标中加载数据
private void loadFromCursor(Cursor c) {
// 获取ID
mId = c.getLong(ID_COLUMN);
// 获取提醒日期
mAlertDate = c.getLong(ALERTED_DATE_COLUMN);
// 获取背景颜色ID
mBgColorId = c.getInt(BG_COLOR_ID_COLUMN);
// 获取创建日期
mCreatedDate = c.getLong(CREATED_DATE_COLUMN);
// 获取是否有附件
mHasAttachment = c.getInt(HAS_ATTACHMENT_COLUMN);
// 获取修改日期
mModifiedDate = c.getLong(MODIFIED_DATE_COLUMN);
// 获取父ID
mParentId = c.getLong(PARENT_ID_COLUMN);
// 获取片段
mSnippet = c.getString(SNIPPET_COLUMN);
// 获取类型
mType = c.getInt(TYPE_COLUMN);
// 获取小部件ID
mWidgetId = c.getInt(WIDGET_ID_COLUMN);
// 获取小部件类型
mWidgetType = c.getInt(WIDGET_TYPE_COLUMN);
// 获取版本
mVersion = c.getLong(VERSION_COLUMN);
}
// 加载数据内容
private void loadDataContent() {
// 声明游标
Cursor c = null;
// 清空数据列表
mDataList.clear();
try {
// 查询数据
c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA,
"(note_id=?)", new String[] {
String.valueOf(mId)
}, null);
// 如果游标不为空
if (c != null) {
// 如果游标中没有数据
if (c.getCount() == 0) {
// 打印警告日志
Log.w(TAG, "it seems that the note has not data");
return;
}
// 遍历游标
while (c.moveToNext()) {
// 创建SqlData对象
SqlData data = new SqlData(mContext, c);
// 将数据添加到数据列表中
mDataList.add(data);
}
} else {
// 打印警告日志
Log.w(TAG, "loadDataContent: cursor = null");
}
} finally {
// 关闭游标
if (c != null)
c.close();
}
}
// 设置内容
public boolean setContent(JSONObject js) {
try {
// 获取note对象该对象包含便签的基本信息
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
// 如果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) {
// for folder we can only update the snnipet and type 对于文件夹,我们只能更新片段和类型
// 从 JSON 对象中获取片段信息,如果不存在则使用空字符串
String snippet = note.has(NoteColumns.SNIPPET) ? note
.getString(NoteColumns.SNIPPET) : "";
// 如果是新建便签或者片段信息发生变化,则将新的片段信息添加到差异值中
if (mIsCreate || !mSnippet.equals(snippet)) {
mDiffNoteValues.put(NoteColumns.SNIPPET, 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);
}
// 更新当前实例的类型
mType = type;
} else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) {
// 获取数据数组
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
// 从 JSON 对象中获取便签 ID如果不存在则使用无效 ID
long id = note.has(NoteColumns.ID) ? note.getLong(NoteColumns.ID) : INVALID_ID;
// 如果是新建便签或者ID发生变化则将新的ID添加到差异值中
if (mIsCreate || mId != id) {
mDiffNoteValues.put(NoteColumns.ID, id);
}
// 更新当前实例的便签 ID
mId = id;
// 从 JSON 对象中获取提醒日期如果不存在则使用0
long alertDate = note.has(NoteColumns.ALERTED_DATE)? note
.getLong(NoteColumns.ALERTED_DATE) : 0;
// 如果是新建便签或者提醒日期发生变化,则将新的提醒日期添加到差异值中
if (mIsCreate || mAlertDate != alertDate) {
mDiffNoteValues.put(NoteColumns.ALERTED_DATE, alertDate);
}
// 更新当前实例的提醒日期
mAlertDate = alertDate;
// 从 JSON 对象中获取背景颜色 ID如果不存在则使用默认背景颜色 ID
int bgColorId = note.has(NoteColumns.BG_COLOR_ID)? note
.getInt(NoteColumns.BG_COLOR_ID) : ResourceParser.getDefaultBgId(mContext);
// 如果是新建便签或者背景颜色 ID 发生变化,则将新的背景颜色 ID 添加到差异值中
if (mIsCreate || mBgColorId != bgColorId) {
mDiffNoteValues.put(NoteColumns.BG_COLOR_ID, bgColorId);
}
// 更新当前实例的背景颜色 ID
mBgColorId = bgColorId;
// 从 JSON 对象中获取创建日期,如果不存在则使用当前时间
long createDate = note.has(NoteColumns.CREATED_DATE) ? note
.getLong(NoteColumns.CREATED_DATE) : System.currentTimeMillis();
// 如果是新建便签或者创建日期发生变化,则将新的创建日期添加到差异值中
if (mIsCreate || mCreatedDate != createDate) {
mDiffNoteValues.put(NoteColumns.CREATED_DATE, createDate);
}
// 更新当前实例的创建日期
mCreatedDate = createDate;
// 从 JSON 对象中获取是否有附件,如果不存在则使用默认值 0
int hasAttachment = note.has(NoteColumns.HAS_ATTACHMENT) ? note
.getInt(NoteColumns.HAS_ATTACHMENT) : 0;
// 如果是新建便签或者是否有附件发生变化,则将新的是否有附件值添加到差异值中
if (mIsCreate || mHasAttachment != hasAttachment) {
mDiffNoteValues.put(NoteColumns.HAS_ATTACHMENT, hasAttachment);
}
// 更新当前实例的是否有附件
mHasAttachment = hasAttachment;
// 从 JSON 对象中获取最后修改日期,如果不存在则使用当前时间
long modifiedDate = note.has(NoteColumns.MODIFIED_DATE) ? note
.getLong(NoteColumns.MODIFIED_DATE) : System.currentTimeMillis();
// 如果是新建便签或者最后修改日期发生变化,则将新的最后修改日期添加到差异值中
if (mIsCreate || mModifiedDate != modifiedDate) {
mDiffNoteValues.put(NoteColumns.MODIFIED_DATE, modifiedDate);
}
// 更新当前实例的最后修改日期
mModifiedDate = modifiedDate;
// 从 JSON 对象中获取父便签 ID如果不存在则使用默认值 0
long parentId = note.has(NoteColumns.PARENT_ID) ? note
.getLong(NoteColumns.PARENT_ID) : 0;
// 如果是新建便签或者父便签 ID 发生变化,则将新的父便签 ID 添加到差异值中
if (mIsCreate || mParentId != parentId) {
mDiffNoteValues.put(NoteColumns.PARENT_ID, parentId);
}
// 更新当前实例的父便签 ID
mParentId = parentId;
// 从 JSON 对象中获取是否删除,如果不存在则使用默认值 false
String snippet = note.has(NoteColumns.SNIPPET) ? note
.getString(NoteColumns.SNIPPET) : "";
// 如果是新建便签或者便签内容发生变化,则将新的便签内容添加到差异值中
if (mIsCreate || !mSnippet.equals(snippet)) {
mDiffNoteValues.put(NoteColumns.SNIPPET, snippet);
}
// 更新当前实例的便签内容
mSnippet = snippet;
// 从 JSON 对象中获取便签类型,如果不存在则使用默认值 1
int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE)
: Notes.TYPE_NOTE;
// 如果是新建便签或者便签类型发生变化,则将新的便签类型添加到差异值中
if (mIsCreate || mType != type) {
mDiffNoteValues.put(NoteColumns.TYPE, type);
}
// 更新当前实例的便签类型
mType = type;
// 从 JSON 对象中获取是否删除,如果不存在则使用默认值 false
int widgetId = note.has(NoteColumns.WIDGET_ID) ? note.getInt(NoteColumns.WIDGET_ID)
: AppWidgetManager.INVALID_APPWIDGET_ID;
// 如果是新建便签或者便签的 widgetId 发生变化,则将新的 widgetId 添加到差异值中
if (mIsCreate || mWidgetId != widgetId) {
mDiffNoteValues.put(NoteColumns.WIDGET_ID, widgetId);
}
// 更新当前实例的 widgetId
mWidgetId = widgetId;
// 从 JSON 对象中获取是否删除,如果不存在则使用默认值 false
int widgetType = note.has(NoteColumns.WIDGET_TYPE) ? note
.getInt(NoteColumns.WIDGET_TYPE) : Notes.TYPE_WIDGET_INVALIDE;
// 如果是新建便签或者便签的 widgetType 发生变化,则将新的 widgetType 添加到差异值中
if (mIsCreate || mWidgetType != widgetType) {
mDiffNoteValues.put(NoteColumns.WIDGET_TYPE, widgetType);
}
// 更新当前实例的 widgetType
mWidgetType = widgetType;
// 从 JSON 对象中获取是否删除,如果不存在则使用默认值 false
long originParent = note.has(NoteColumns.ORIGIN_PARENT_ID) ? note
.getLong(NoteColumns.ORIGIN_PARENT_ID) : 0;
// 如果是新建便签或者便签的 originParent 发生变化,则将新的 originParent 添加到差异值中
if (mIsCreate || mOriginParent != originParent) {
mDiffNoteValues.put(NoteColumns.ORIGIN_PARENT_ID, originParent);
}
// 更新当前实例的 originParent
mOriginParent = originParent;
// 从 JSON 对象中获取是否删除,如果不存在则使用默认值 false
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
SqlData sqlData = null;
// 如果是新建便签或者 data 列表为空,则创建新的 SqlData 对象
if (data.has(DataColumns.ID)) {
// 如果 data 列表不为空,则查找是否已经存在相同 ID 的 SqlData 对象
long dataId = data.getLong(DataColumns.ID);
for (SqlData temp : mDataList) {
if (dataId == temp.getId()) {
sqlData = temp;
}
}
}
// 如果 sqlData 为空,则创建新的 SqlData 对象
if (sqlData == null) {
sqlData = new SqlData(mContext);
mDataList.add(sqlData);
}
// 设置 SqlData 对象的内容
sqlData.setContent(data);
}
}
} catch (JSONException e) {
// 捕获 JSON 解析异常,输出错误日志并打印堆栈信息
Log.e(TAG, e.toString());
e.printStackTrace();
// 解析失败,返回 false
return false;
}
// 解析成功,返回 true
return true;
}
// 获取内容
public JSONObject getContent() {
try {
// 创建一个JSONObject对象
JSONObject js = new JSONObject();
// 如果mIsCreate为true说明还没有在数据库中创建
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
// 创建一个JSONObject对象用于存储note
JSONObject note = new JSONObject();
// 如果mType为Notes.TYPE_NOTE说明是笔记类型
if (mType == Notes.TYPE_NOTE) {
// 将note的各个属性放入JSONObject中
note.put(NoteColumns.ID, mId);
note.put(NoteColumns.ALERTED_DATE, mAlertDate);
note.put(NoteColumns.BG_COLOR_ID, mBgColorId);
note.put(NoteColumns.CREATED_DATE, mCreatedDate);
note.put(NoteColumns.HAS_ATTACHMENT, mHasAttachment);
note.put(NoteColumns.MODIFIED_DATE, mModifiedDate);
note.put(NoteColumns.PARENT_ID, mParentId);
note.put(NoteColumns.SNIPPET, mSnippet);
note.put(NoteColumns.TYPE, mType);
note.put(NoteColumns.WIDGET_ID, mWidgetId);
note.put(NoteColumns.WIDGET_TYPE, mWidgetType);
note.put(NoteColumns.ORIGIN_PARENT_ID, mOriginParent);
// 将note放入JSONObject中
js.put(GTaskStringUtils.META_HEAD_NOTE, note);
// 创建一个JSONArray对象用于存储data
JSONArray dataArray = new JSONArray();
// 遍历mDataList
for (SqlData sqlData : mDataList) {
// 获取sqlData的内容
JSONObject data = sqlData.getContent();
// 如果data不为空则将其放入dataArray中
if (data != null) {
dataArray.put(data);
}
}
// 将dataArray放入JSONObject中
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
// 如果mType为Notes.TYPE_FOLDER或Notes.TYPE_SYSTEM说明是文件夹或系统类型
} else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) {
// 将note的各个属性放入JSONObject中
note.put(NoteColumns.ID, mId);
note.put(NoteColumns.TYPE, mType);
note.put(NoteColumns.SNIPPET, mSnippet);
// 将note放入JSONObject中
js.put(GTaskStringUtils.META_HEAD_NOTE, note);
}
// 返回JSONObject
return js;
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
return null;
}
// 设置父节点ID
public void setParentId(long id) {
// 将父节点ID赋值给mParentId
mParentId = id;
// 将父节点ID添加到mDiffNoteValues中
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
}
// 设置GtaskId
public void setGtaskId(String gid) {
// 将GtaskId放入mDiffNoteValues中
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
}
// 设置同步ID
public void setSyncId(long syncId) {
// 将同步ID放入DiffNoteValues中
mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId);
}
// 重置本地修改
public void resetLocalModified() {
// 将NoteColumns.LOCAL_MODIFIED对应的值设置为0
mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0);
}
// 获取ID
public long getId() {
// 返回ID
return mId;
}
// 获取父节点ID
public long getParentId() {
return mParentId;
}
// 获取片段
public String getSnippet() {
// 返回mSnippet
return mSnippet;
}
// 判断当前类型是否为笔记类型
public boolean isNoteType() {
// 如果mType等于Notes.TYPE_NOTE则返回true否则返回false
return mType == Notes.TYPE_NOTE;
}
public void commit(boolean validateVersion) {
// 如果是创建
if (mIsCreate) {
// 如果id为无效id且mDiffNoteValues中包含NoteColumns.ID
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {
// 从mDiffNoteValues中移除NoteColumns.ID
mDiffNoteValues.remove(NoteColumns.ID);
}
// 插入数据到Notes.CONTENT_NOTE_URI
Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues);
try {
// 获取插入数据的id
mId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
// 如果获取id失败打印错误日志并抛出ActionFailureException
Log.e(TAG, "Get note id error :" + e.toString());
throw new ActionFailureException("create note failed");
}
// 如果id为0抛出IllegalStateException
if (mId == 0) {
throw new IllegalStateException("Create thread id failed");
}
// 如果类型为Notes.TYPE_NOTE
if (mType == Notes.TYPE_NOTE) {
// 遍历mDataList调用commit方法
for (SqlData sqlData : mDataList) {
sqlData.commit(mId, false, -1);
}
}
} else {
// 如果id小于等于0且id不是Notes.ID_ROOT_FOLDER和Notes.ID_CALL_RECORD_FOLDER
if (mId <= 0 && mId != Notes.ID_ROOT_FOLDER && mId != Notes.ID_CALL_RECORD_FOLDER) {
// 打印错误日志并抛出IllegalStateException
Log.e(TAG, "No such note");
throw new IllegalStateException("Try to update note with invalid id");
}
// 如果mDiffNoteValues不为空
if (mDiffNoteValues.size() > 0) {
// 版本号加1
mVersion ++;
int result = 0;
// 如果不验证版本号
if (!validateVersion) {
// 更新数据
result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "("
+ 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)
});
}
// 如果没有更新,打印警告日志
if (result == 0) {
Log.w(TAG, "there is no update. maybe user updates note when syncing");
}
}
// 如果类型为Notes.TYPE_NOTE
if (mType == Notes.TYPE_NOTE) {
// 遍历mDataList调用commit方法
for (SqlData sqlData : mDataList) {
sqlData.commit(mId, validateVersion, mVersion);
}
}
}
// refresh local info刷新本地信息从数据库中重新加载当前便签的基本信息
loadFromCursor(mId);
// 根据当前便签的 ID 从数据库中查询并更新当前对象的属性
if (mType == Notes.TYPE_NOTE)// 如果当前便签的类型是笔记类型
// 加载该笔记的数据内容,将相关的数据信息从数据库中读取并更新到 mDataList 中
loadDataContent();
// 清空记录便签属性差异的 ContentValues 对象
mDiffNoteValues.clear();
// 将创建标志设置为 false表示该便签已经在数据库中存在不是新建状态
mIsCreate = false;
}
}

@ -1,441 +0,0 @@
//开源许可协议声明
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//类说明
package net.micode.notes.gtask.data;
//导入Android系统提供的Cursor类用于数据库查询操作。Cursor类表示数据库查询结果集可以用来遍历查询结果。
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Task extends Node {
// 定义一个常量,用于打印日志
private static final String TAG = Task.class.getSimpleName();
// 定义一个布尔变量,表示任务是否完成
private boolean mCompleted;
// 定义一个字符串变量,用于存储任务的备注
private String mNotes;
// 定义一个JSONObject变量用于存储任务的元信息
private JSONObject mMetaInfo;
// 定义一个Task变量用于存储任务的前一个兄弟任务
private Task mPriorSibling;
// 定义一个TaskList变量用于存储任务的父任务列表
private TaskList mParent;
// 构造函数,初始化任务
public Task() {
super();
mCompleted = false;
mNotes = null;
mPriorSibling = null;
mParent = null;
mMetaInfo = null;
}
// 获取创建任务的JSON对象
public JSONObject getCreateAction(int actionId) {
// 创建一个JSONObject对象
JSONObject js = new JSONObject();
try {
// action_type
// 将action_type设置为create
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// action_id
// 将action_id设置为传入的参数
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// index
// 将index设置为父任务的子任务索引
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this));
// entity_delta
// 创建一个JSONObject对象用于存储任务信息
JSONObject entity = new JSONObject();
// 将任务名称放入entity中
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
// 将创建者ID放入entity中
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
// 将任务类型放入entity中
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_TASK);
// 如果任务有备注则将备注放入entity中
if (getNotes() != null) {
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
}
// 将entity放入js中
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
// parent_id
// 将父任务的GID放入js中
js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid());
// dest_parent_type
// 将目标父任务类型设置为group
js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
// list_id
// 将父任务的GID放入js中
js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid());
// prior_sibling_id
// 如果有前一个兄弟任务则将前一个兄弟任务的GID放入js中
if (mPriorSibling != null) {
js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid());
}
} catch (JSONException e) {
// 如果发生JSONException则打印错误日志并抛出ActionFailureException异常
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate task-create jsonobject");
}
// 返回JSONObject对象
return js;
}
// 获取更新任务的JSON对象
public JSONObject getUpdateAction(int actionId) {
// 创建一个JSONObject对象
JSONObject js = new JSONObject();
try {
// action_type
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// action_id
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// id
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// entity_delta
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
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);
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate task-update jsonobject");
}
return js;
}
// 根据远程JSON设置任务内容
public void setContentByRemoteJSON(JSONObject js) {
// 根据远程JSON设置内容
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
// 设置id
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// last_modified
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
// 设置最后修改时间
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// name
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
// 设置名称
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
// notes
if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) {
// 设置备注
setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES));
}
// deleted
if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) {
// 设置是否删除
setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED));
}
// completed
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");
}
}
}
// 根据本地JSON设置任务内容
public void setContentByLocalJSON(JSONObject js) {
// 如果JSON为空或者没有META_HEAD_NOTE或META_HEAD_DATA字段则打印警告日志
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
try {
// 获取META_HEAD_NOTE字段对应的JSONObject
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
// 如果note的类型不是Notes.TYPE_NOTE则打印错误日志并返回
if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) {
Log.e(TAG, "invalid type");
return;
}
// 遍历dataArray中的每个JSONObject
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
// 如果data的MIME_TYPE字段为DataConstants.NOTE则设置name字段为data的CONTENT字段
if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) {
setName(data.getString(DataColumns.CONTENT));
break;
}
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
// 获取本地JSON对象
public JSONObject getLocalJSONFromContent() {
// 获取名称
String name = getName();
try {
// 如果mMetaInfo为空说明是新建的任务
if (mMetaInfo == null) {
// new task created from web
// 如果名称为空,说明是空的笔记
if (name == null) {
Log.w(TAG, "the note seems to be an empty one");
return null;
}
// 创建一个新的JSONObject
JSONObject js = new JSONObject();
// 创建一个新的JSONObject用于存储笔记信息
JSONObject note = new JSONObject();
// 创建一个新的JSONArray用于存储数据
JSONArray dataArray = new JSONArray();
// 创建一个新的JSONObject用于存储数据信息
JSONObject data = new JSONObject();
// 将名称存入数据信息
data.put(DataColumns.CONTENT, name);
// 将数据信息存入数据数组
dataArray.put(data);
// 将数据数组存入笔记信息
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
// 将笔记信息存入JSONObject
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
js.put(GTaskStringUtils.META_HEAD_NOTE, note);
return js;
} else {
// synced task
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());
break;
}
}
// 将数据信息存入数据数组
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
return mMetaInfo;
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
return null;
}
}
// 设置任务的元信息
// 设置元数据信息
public void setMetaInfo(MetaData metaData) {
// 如果元数据不为空且元数据的注释不为空
if (metaData != null && metaData.getNotes() != null) {
try {
// 将元数据的注释转换为JSON对象
mMetaInfo = new JSONObject(metaData.getNotes());
} catch (JSONException e) {
// 如果转换失败,打印警告日志
Log.w(TAG, e.toString());
// 将元数据信息设置为空
mMetaInfo = null;
}
}
}
// 获取同步动作
public int getSyncAction(Cursor c) {
try {
// 获取noteInfo
JSONObject noteInfo = null;
if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) {
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
}
// 如果noteInfo为空则返回SYNC_ACTION_UPDATE_REMOTE
if (noteInfo == null) {
Log.w(TAG, "it seems that note meta has been deleted");
return SYNC_ACTION_UPDATE_REMOTE;
}
// 如果noteInfo中没有ID则返回SYNC_ACTION_UPDATE_LOCAL
if (!noteInfo.has(NoteColumns.ID)) {
Log.w(TAG, "remote note id seems to be deleted");
return SYNC_ACTION_UPDATE_LOCAL;
}
// validate the note id now
// 验证note id是否一致
if (c.getLong(SqlNote.ID_COLUMN) != noteInfo.getLong(NoteColumns.ID)) {
Log.w(TAG, "note id doesn't match");
return SYNC_ACTION_UPDATE_LOCAL;
}
// 检查本地是否有修改
if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
// there is no local update本地没有更新继续比较本地同步 ID 和远程任务的最后修改时间
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// no update both side本地和远程都没有更新无需同步操作
return SYNC_ACTION_NONE;
} else {
// apply remote to local远程有更新本地无更新需要将远程的更新应用到本地
return SYNC_ACTION_UPDATE_LOCAL;
}
} else {
// validate gtask id 本地有更新,验证本地存储的 Google 任务 ID 和当前任务的全局唯一标识符是否一致
if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) {
// 两者不一致,记录错误日志并返回错误同步动作
Log.e(TAG, "gtask id doesn't match");
return SYNC_ACTION_ERROR;
}
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// local modification only 本地有修改,远程无更新,需要将本地的修改同步到远程
return SYNC_ACTION_UPDATE_REMOTE;
} else {
// 本地和远程都有更新,发生同步冲突
return SYNC_ACTION_UPDATE_CONFLICT;
}
}
} catch (Exception e) {
// 捕获异常,记录错误日志并打印堆栈信息
Log.e(TAG, e.toString());
e.printStackTrace();
}
// 发生异常或其他未知情况,返回错误同步动作
return SYNC_ACTION_ERROR;
}
// 判断任务是否值得保存
public boolean isWorthSaving() {
// 如果mMetaInfo不为空或者getName()返回的字符串不为空且长度大于0或者getNotes()返回的字符串不为空且长度大于0则返回true
return mMetaInfo != null || (getName() != null && getName().trim().length() > 0)
|| (getNotes() != null && getNotes().trim().length() > 0);
}
// 设置任务是否完成
public void setCompleted(boolean completed) {
// 将传入的参数completed赋值给成员变量mCompleted
this.mCompleted = completed;
}
// 设置任务的备注
public void setNotes(String notes) {
// 将传入的备注赋值给成员变量mNotes
this.mNotes = notes;
}
// 设置任务的前一个兄弟任务
public void setPriorSibling(Task priorSibling) {
// 将传入的前一个兄弟任务赋值给成员变量mPriorSibling
this.mPriorSibling = priorSibling;
}
// 设置任务的父任务列表
public void setParent(TaskList parent) {
// 将传入的父任务列表赋值给成员变量mParent
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;
}
}

@ -1,461 +0,0 @@
//开源许可证声明
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
import android.database.Cursor;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
//这段代码定义了一个名为TaskList的Java类它继承自Node类。
//这个类主要用于管理任务列表,包括创建、更新、设置内容、同步动作、添加、移除、移动子任务等功能。
public class TaskList extends Node {
// 定义一个常量,用于打印日志
private static final String TAG = TaskList.class.getSimpleName();
// 定义一个变量,用于存储任务列表的索引
private int mIndex;
// 定义一个变量,用于存储任务列表的子任务
private ArrayList<Task> mChildren;
// 构造函数,初始化任务列表的子任务和索引
public TaskList() {
// 调用父类构造函数
super();
// 初始化mChildren为ArrayList<Task>类型
mChildren = new ArrayList<Task>();
// 初始化mIndex为1
mIndex = 1;
}
// 获取创建任务的JSON对象
public JSONObject getCreateAction(int actionId) {
// 创建一个JSONObject对象
JSONObject js = new JSONObject();
try {
// action_type
// 将action_type设置为create
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// action_id
// 将action_id设置为传入的参数
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// index
// 将index设置为成员变量mIndex的值
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex);
// entity_delta
// 创建一个JSONObject对象entity
JSONObject entity = new JSONObject();
// 将entity的name设置为getName()的返回值
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
// 将entity的creator_id设置为null
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
// 将entity的entity_type设置为group
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
// 将entity设置为entity_delta的值
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
// 打印错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 抛出ActionFailureException异常
throw new ActionFailureException("fail to generate tasklist-create jsonobject");
}
// 返回JSONObject对象
return js;
}
// 获取更新任务的JSON对象
public JSONObject getUpdateAction(int actionId) {
// 创建一个JSONObject对象用于存储更新任务列表的相关信息
JSONObject js = new JSONObject();
try {
// action_type设置操作类型为更新任务列表
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// action_id设置本次操作的唯一标识符
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// id设置要更新的任务列表的全局唯一标识符
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// entity_delta创建一个新的 JSON 对象,用于存储任务列表实体的变更信息
JSONObject entity = new JSONObject();
// name: 设置任务列表的名称
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
// deleted: 设置任务列表的删除状态
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
// updated: 设置任务列表的更新时间
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
// 记录 JSON 解析异常的错误信息
Log.e(TAG, e.toString());
// 打印异常堆栈信息
e.printStackTrace();
// 抛出一个自定义的 ActionFailureException 异常,用于表示操作失败
throw new ActionFailureException("fail to generate tasklist-update jsonobject");
}
return js;
}
// 根据远程JSON设置任务列表的内容
public void setContentByRemoteJSON(JSONObject js) {
// 根据远程JSON设置内容
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
// 设置id
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// last_modified
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
// 设置最后修改时间
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// name
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
// 设置名称
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
// 抛出异常
throw new ActionFailureException("fail to get tasklist content from jsonobject");
}
}
}
// 根据本地JSON设置任务列表的内容
public void setContentByLocalJSON(JSONObject js) {
// 如果JSON为空或者没有META_HEAD_NOTE字段则打印警告日志
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
try {
// 获取META_HEAD_NOTE字段对应的JSONObject
JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
// 如果类型为文件夹
if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) {
// 获取文件夹名称
String name = folder.getString(NoteColumns.SNIPPET);
// 设置名称
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name);
// 如果类型为系统文件夹
} 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);
// 否则打印错误日志
else
Log.e(TAG, "invalid system folder");
// 否则打印错误日志
} else {
Log.e(TAG, "error type");
}
// 捕获JSON异常
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
// 获取本地JSON对象
// 从内容中获取本地JSON
public JSONObject getLocalJSONFromContent() {
try {
// 创建一个JSONObject对象
JSONObject js = new JSONObject();
// 创建一个JSONObject对象用于存储文件夹信息
JSONObject folder = new JSONObject();
// 获取文件夹名称
String folderName = getName();
// 如果文件夹名称以MIUI_FOLDER_PREFFIX开头则去掉该前缀
if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX))
folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(),
folderName.length());
// 将文件夹名称放入folder对象中
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对象放入js对象中
js.put(GTaskStringUtils.META_HEAD_NOTE, folder);
// 返回js对象
return js;
} catch (JSONException e) {
// 打印错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 返回null
return null;
}
}
// 根据传入的 Cursor 对象判断任务列表的同步动作。
//该方法会对比本地数据和远程数据的修改状态,从而决定采取何种同步操作。
public int getSyncAction(Cursor c) {
try {
// 获取本地修改列的值,判断本地数据是否有更新
if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
// there is no local update本地没有更新
// 比较本地同步 ID 列的值和远程任务列表的最后修改时间
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// no update both side 本地和远程都没有更新,无需同步操作
return SYNC_ACTION_NONE;
} else {
// apply remote to local 远程有更新,本地无更新,需要将远程的更新应用到本地
return SYNC_ACTION_UPDATE_LOCAL;
}
} else {
// validate gtask id本地有更新验证本地存储的 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()) {
// local modification only 本地有修改,远程无更新,需要将本地的修改同步到远程
return SYNC_ACTION_UPDATE_REMOTE;
} else {
// for folder conflicts, just apply local modification
// 对于文件夹冲突,直接将本地修改同步到远程
return SYNC_ACTION_UPDATE_REMOTE;
}
}
} catch (Exception e) {
// 捕获异常,记录错误日志
Log.e(TAG, e.toString());
// 打印异常堆栈信息
e.printStackTrace();
}
// 发生异常或其他未知情况,返回错误同步动作
return SYNC_ACTION_ERROR;
}
// 获取子任务数量
public int getChildTaskCount() {
// 返回子任务列表的大小
return mChildren.size();
}
// 添加子任务
public boolean addChildTask(Task task) {
boolean ret = false;
// 判断任务是否为空且不包含在子任务列表中
if (task != null && !mChildren.contains(task)) {
// 添加子任务
ret = mChildren.add(task);
// 如果添加成功
if (ret) {
// need to set prior sibling and parent
task.setPriorSibling(mChildren.isEmpty() ? null : mChildren
.get(mChildren.size() - 1));
task.setParent(this);
}
}
return ret;
}
// 在指定位置添加子任务
//如果指定的索引无效或者任务已经存在于列表中,操作将失败。
//成功添加任务后,会更新相关任务的前一个兄弟任务引用。
public boolean addChildTask(Task task, int index) {
// 如果索引小于0或者大于子任务列表的大小则返回false
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);
// update the task list
// 定义两个任务对象,分别用于存储插入位置的前一个任务和后一个任务
Task preTask = null;
// 如果插入位置不是列表的第一个位置,获取插入位置的前一个任务
if (index != 0)
if (index != 0)
preTask = mChildren.get(index - 1);
// 如果插入位置不是列表的最后一个位置,获取插入位置的后一个任务
if (index != mChildren.size() - 1)
afterTask = mChildren.get(index + 1);
// 设置新插入任务的前一个兄弟任务
task.setPriorSibling(preTask);
// 如果插入位置后面有任务,更新该任务的前一个兄弟任务为新插入的任务
if (afterTask != null)
afterTask.setPriorSibling(task);
}
return true;
}
// 移除子任务
public boolean removeChildTask(Task task) {
boolean ret = false;
// 获取子任务在子任务列表中的索引
int index = mChildren.indexOf(task);
if (index != -1) {
// 移除子任务
ret = mChildren.remove(task);
if (ret) {
// reset prior sibling and parent
task.setPriorSibling(null);
task.setParent(null);
// update the task list
if (index != mChildren.size()) {
mChildren.get(index).setPriorSibling(
index == 0 ? null : mChildren.get(index - 1));
}
}
}
return ret;
}
// 移动子任务
public boolean moveChildTask(Task task, int index) {
// 如果索引小于0或者大于等于子任务列表的大小则返回false
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "move child task: invalid index");
return false;
}
// 获取子任务在子任务列表中的位置
int pos = mChildren.indexOf(task);
// 如果子任务不在子任务列表中则返回false
if (pos == -1) {
Log.e(TAG, "move child task: the task should in the list");
return false;
}
// 如果子任务的位置和索引相同则返回true
if (pos == index)
return true;
// 否则,先移除子任务,再添加子任务到指定位置
return (removeChildTask(task) && addChildTask(task, index));
}
// 根据GID查找子任务
public Task findChildTaskByGid(String gid) {
// 遍历子任务列表
for (int i = 0; i < mChildren.size(); i++) {
// 获取子任务
Task t = mChildren.get(i);
// 如果子任务的gid与传入的gid相等则返回该子任务
if (t.getGid().equals(gid)) {
return t;
}
}
// 如果没有找到相等的子任务则返回null
return null;
}
// 获取子任务在子任务列表中的索引
public int getChildTaskIndex(Task task) {
// 返回子任务在子任务列表中的索引
return mChildren.indexOf(task);
}
// 根据索引获取子任务
public Task getChildTaskByIndex(int index) {
// 如果索引小于0或者大于等于子任务列表的大小则输出错误信息并返回null
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "getTaskByIndex: invalid index");
return null;
}
// 返回子任务列表中指定索引的任务
return mChildren.get(index);
}
// 根据GID获取子任务
public Task getChilTaskByGid(String gid) {
// 遍历子任务列表
for (Task task : mChildren) {
// 如果子任务的gid与传入的gid相等则返回该子任务
if (task.getGid().equals(gid))
return task;
}
// 如果没有找到匹配的子任务则返回null
return null;
}
// 获取子任务列表
public ArrayList<Task> getChildTaskList() {
// 返回子任务列表
return this.mChildren;
}
// 设置索引
public void setIndex(int index) {
// 将传入的索引赋值给成员变量mIndex
this.mIndex = index;
}
// 获取索引
public int getIndex() {
// 返回索引
return this.mIndex;
}
}

@ -1,361 +0,0 @@
//开源许可证声明
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.model;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.net.Uri;
import android.os.RemoteException;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.CallNote;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.Notes.TextNote;
import java.util.ArrayList;
//处理笔记note的数据和同步操作。
public class Note {
// 定义一个ContentValues对象用于存储note的差值
private ContentValues mNoteDiffValues;
// 定义一个NoteData对象用于存储note的数据
private NoteData mNoteData;
// 定义一个TAG常量用于日志输出
private static final String TAG = "Note";
/**
* Create a new note id for adding a new note to databases
*/
//同步方法用于在数据库中创建一个新的笔记并返回新笔记的ID。
//它首先创建一个ContentValues对象设置创建时间和修改时间以及笔记类型和父文件夹ID然后插入数据库并获取新笔记的ID。
public static synchronized long getNewNoteId(Context context, long folderId) {
// Create a new note in the database 在数据库中创建一个新的笔记
ContentValues values = new ContentValues();
// 获取当前系统时间作为笔记的创建时间
long createdTime = System.currentTimeMillis();
// 将创建时间插入到 ContentValues 中
values.put(NoteColumns.CREATED_DATE, createdTime);
// 将修改时间设置为与创建时间相同,并插入到 ContentValues 中
values.put(NoteColumns.MODIFIED_DATE, createdTime);
// 设置笔记类型为普通笔记,并插入到 ContentValues 中
values.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
// 标记笔记已被本地修改,并插入到 ContentValues 中
values.put(NoteColumns.LOCAL_MODIFIED, 1);
// 设置笔记的父文件夹ID并插入到 ContentValues 中
values.put(NoteColumns.PARENT_ID, folderId);
// 调用 ContentResolver 的 insert 方法将笔记信息插入到数据库中,并获取返回的 Uri
Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values);
long noteId = 0;
try {
// Get the note id from the uri从返回的 Uri 中提取笔记的 ID
noteId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
// 若提取 ID 时发生格式错误,记录错误日志并将笔记 ID 设置为 0
Log.e(TAG, "Get note id error :" + e.toString());
noteId = 0;
}
if (noteId == -1) {
// 若笔记 ID 为 -1抛出异常提示笔记 ID 错误
throw new IllegalStateException("Wrong note id:" + noteId);
}
return noteId;
}
// 构造函数
public Note() {
// 创建一个ContentValues对象用于存储数据
mNoteDiffValues = new ContentValues();
// 创建一个NoteData对象用于存储数据
mNoteData = new NoteData();
}
// 设置笔记的值
public void setNoteValue(String key, String value) {
// 将key和value放入mNoteDiffValues中
mNoteDiffValues.put(key, value);
// 将LOCAL_MODIFIED字段设置为1
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
// 将MODIFIED_DATE字段设置为当前时间
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
// 设置文本数据
public void setTextData(String key, String value) {
// 调用mNoteData对象的setTextData方法传入key和value参数
mNoteData.setTextData(key, value);
}
// 设置文本数据ID
public void setTextDataId(long id) {
// 调用mNoteData对象的setTextDataId方法传入参数id
mNoteData.setTextDataId(id);
}
// 获取文本数据ID
public long getTextDataId() {
// 返回NoteData对象中的文本数据ID
return mNoteData.mTextDataId;
}
// 设置通话数据ID
public void setCallDataId(long id) {
// 调用mNoteData对象的setCallDataId方法传入参数id
mNoteData.setCallDataId(id);
}
// 设置通话数据
public void setCallData(String key, String value) {
// 调用mNoteData对象的setCallData方法传入key和value参数
mNoteData.setCallData(key, value);
}
// 判断笔记是否被本地修改
public boolean isLocalModified() {
// 如果笔记的差值列表不为空或者笔记数据被本地修改则返回true
return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified();
}
// 同步笔记,将笔记的修改同步到数据库中。
// 同步笔记的方法,用于将本地的笔记数据同步到云端。
public boolean syncNote(Context context, long noteId) {
// 检查noteId是否小于等于0如果是则抛出异常
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
// 如果数据没有修改则直接返回true
if (!isLocalModified()) {
return true;
}
/**
* In theory, once data changed, the note should be updated on {@link NoteColumns#LOCAL_MODIFIED} and
* {@link NoteColumns#MODIFIED_DATE}. For data safety, though update note fails, we also update the
* note data info
*/
/**
* {@link }
* {@link } 使
*
*/
// 更新笔记的差值列表到数据库中,如果更新失败,则打印错误日志
if (context.getContentResolver().update(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), mNoteDiffValues, null,
null) == 0) {
//如果更新行数为 0说明更新失败记录错误日志
Log.e(TAG, "Update note error, should not happen");
// Do not return, fall through
}
// 清空笔记的差值列表
mNoteDiffValues.clear();
// 检查笔记数据是否有本地修改,并且尝试将笔记数据同步到数据库中
// 如果笔记数据有修改且同步失败pushIntoContentResolver 返回 null则返回 false 表示同步失败
if (mNoteData.isLocalModified()
&& (mNoteData.pushIntoContentResolver(context, noteId) == null)) {
return false;
}
return true;
}
private class NoteData {
// 文本数据ID
private long mTextDataId;
// 文本数据内容
private ContentValues mTextDataValues;
// 通话数据ID
private long mCallDataId;
// 通话数据内容
private ContentValues mCallDataValues;
// 日志标签
private static final String TAG = "NoteData";
// 构造函数初始化NoteData对象
public NoteData() {
// 初始化mTextDataValues对象
mTextDataValues = new ContentValues();
// 初始化mCallDataValues对象
mCallDataValues = new ContentValues();
// 初始化mTextDataId为0
mTextDataId = 0;
// 初始化mCallDataId为0
mCallDataId = 0;
}
// 判断文本数据和通话数据是否被修改
boolean isLocalModified() {
// 如果文本数据值列表的大小大于0或者通话数据值列表的大小大于0则返回true
return mTextDataValues.size() > 0 || mCallDataValues.size() > 0;
}
// 设置文本数据ID
void setTextDataId(long id) {
// 如果ID小于等于0抛出异常
if(id <= 0) {
throw new IllegalArgumentException("Text data id should larger than 0");
}
// 设置文本数据ID
mTextDataId = id;
}
// 设置通话数据ID
void setCallDataId(long id) {
// 如果id小于等于0抛出异常
if (id <= 0) {
throw new IllegalArgumentException("Call data id should larger than 0");
}
// 设置mCallDataId为id
mCallDataId = id;
}
// 设置通话数据
void setCallData(String key, String value) {
// 将key和value存入mCallDataValues中
mCallDataValues.put(key, value);
// 将LOCAL_MODIFIED字段设置为1
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
// 将MODIFIED_DATE字段设置为当前时间
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
// 设置文本数据
void setTextData(String key, String value) {
// 将key和value存入mTextDataValues中
mTextDataValues.put(key, value);
// 将LOCAL_MODIFIED字段设置为1
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
// 将MODIFIED_DATE字段设置为当前时间
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
// 将数据推送到ContentResolver
//根据数据的状态(是否已有 ID决定是插入新数据还是更新现有数据。
// 如果有多个操作需要执行,会使用批量操作来提高效率。
Uri pushIntoContentResolver(Context context, long noteId) {
/**
* Check for safety ID
*/
if (noteId <= 0) {
// 若笔记 ID 无效,抛出异常提示
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
//创建一个存储 ContentProvider 操作的列表,用于批量执行操作
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
// 定义一个 ContentProvider 操作构建器,用于构建更新操作
ContentProviderOperation.Builder builder = null;
// 如果文本数据不为空,需要处理文本数据
if(mTextDataValues.size() > 0) {
// 将笔记 ID 关联到文本数据中
mTextDataValues.put(DataColumns.NOTE_ID, noteId);
// 如果文本数据ID为0则插入新数据
if (mTextDataId == 0) {
// 设置文本数据的 MIME 类型
mTextDataValues.put(DataColumns.MIME_TYPE, TextNote.CONTENT_ITEM_TYPE);
// 调用 ContentResolver 的 insert 方法插入新的文本数据,并获取返回的 Uri
Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI,
mTextDataValues);
try {
// 从返回的 Uri 中提取新插入文本数据的 ID并设置到 mTextDataId 中
setTextDataId(Long.valueOf(uri.getPathSegments().get(1)));
} catch (NumberFormatException e) {
// 若提取 ID 时发生格式错误,记录错误日志并清空文本数据
Log.e(TAG, "Insert new text data fail with noteId" + noteId);
mTextDataValues.clear();
return null;
}
// 否则,说明文本数据已存在,需要更新现有数据
} else {
// 创建一个更新操作的构建器,指定要更新的数据 Uri
builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mTextDataId));
// 设置要更新的数据值
builder.withValues(mTextDataValues);
// 将更新操作添加到操作列表中
operationList.add(builder.build());
}
// 清空文本数据值
mTextDataValues.clear();
}
// 如果通话数据不为空
if(mCallDataValues.size() > 0) {
mCallDataValues.put(DataColumns.NOTE_ID, noteId);
// 如果通话数据ID为0则插入新数据
if (mCallDataId == 0) {
// 设置数据类型为通话记录类型
mCallDataValues.put(DataColumns.MIME_TYPE, CallNote.CONTENT_ITEM_TYPE);
// 插入新数据并获取插入后的 Uri
Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI,
mCallDataValues);
try {
// 从 Uri 中提取 ID
setCallDataId(Long.valueOf(uri.getPathSegments().get(1)));
} catch (NumberFormatException e) {
// 若提取 ID 时发生格式错误,记录错误日志并清空数据
Log.e(TAG, "Insert new call data fail with noteId" + noteId);
mCallDataValues.clear();
return null;
}
// 否则更新数据
} else {
// 创建一个更新操作的构建器,指定要更新的数据 Uri
builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mCallDataId));
// 设置要更新的数据值
builder.withValues(mCallDataValues);
// 将更新操作添加到操作列表中
operationList.add(builder.build());
}
// 清空数据值
mCallDataValues.clear();
}
// 如果操作列表不为空,则执行批量操作
if (operationList.size() > 0) {
try {
// 执行批量操作
ContentProviderResult[] results = context.getContentResolver().applyBatch(
Notes.AUTHORITY, operationList);
// 返回更新后的数据 Uri
return (results == null || results.length == 0 || results[0] == null) ? null
: ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId);
} catch (RemoteException e) {
// 若远程操作异常,记录错误日志并返回 null
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
return null;
} catch (OperationApplicationException e) {
// 若操作应用异常,记录错误日志并返回 null
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
return null;
}
}
return null;
}
}
}

@ -1,531 +0,0 @@
//开源许可证声明
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.model;
import android.appwidget.AppWidgetManager;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.CallNote;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.Notes.TextNote;
import net.micode.notes.tool.ResourceParser.NoteBgResources;
//用于处理笔记Note的相关操作。
//这个类包含了笔记的各种属性如内容、模式、警报日期、修改日期、背景颜色ID、小部件ID、小部件类型、文件夹ID等。
//它还定义了一些方法来创建新的笔记、加载现有的笔记、保存笔记、设置警报日期、标记笔记为已删除、设置背景颜色、设置清单模式、设置小部件类型、设置小部件ID、设置工作文本、转换为电话笔记等。
public class WorkingNote {
// Note对象
private Note mNote;
// Note的ID
private long mNoteId;
// Note的内容
private String mContent;
// Note的模式
private int mMode;
// 提醒日期
private long mAlertDate;
// 修改日期
private long mModifiedDate;
// 背景颜色ID
private int mBgColorId;
// 小部件ID
private int mWidgetId;
// 小部件类型
private int mWidgetType;
// 文件夹ID
private long mFolderId;
// 上下文
private Context mContext;
// 日志标签
private static final String TAG = "WorkingNote";
// 是否已删除
private boolean mIsDeleted;
// Note设置状态监听器
private NoteSettingChangedListener mNoteSettingStatusListener;
// 数据投影
public static final String[] DATA_PROJECTION = new String[] {
DataColumns.ID,
DataColumns.CONTENT,
DataColumns.MIME_TYPE,
DataColumns.DATA1,
DataColumns.DATA2,
DataColumns.DATA3,
DataColumns.DATA4,
};
// Note投影
public static final String[] NOTE_PROJECTION = new String[] {
NoteColumns.PARENT_ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.MODIFIED_DATE
};
// 数据ID列
private static final int DATA_ID_COLUMN = 0;
// 数据内容列
private static final int DATA_CONTENT_COLUMN = 1;
// 数据MIME类型列
private static final int DATA_MIME_TYPE_COLUMN = 2;
// 数据模式列
private static final int DATA_MODE_COLUMN = 3;
// Note父ID列
private static final int NOTE_PARENT_ID_COLUMN = 0;
// Note提醒日期列
private static final int NOTE_ALERTED_DATE_COLUMN = 1;
// Note背景颜色ID列
private static final int NOTE_BG_COLOR_ID_COLUMN = 2;
// Note小部件ID列
private static final int NOTE_WIDGET_ID_COLUMN = 3;
// Note小部件类型列
private static final int NOTE_WIDGET_TYPE_COLUMN = 4;
// Note修改日期列
private static final int NOTE_MODIFIED_DATE_COLUMN = 5;
// New note construct
// 构造函数用于创建一个WorkingNote对象
private WorkingNote(Context context, long folderId) {
// 保存上下文
mContext = context;
// 初始化提醒日期为0
mAlertDate = 0;
// 初始化修改日期为当前时间
mModifiedDate = System.currentTimeMillis();
// 保存文件夹ID
mFolderId = folderId;
// 创建一个新的Note对象
mNote = new Note();
// 初始化NoteID为0
mNoteId = 0;
// 初始化删除状态为false
mIsDeleted = false;
// 初始化模式为0
mMode = 0;
// 初始化小部件类型为无效
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
}
// Existing note construct
// 构造函数用于创建一个WorkingNote对象
private WorkingNote(Context context, long noteId, long folderId) {
// 保存上下文
mContext = context;
// 保存笔记ID
mNoteId = noteId;
// 保存文件夹ID
mFolderId = folderId;
// 初始化删除状态为false
mIsDeleted = false;
// 创建一个新的Note对象
mNote = new Note();
// 加载笔记
loadNote();
}
// 加载笔记
private void loadNote() {
// 从ContentResolver中查询指定id的笔记
Cursor cursor = mContext.getContentResolver().query(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId), NOTE_PROJECTION, null,
null, null);
// 如果查询结果不为空
if (cursor != null) {
// 如果查询结果中有数据
if (cursor.moveToFirst()) {
// 获取笔记的父文件夹id
mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN);
// 获取笔记的背景颜色id
mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN);
// 获取笔记的widget id
mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN);
// 获取笔记的widget类型
mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN);
// 获取笔记的提醒日期
mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);
// 获取笔记的修改日期
mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);
}
// 关闭查询结果
cursor.close();
} else {
// 如果查询结果为空,则打印错误日志并抛出异常
Log.e(TAG, "No note with id:" + mNoteId);
throw new IllegalArgumentException("Unable to find note with id " + mNoteId);
}
// 加载笔记数据
loadNoteData();
}
// 加载笔记数据
private void loadNoteData() {
// 从ContentResolver中查询笔记数据
Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION,
DataColumns.NOTE_ID + "=?", new String[] {
String.valueOf(mNoteId)
}, null);
// 如果查询结果不为空
if (cursor != null) {
// 如果查询结果中有数据
if (cursor.moveToFirst()) {
// 遍历查询结果
do {
// 获取数据类型
String type = cursor.getString(DATA_MIME_TYPE_COLUMN);
// 如果数据类型为笔记
if (DataConstants.NOTE.equals(type)) {
// 获取笔记内容
mContent = cursor.getString(DATA_CONTENT_COLUMN);
// 获取笔记模式
mMode = cursor.getInt(DATA_MODE_COLUMN);
// 设置笔记数据ID
mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN));
// 如果数据类型为电话笔记
} else if (DataConstants.CALL_NOTE.equals(type)) {
// 设置电话笔记数据ID
mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN));
// 如果数据类型不正确
} else {
// 打印错误日志
Log.d(TAG, "Wrong note type with type:" + type);
}
} while (cursor.moveToNext());
}
// 关闭查询结果
cursor.close();
// 如果查询结果为空
} else {
// 打印错误日志
Log.e(TAG, "No data with id:" + mNoteId);
// 抛出异常
throw new IllegalArgumentException("Unable to find note's data with id " + mNoteId);
}
}
// 创建一个空的WorkingNote对象
public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
int widgetType, int defaultBgColorId) {
// 创建一个新的WorkingNote对象传入上下文、文件夹ID
WorkingNote note = new WorkingNote(context, folderId);
// 设置背景颜色ID
note.setBgColorId(defaultBgColorId);
// 设置小部件ID
note.setWidgetId(widgetId);
// 设置小部件类型
note.setWidgetType(widgetType);
// 返回创建的WorkingNote对象
return note;
}
// 从上下文和id加载工作笔记
public static WorkingNote load(Context context, long id) {
// 创建一个新的工作笔记对象传入上下文、id和0
return new WorkingNote(context, id, 0);
}
// 保存笔记
// 同步方法,用于保存笔记
public synchronized boolean saveNote() {
// 如果需要保存
if (isWorthSaving()) {
// 如果数据库中不存在
if (!existInDatabase()) {
// 获取新的笔记ID
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
// 如果获取失败,打印错误日志
Log.e(TAG, "Create new note fail with id:" + mNoteId);
return false;
}
}
// 同步笔记
mNote.syncNote(mContext, mNoteId);
/**
* Update widget content if there exist any widget of this note
*/
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE
&& mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onWidgetChanged();
}
return true;
} else {
return false;
}
}
// 判断当前对象是否存在于数据库中
public boolean existInDatabase() {
// 如果mNoteId大于0则表示当前对象存在于数据库中
return mNoteId > 0;
}
// 判断是否值得保存
private boolean isWorthSaving() {
// 如果已经被删除,或者不存在于数据库中且内容为空,或者存在于数据库中但未修改
if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent))
|| (existInDatabase() && !mNote.isLocalModified())) {
// 不值得保存
return false;
} else {
// 值得保存
return true;
}
}
// 设置NoteSettingChangedListener监听器
public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {
// 将传入的监听器赋值给mNoteSettingStatusListener
mNoteSettingStatusListener = l;
}
// 设置提醒日期
public void setAlertDate(long date, boolean set) {
// 如果传入的日期与当前日期不同
if (date != mAlertDate) {
// 更新当前日期
mAlertDate = date;
// 将日期转换为字符串并设置到Note对象中
mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate));
}
// 如果设置了监听器
if (mNoteSettingStatusListener != null) {
// 调用监听器的onClockAlertChanged方法传入日期和设置状态
mNoteSettingStatusListener.onClockAlertChanged(date, set);
}
}
// 标记是否已删除
public void markDeleted(boolean mark) {
// 将mIsDeleted设置为mark
mIsDeleted = mark;
// 如果mWidgetId不为INVALID_APPWIDGET_IDmWidgetType不为INVALIDE并且mNoteSettingStatusListener不为null
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) {
// 调用mNoteSettingStatusListener的onWidgetChanged方法
mNoteSettingStatusListener.onWidgetChanged();
}
}
// 设置背景颜色ID
public void setBgColorId(int id) {
// 如果传入的ID与当前背景颜色ID不同
if (id != mBgColorId) {
// 更新当前背景颜色ID
mBgColorId = id;
// 如果有监听器则调用监听器的onBackgroundColorChanged方法
if (mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onBackgroundColorChanged();
}
// 更新笔记的背景颜色ID
mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id));
}
}
// 设置检查列表模式
public void setCheckListMode(int mode) {
// 如果当前模式与传入的模式不同
if (mMode != mode) {
// 如果有监听器则调用监听器的onCheckListModeChanged方法
if (mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);
}
// 更新模式
mMode = mode;
// 将模式保存到文本数据中
mNote.setTextData(TextNote.MODE, String.valueOf(mMode));
}
}
// 设置小部件类型
public void setWidgetType(int type) {
// 如果传入的类型与当前类型不同
if (type != mWidgetType) {
// 更新当前类型
mWidgetType = type;
// 将当前类型保存到NoteColumns.WIDGET_TYPE字段中
mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType));
}
}
// 设置小部件ID
public void setWidgetId(int id) {
// 如果传入的ID与当前的小部件ID不同
if (id != mWidgetId) {
// 将当前的小部件ID设置为传入的ID
mWidgetId = id;
// 将小部件ID保存到Note对象中
mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));
}
}
// 设置工作文本
public void setWorkingText(String text) {
// 如果工作文本和传入的文本不相等
if (!TextUtils.equals(mContent, text)) {
// 将传入的文本赋值给工作文本
mContent = text;
// 将工作文本设置到Note对象中
mNote.setTextData(DataColumns.CONTENT, mContent);
}
}
// 将电话号码和通话日期转换为CallNote
public void convertToCallNote(String phoneNumber, long callDate) {
// 将通话日期转换为字符串并设置到CallNote中
mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate));
// 将电话号码设置到CallNote中
mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber);
// 设置CallNote的父ID为通话记录文件夹的ID
mNote.setNoteValue(NoteColumns.PARENT_ID, String.valueOf(Notes.ID_CALL_RECORD_FOLDER));
}
// 判断是否有闹钟提醒
public boolean hasClockAlert() {
// 如果mAlertDate大于0则返回true否则返回false
return (mAlertDate > 0 ? true : false);
}
// 获取内容
public String getContent() {
// 返回mContent
return mContent;
}
// 获取提醒日期
public long getAlertDate() {
// 返回提醒日期
return mAlertDate;
}
// 获取修改日期
public long getModifiedDate() {
// 返回修改日期
return mModifiedDate;
}
// 获取背景颜色资源ID
public int getBgColorResId() {
// 根据背景颜色ID获取对应的背景颜色资源ID
return NoteBgResources.getNoteBgResource(mBgColorId);
}
// 获取背景颜色ID
public int getBgColorId() {
// 返回背景颜色ID
return mBgColorId;
}
// 获取标题背景资源ID
public int getTitleBgResId() {
// 根据背景颜色ID获取标题背景资源ID
return NoteBgResources.getNoteTitleBgResource(mBgColorId);
}
// 获取检查列表模式
public int getCheckListMode() {
// 返回模式
return mMode;
}
// 获取笔记ID
public long getNoteId() {
// 返回笔记ID
return mNoteId;
}
// 获取文件夹ID
public long getFolderId() {
// 返回文件夹ID
return mFolderId;
}
// 获取小部件ID
public int getWidgetId() {
// 返回小部件ID
return mWidgetId;
}
// 获取小部件类型
public int getWidgetType() {
// 返回小部件类型
return mWidgetType;
}
public interface NoteSettingChangedListener {
/**
* Called when the background color of current note has just changed
*/
// 当背景颜色改变时调用
void onBackgroundColorChanged();
/**
* Called when user set clock
*/
// 当时钟提醒日期改变时调用此方法
void onClockAlertChanged(long date, boolean set);
/**
* Call when user create note from widget
*/
// 当小部件发生变化时调用
void onWidgetChanged();
/**
* Call when switch between check list mode and normal mode
* @param oldMode is previous mode before change
* @param newMode is new mode
*/
// 当列表模式改变时调用此方法
void onCheckListModeChanged(int oldMode, int newMode);
}
}
Loading…
Cancel
Save