|
|
|
|
@ -13,7 +13,7 @@
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
//常益瑞的阅读代码和标注
|
|
|
|
|
package net.micode.notes.gtask.data;
|
|
|
|
|
|
|
|
|
|
import android.appwidget.AppWidgetManager;
|
|
|
|
|
@ -122,6 +122,11 @@ public class SqlNote {
|
|
|
|
|
|
|
|
|
|
private ArrayList<SqlData> mDataList;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造一个新的SqlNote对象,并初始化其属性。
|
|
|
|
|
*
|
|
|
|
|
* @param context 上下文环境
|
|
|
|
|
*/
|
|
|
|
|
public SqlNote(Context context) {
|
|
|
|
|
mContext = context;
|
|
|
|
|
mContentResolver = context.getContentResolver();
|
|
|
|
|
@ -142,7 +147,12 @@ public class SqlNote {
|
|
|
|
|
mDiffNoteValues = new ContentValues();
|
|
|
|
|
mDataList = new ArrayList<SqlData>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据给定的上下文环境和游标构造一个SqlNote对象,并从游标加载数据。
|
|
|
|
|
*
|
|
|
|
|
* @param context 上下文环境
|
|
|
|
|
* @param c 游标对象
|
|
|
|
|
*/
|
|
|
|
|
public SqlNote(Context context, Cursor c) {
|
|
|
|
|
mContext = context;
|
|
|
|
|
mContentResolver = context.getContentResolver();
|
|
|
|
|
@ -153,7 +163,12 @@ public class SqlNote {
|
|
|
|
|
loadDataContent();
|
|
|
|
|
mDiffNoteValues = new ContentValues();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据给定的上下文环境和指定ID构造一个SqlNote对象,并根据ID加载数据。
|
|
|
|
|
*
|
|
|
|
|
* @param context 上下文环境
|
|
|
|
|
* @param id 数据的唯一标识符
|
|
|
|
|
*/
|
|
|
|
|
public SqlNote(Context context, long id) {
|
|
|
|
|
mContext = context;
|
|
|
|
|
mContentResolver = context.getContentResolver();
|
|
|
|
|
@ -166,25 +181,43 @@ public class SqlNote {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从数据库加载指定ID的笔记信息
|
|
|
|
|
*
|
|
|
|
|
* @param id 需要加载的笔记的ID
|
|
|
|
|
*/
|
|
|
|
|
private void loadFromCursor(long id) {
|
|
|
|
|
// 创建Cursor对象,用于执行SQL查询
|
|
|
|
|
Cursor c = null;
|
|
|
|
|
try {
|
|
|
|
|
// 根据传入的ID查询数据库中的笔记信息
|
|
|
|
|
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)",
|
|
|
|
|
new String[] {
|
|
|
|
|
String.valueOf(id)
|
|
|
|
|
}, null);
|
|
|
|
|
// 如果查询结果不为空,移动到查询结果的第一行,并调用loadFromCursor方法处理数据
|
|
|
|
|
if (c != null) {
|
|
|
|
|
c.moveToNext();
|
|
|
|
|
loadFromCursor(c);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果查询结果为空,记录警告日志
|
|
|
|
|
Log.w(TAG, "loadFromCursor: cursor = null");
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
// 关闭Cursor资源,避免内存泄漏
|
|
|
|
|
if (c != null)
|
|
|
|
|
c.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从Cursor中加载数据
|
|
|
|
|
*
|
|
|
|
|
* 此方法用于从数据库查询结果(Cursor)中提取数据,并将其赋值给当前对象的成员变量
|
|
|
|
|
* 它按列索引读取各种类型的数据(长整型、整型、字符串等),并更新对象的状态
|
|
|
|
|
*
|
|
|
|
|
* @param c 数据库查询结果的Cursor对象,包含待加载的数据
|
|
|
|
|
*/
|
|
|
|
|
private void loadFromCursor(Cursor c) {
|
|
|
|
|
mId = c.getLong(ID_COLUMN);
|
|
|
|
|
mAlertDate = c.getLong(ALERTED_DATE_COLUMN);
|
|
|
|
|
@ -200,24 +233,37 @@ public class SqlNote {
|
|
|
|
|
mVersion = c.getLong(VERSION_COLUMN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 加载笔记内容
|
|
|
|
|
*
|
|
|
|
|
* 本方法从内容提供者中查询特定笔记的详细数据主要用途是在笔记详情活动中展示笔记的具体内容
|
|
|
|
|
* 方法首先清除现有的数据列表,然后从内容提供者处获取并添加新的数据
|
|
|
|
|
*/
|
|
|
|
|
private void loadDataContent() {
|
|
|
|
|
// 声明一个Cursor对象用于查询数据
|
|
|
|
|
Cursor c = null;
|
|
|
|
|
// 清空数据列表,准备加载新的数据
|
|
|
|
|
mDataList.clear();
|
|
|
|
|
try {
|
|
|
|
|
// 执行查询操作,根据note_id获取笔记的详细数据
|
|
|
|
|
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 data = new SqlData(mContext, c);
|
|
|
|
|
mDataList.add(data);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 如果查询结果的Cursor为null,记录警告日志
|
|
|
|
|
Log.w(TAG, "loadDataContent: cursor = null");
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
@ -226,19 +272,27 @@ public class SqlNote {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从给定的JSONObject中设置便笺的内容。
|
|
|
|
|
*
|
|
|
|
|
* @param js 包含便笺信息的JSON对象。
|
|
|
|
|
* @return 如果成功设置内容返回true,否则返回false。
|
|
|
|
|
*/
|
|
|
|
|
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) {
|
|
|
|
|
// for folder we can only update the snnipet and type
|
|
|
|
|
String snippet = note.has(NoteColumns.SNIPPET) ? note
|
|
|
|
|
// 更新文件夹类型的便笺的摘要和类型 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;
|
|
|
|
|
@ -359,17 +413,24 @@ public class SqlNote {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据对象的类型组装并返回一个包含笔记或文件夹信息的JSONObject
|
|
|
|
|
* 此方法主要用于生成内容的JSON表示,包括笔记的详细信息以及可能关联的数据
|
|
|
|
|
*
|
|
|
|
|
* @return 包含笔记或文件夹信息的JSONObject,如果未创建则返回null
|
|
|
|
|
*/
|
|
|
|
|
public JSONObject getContent() {
|
|
|
|
|
try {
|
|
|
|
|
JSONObject js = new JSONObject();
|
|
|
|
|
|
|
|
|
|
// 检查标记,确保对象已经在数据库中创建,否则记录错误并返回null
|
|
|
|
|
if (mIsCreate) {
|
|
|
|
|
Log.e(TAG, "it seems that we haven't created this in database yet");
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据对象类型,构造不同的JSONObject
|
|
|
|
|
JSONObject note = new JSONObject();
|
|
|
|
|
if (mType == Notes.TYPE_NOTE) {
|
|
|
|
|
// 如果是笔记类型,将笔记的详细信息添加到JSONObject中
|
|
|
|
|
note.put(NoteColumns.ID, mId);
|
|
|
|
|
note.put(NoteColumns.ALERTED_DATE, mAlertDate);
|
|
|
|
|
note.put(NoteColumns.BG_COLOR_ID, mBgColorId);
|
|
|
|
|
@ -383,7 +444,7 @@ public class SqlNote {
|
|
|
|
|
note.put(NoteColumns.WIDGET_TYPE, mWidgetType);
|
|
|
|
|
note.put(NoteColumns.ORIGIN_PARENT_ID, mOriginParent);
|
|
|
|
|
js.put(GTaskStringUtils.META_HEAD_NOTE, note);
|
|
|
|
|
|
|
|
|
|
// 构造一个JSONArray来存储关联的数据对象,并将其添加到主JSONObject中
|
|
|
|
|
JSONArray dataArray = new JSONArray();
|
|
|
|
|
for (SqlData sqlData : mDataList) {
|
|
|
|
|
JSONObject data = sqlData.getContent();
|
|
|
|
|
@ -393,6 +454,7 @@ public class SqlNote {
|
|
|
|
|
}
|
|
|
|
|
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
|
|
|
|
|
} else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) {
|
|
|
|
|
// 如果是文件夹或系统类型,将基本信息添加到JSONObject中
|
|
|
|
|
note.put(NoteColumns.ID, mId);
|
|
|
|
|
note.put(NoteColumns.TYPE, mType);
|
|
|
|
|
note.put(NoteColumns.SNIPPET, mSnippet);
|
|
|
|
|
@ -401,6 +463,7 @@ public class SqlNote {
|
|
|
|
|
|
|
|
|
|
return js;
|
|
|
|
|
} catch (JSONException e) {
|
|
|
|
|
// 捕获JSONException异常,记录错误并打印堆栈跟踪
|
|
|
|
|
Log.e(TAG, e.toString());
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
@ -408,18 +471,29 @@ public class SqlNote {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setParentId(long id) {
|
|
|
|
|
// 设置父ID
|
|
|
|
|
mParentId = id;
|
|
|
|
|
// 记录父ID的变更值
|
|
|
|
|
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 设置任务的GtaskId
|
|
|
|
|
*
|
|
|
|
|
* @param gid 任务的GtaskId
|
|
|
|
|
*/
|
|
|
|
|
public void setGtaskId(String gid) {
|
|
|
|
|
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置同步I
|
|
|
|
|
public void setSyncId(long syncId) {
|
|
|
|
|
mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将本地修改状态重置为未修改
|
|
|
|
|
*
|
|
|
|
|
* 本方法通过将本地修改状态值设置为0,来标记当前笔记未经过本地修改
|
|
|
|
|
* 这对于同步或者比较操作中,判断笔记是否经过本地修改至关重要
|
|
|
|
|
*/
|
|
|
|
|
public void resetLocalModified() {
|
|
|
|
|
mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0);
|
|
|
|
|
}
|
|
|
|
|
@ -440,23 +514,38 @@ public class SqlNote {
|
|
|
|
|
return mType == Notes.TYPE_NOTE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提交笔记更改或创建新笔记
|
|
|
|
|
* 如果是新创建的笔记,将尝试把笔记插入数据库
|
|
|
|
|
* 如果是更新现有笔记,将尝试更新数据库中的笔记信息
|
|
|
|
|
*
|
|
|
|
|
* @param validateVersion 是否验证版本在更新时的有效性
|
|
|
|
|
* @throws ActionFailureException 如果创建笔记失败
|
|
|
|
|
* @throws IllegalStateException 如果创建线程ID失败或尝试用无效ID更新笔记
|
|
|
|
|
*/
|
|
|
|
|
public void commit(boolean validateVersion) {
|
|
|
|
|
// 如果是新创建的笔记
|
|
|
|
|
if (mIsCreate) {
|
|
|
|
|
// 检查是否需要移除无效的ID值
|
|
|
|
|
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {
|
|
|
|
|
mDiffNoteValues.remove(NoteColumns.ID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 插入新笔记并获取URI
|
|
|
|
|
Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues);
|
|
|
|
|
try {
|
|
|
|
|
// 从URI中提取并设置新创建的笔记ID
|
|
|
|
|
mId = Long.valueOf(uri.getPathSegments().get(1));
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
// 日志记录获取笔记ID错误
|
|
|
|
|
Log.e(TAG, "Get note id error :" + e.toString());
|
|
|
|
|
// 抛出异常指示创建笔记失败
|
|
|
|
|
throw new ActionFailureException("create note failed");
|
|
|
|
|
}
|
|
|
|
|
if (mId == 0) {
|
|
|
|
|
// 抛出异常指示创建线程ID失败
|
|
|
|
|
throw new IllegalStateException("Create thread id failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是普通笔记,提交附加数据
|
|
|
|
|
if (mType == Notes.TYPE_NOTE) {
|
|
|
|
|
for (SqlData sqlData : mDataList) {
|
|
|
|
|
sqlData.commit(mId, false, -1);
|
|
|
|
|
@ -467,6 +556,7 @@ public class SqlNote {
|
|
|
|
|
Log.e(TAG, "No such note");
|
|
|
|
|
throw new IllegalStateException("Try to update note with invalid id");
|
|
|
|
|
}
|
|
|
|
|
// 如果有更改值,更新笔记
|
|
|
|
|
if (mDiffNoteValues.size() > 0) {
|
|
|
|
|
mVersion ++;
|
|
|
|
|
int result = 0;
|
|
|
|
|
@ -482,11 +572,12 @@ public class SqlNote {
|
|
|
|
|
String.valueOf(mId), String.valueOf(mVersion)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// 如果更新结果为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);
|
|
|
|
|
|