You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2Q1/SqlNote.java

519 lines
44 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* 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;//包名为“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;//导入“Notes”类
import net.micode.notes.data.Notes.DataColumns;//导入“Notes”类的“DataColumns”内部类
import net.micode.notes.data.Notes.NoteColumns;//导入“Notes”类的“NoteColumns”内部类
import net.micode.notes.gtask.exception.ActionFailureException;//导入“gtask 操作失败异常”;
import net.micode.notes.tool.GTaskStringUtils;//导入“Notes 工具类的字符串操作工具”;
import net.micode.notes.tool.ResourceParser;//导入资源解析器;
import org.json.JSONArray;//导入 JSON 数组;
import org.json.JSONException;//导入 JSON 异常;
import org.json.JSONObject;//导入 JSON 对象;
import java.util.ArrayList;//导入数组列表。
public class SqlNote {//定义一个名为“SqlNote”的公共类
private static final String TAG = SqlNote.class.getSimpleName();//定义一个静态字符串变量“tag”其值为当前类的简单名称
private static final int INVALID_ID = -99999;//定义一个静态整型常量“INVALID_ID”其值为-99999
public static final String[] PROJECTION_NOTE = new String[] {//定义一个公共静态字符串数组“PROJECTION_NOTE”其中包含了一些列名
NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID,//“PROJECTION_NOTE”数组中的元素包括“NoteColumns.ID”、“NoteColumns.ALERTED_DATE”和“NoteColumns.BG_COLOR_ID”
NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE,//定义“PROJECTION_NOTE”数组中的元素包括“NoteColumns.CREATED_DATE”、“NoteColumns.HAS_ATTACHMENT”和“NoteColumns.MODIFIED_DATE”
NoteColumns.NOTES_COUNT, NoteColumns.PARENT_ID, NoteColumns.SNIPPET, NoteColumns.TYPE,//定义“PROJECTION_NOTE”数组中的元素包括“NoteColumns.NOTES_COUNT”、“NoteColumns.PARENT_ID”、“NoteColumns.SNIPPET”和“NoteColumns.TYPE”
NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, NoteColumns.SYNC_ID,//定义“PROJECTION_NOTE”数组中的元素包括“NoteColumns.WIDGET_ID”、“NoteColumns.WIDGET_TYPE”和“NoteColumns.SYNC_ID”
NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID,//定义“PROJECTION_NOTE”数组中的元素包括“NoteColumns.LOCAL_MODIFIED”、“NoteColumns.ORIGIN_PARENT_ID”和“NoteColumns.GTASK_ID”
NoteColumns.VERSION//定义“PROJECTION_NOTE”数组中的元素包括“NoteColumns.VERSION”
};
public static final int ID_COLUMN = 0;//定义一个公共静态整型常量“ID_COLUMN”其值为 0
public static final int ALERTED_DATE_COLUMN = 1;//定义一个公共静态整型常量“ALERTED_DATE_COLUMN”其值为 1
public static final int BG_COLOR_ID_COLUMN = 2;//定义一个公共静态整型常量“BG_COLOR_ID_COLUMN”其值为 2
public static final int CREATED_DATE_COLUMN = 3;//定义一个公共静态整型常量“CREATED_DATE_COLUMN”其值为 3
public static final int HAS_ATTACHMENT_COLUMN = 4;//定义一个公共静态整型常量“HAS_ATTACHMENT_COLUMN”其值为 4
public static final int MODIFIED_DATE_COLUMN = 5;//定义一个公共静态整型常量“MODIFIED_DATE_COLUMN”其值为 5
public static final int NOTES_COUNT_COLUMN = 6;//定义一个公共静态整型常量“NOTES_COUNT_COLUMN”其值为 6
public static final int PARENT_ID_COLUMN = 7;//定义一个公共静态整型常量“PARENT_ID_COLUMN”其值为 7
public static final int SNIPPET_COLUMN = 8;//定义一个公共静态整型常量“SNIPPET_COLUMN”其值为 8
public static final int TYPE_COLUMN = 9;//定义一个公共静态整型常量“TYPE_COLUMN”其值为 9
public static final int WIDGET_ID_COLUMN = 10;//定义一个公共静态整型常量“WIDGET_ID_COLUMN”其值为 10
public static final int WIDGET_TYPE_COLUMN = 11;//定义一个公共静态整型常量“WIDGET_TYPE_COLUMN”其值为 11
public static final int SYNC_ID_COLUMN = 12;//定义一个公共静态整型常量“SYNC_ID_COLUMN”其值为 12
public static final int LOCAL_MODIFIED_COLUMN = 13;//定义一个公共静态整型常量“LOCAL_MODIFIED_COLUMN”其值为 13
public static final int ORIGIN_PARENT_ID_COLUMN = 14;//定义一个公共静态整型常量“ORIGIN_PARENT_ID_COLUMN”其值为 14
public static final int GTASK_ID_COLUMN = 15;//定义一个公共静态整型常量“GTASK_ID_COLUMN”其值为 15
public static final int VERSION_COLUMN = 16;//定义一个公共静态整型常量“VERSION_COLUMN”其值为 16
private Context mContext;//定义一个私有成员变量“mContext”其类型为“Context”
private ContentResolver mContentResolver;//定义一个私有成员变量“mContentResolver”其类型为“ContentResolver”
private boolean mIsCreate;//定义一个私有成员变量“mIsCreate”其类型为“boolean”
private long mId;//定义一个私有成员变量“mId”其类型为“long”
private long mAlertDate;//定义一个私有成员变量“mAlertDate”其类型为“long”
private int mBgColorId;//定义一个私有成员变量“mBgColorId”其类型为“int”
private long mCreatedDate;//定义一个私有成员变量“mCreatedDate”其类型为“long”
private int mHasAttachment;//定义一个私有成员变量“mHasAttachment”其类型为“int”
private long mModifiedDate;//定义一个私有成员变量“mModifiedDate”其类型为“long”
private long mParentId;//定义一个私有成员变量“mParentId”其类型为“long”
private String mSnippet;//定义一个私有成员变量“mSnippet”其类型为“String”
private int mType;//定义一个私有成员变量“mType”其类型为“int”
private int mWidgetId;//定义一个私有成员变量“mWidgetId”其类型为“int”
private int mWidgetType;//定义一个私有成员变量“mWidgetType”其类型为“int”
private long mOriginParent;//定义一个私有成员变量“mOriginParent”其类型为“long”
private long mVersion;//定义一个私有成员变量“mVersion”其类型为“long”
private ContentValues mDiffNoteValues;//定义一个私有成员变量“mDiffNoteValues”其类型为“ContentValues”
private ArrayList<SqlData> mDataList;//定义一个私有成员变量“mDataList”其类型为“ArrayList”
public SqlNote(Context context) {//定义类的构造函数接收一个“Context”类型的参数
mContext = context;//在构造函数中将传入的“context”赋值给成员变量“mContext”
mContentResolver = context.getContentResolver();//获取“context”的内容解析器并赋值给成员变量“mContentResolver”
mIsCreate = true;//将成员变量“mIsCreate”设置为“true”表示当前是创建新的笔记
mId = INVALID_ID;//将成员变量“mId”设置为“INVALID_ID”表示笔记的 ID 无效;
mAlertDate = 0;//将成员变量“mAlertDate”设置为 0表示笔记的提醒日期为 0
mBgColorId = ResourceParser.getDefaultBgId(context);//获取默认的背景颜色 ID并赋值给成员变量“mBgColorId”
mCreatedDate = System.currentTimeMillis();//获取当前系统时间并赋值给成员变量“mCreatedDate”表示笔记的创建日期
mHasAttachment = 0;//将成员变量“mHasAttachment”设置为 0表示笔记没有附件
mModifiedDate = System.currentTimeMillis();//获取当前系统时间并赋值给成员变量“mModifiedDate”表示笔记的修改日期
mParentId = 0;//“mParentId”设置为 0表示笔记的父 ID 为 0
mSnippet = "";//将成员变量“mSnippet”设置为空字符串表示笔记的片段为空
mType = Notes.TYPE_NOTE;//Notes.TYPE_NOTE”表示笔记的类型为普通笔记
mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;//将成员变量“mWidgetId”设置为“AppWidgetManager.INVALID_APPWIDGET_ID”表示笔记的小部件 ID 无效;
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;//将成员变量“mWidgetType”设置为“Notes.TYPE_WIDGET_INVALIDE”表示笔记的小部件类型无效
mOriginParent = 0;//将成员变量“mOriginParent”设置为 0表示笔记的原始父 ID 为 0
mVersion = 0;//将成员变量“mVersion”设置为 0表示笔记的版本号为 0
mDiffNoteValues = new ContentValues();//创建一个新的“ContentValues”对象并赋值给成员变量“mDiffNoteValues”
mDataList = new ArrayList<SqlData>();//创建一个新的“ArrayList”对象并赋值给成员变量“mDataList”
}
public SqlNote(Context context, Cursor c) {//定义类的另一个构造函数接收一个“Context”类型的参数和一个“Cursor”类型的参数
mContext = context;//在构造函数中将传入的“context”赋值给成员变量“mContext”
mContentResolver = context.getContentResolver();//获取“context”的内容解析器并赋值给成员变量“mContentResolver”
mIsCreate = false;//将成员变量“mIsCreate”设置为“false”表示当前不是创建新的笔记
loadFromCursor(c);//调用“loadFromCursor”方法从“Cursor”中加载笔记的数据
mDataList = new ArrayList<SqlData>();//创建一个新的“ArrayList”对象并赋值给成员变量“mDataList”
if (mType == Notes.TYPE_NOTE)//如果笔记的类型为普通笔记则调用“loadDataContent”方法加载笔记的数据内容
loadDataContent();
mDiffNoteValues = new ContentValues();//创建一个新的“ContentValues”对象并赋值给成员变量“mDiffNoteValues”
}
public SqlNote(Context context, long id) {//定义类的另一个构造函数接收一个“Context”类型的参数和一个“long”类型的参数
mContext = context;//在构造函数中将传入的“context”赋值给成员变量“mContext”
mContentResolver = context.getContentResolver();//获取“context”的内容解析器并赋值给成员变量“mContentResolver”
mIsCreate = false;//将成员变量“mIsCreate”设置为“false”表示当前不是创建新的笔记
loadFromCursor(id);//调用“loadFromCursor”方法根据“id”从数据库中加载笔记的数据
mDataList = new ArrayList<SqlData>();//创建一个新的“ArrayList”对象并赋值给成员变量“mDataList”
if (mType == Notes.TYPE_NOTE)//如果笔记的类型为普通笔记则调用“loadDataContent”方法加载笔记的数据内容
loadDataContent();
mDiffNoteValues = new ContentValues();//创建一个新的“ContentValues”对象并赋值给成员变量“mDiffNoteValues”
}
private void loadFromCursor(long id) {//定义一个私有方法“loadFromCursor”接收一个“long”类型的参数
Cursor c = null;//声明一个“Cursor”类型的变量“c”并初始化为“null”
try {
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)",//使用“mContentResolver”查询“Notes.CONTENT_NOTE_URI”表获取指定“id”的笔记数据并将结果存储在“c”中
new String[] {//设置查询条件的参数值;
String.valueOf(id)//将“id”转换为字符串并作为查询条件的参数值
}, null);//设置查询的排序方式为“null”
if (c != null) {//如果“c”不为“null”则执行以下操作
c.moveToNext();//将游标移动到下一条记录;
loadFromCursor(c);//调用“loadFromCursor”方法从游标中加载笔记的数据
} else {//如果“c”为“null”则执行以下操作
Log.w(TAG, "loadFromCursor: cursor = null");//输出日志信息,提示游标为空;
}
} finally {//V在“finally”代码块中执行以下操作
if (c != null)//如果“c”不为“null”则执行以下操作
c.close();//关闭游标;
}
}
private void loadFromCursor(Cursor c) {//定义一个私有方法“loadFromCursor”接收一个“Cursor”类型的参数
mId = c.getLong(ID_COLUMN);//从游标中获取“ID_COLUMN”列的值并赋值给成员变量“mId”
mAlertDate = c.getLong(ALERTED_DATE_COLUMN);//从游标中获取“ALERTED_DATE_COLUMN”列的值并赋值给成员变量“mAlertDate”
mBgColorId = c.getInt(BG_COLOR_ID_COLUMN);//从游标中获取“BG_COLOR_ID_COLUMN”列的值并赋值给成员变量“mBgColorId”
mCreatedDate = c.getLong(CREATED_DATE_COLUMN);//从游标中获取“CREATED_DATE_COLUMN”列的值并赋值给成员变量“mCreatedDate”
mHasAttachment = c.getInt(HAS_ATTACHMENT_COLUMN);//从游标中获取“HAS_ATTACHMENT_COLUMN”列的值并赋值给成员变量“mHasAttachment”
mModifiedDate = c.getLong(MODIFIED_DATE_COLUMN);//从游标中获取“MODIFIED_DATE_COLUMN”列的值并赋值给成员变量“mModifiedDate”
mParentId = c.getLong(PARENT_ID_COLUMN);//从游标中获取“PARENT_ID_COLUMN”列的值并赋值给成员变量“mParentId”
mSnippet = c.getString(SNIPPET_COLUMN);//从游标中获取“SNIPPET_COLUMN”列的值并赋值给成员变量“mSnippet”
mType = c.getInt(TYPE_COLUMN);//从游标中获取“TYPE_COLUMN”列的值并赋值给成员变量“mType”
mWidgetId = c.getInt(WIDGET_ID_COLUMN);//从游标中获取“WIDGET_ID_COLUMN”列的值并赋值给成员变量“mWidgetId”
mWidgetType = c.getInt(WIDGET_TYPE_COLUMN);//从游标中获取“WIDGET_TYPE_COLUMN”列的值并赋值给成员变量“mWidgetType”
mVersion = c.getLong(VERSION_COLUMN);//从游标中获取“VERSION_COLUMN”列的值并赋值给成员变量“mVersion”
}
private void loadDataContent() {//定义一个私有方法“loadDataContent”
Cursor c = null;//明一个“Cursor”类型的变量“c”并初始化为“null”
mDataList.clear();//清空“mDataList”列表
try {try
c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA,//使用“mContentResolver”查询“Notes.CONTENT_DATA_URI”表获取指定笔记的“SqlData”数据并将结果存储在“c”中
"(note_id=?)", new String[] {
String.valueOf(mId)// //是一个字符串数组用于在数据库查询中指定条件。其中 note_id=?  是查询条件,表示要查找的笔记的 ID 为指定的值 new String[] { String.valueOf(mId) }  是条件的值,将当前笔记的 ID 转换为字符串并作为查询条件的值 null  表示不指定排序方式。
}, null);
if (c != null) {//如果游标不为空,则执行以下操作。
if (c.getCount() == 0) {//如果游标中的行数为 0则表示该笔记似乎没有数据。
Log.w(TAG, "it seems that the note has not data");//:输出一条警告日志,提示该笔记似乎没有数据。
return;
}
while (c.moveToNext()) {//当游标可以向下移动时,执行以下循环。
SqlData data = new SqlData(mContext, c);//创建一个新的  SqlData  对象,用于表示当前游标指向的数据。
mDataList.add(data);//将新创建的  SqlData  对象添加到  mDataList  列表中。
}
} else {//如果游标为空,则执行以下操作。
Log.w(TAG, "loadDataContent: cursor = null");//输出一条警告日志,提示游标为空。
}
} finally {//无论游标是否为空,都执行以下操作。
if (c != null)
c.close();//如果游标不为空,则关闭游标。
}
}
public boolean setContent(JSONObject js) {
try {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);//从传入的  JSONObject  中获取名为  GTaskStringUtils.META_HEAD_NOTE  的子对象,并将其赋值给  note  变量。
if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {//如果  note  对象的  type  字段的值为  Notes.TYPE_SYSTEM 则表示这是一个系统文件夹不能进行设置操作。
Log.w(TAG, "cannot set system folder");//输出一条警告日志,提示不能设置系统文件夹。
} else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) {//如果  note  对象的  type  字段的值为  Notes.TYPE_FOLDER 则表示这是一个文件夹可以进行设置操作但只能更新  snippet  type  字段。
// for folder we can only update the snnipet and type
String snippet = note.has(NoteColumns.SNIPPET) ? note
.getString(NoteColumns.SNIPPET) : "";//获取  note  对象的  snippet  字段的值,如果该字段不存在,则使用空字符串作为默认值。
if (mIsCreate || !mSnippet.equals(snippet)) {//如果当前是创建新笔记,或者当前的  snippet  值与从  note  对象中获取的  snippet  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.SNIPPET, snippet);//将  snippet  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mSnippet = snippet;//将从  note  对象中获取的  snippet  值赋值给当前笔记的  snippet  字段。
int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE)
: Notes.TYPE_NOTE;//Notes.TYPE_NOTE; :获取  note  对象的  type  字段的值,如果该字段不存在,则使用  Notes.TYPE_NOTE  作为默认值。
if (mIsCreate || mType != type) {//如果当前是创建新笔记,或者当前的  type  值与从  note  对象中获取的  type  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.TYPE, type);//将  type  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mType = type;//将从  note  对象中获取的  type  值赋值给当前笔记的  type  字段。
} else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) {//如果  note  对象的  type  字段的值为  Notes.TYPE_NOTE 则表示这是一个普通笔记可以进行设置操作。
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);//从传入的  JSONObject  中获取名为  GTaskStringUtils.META_HEAD_DATA  的子对象,并将其转换为  JSONArray  类型。
long id = note.has(NoteColumns.ID) ? note.getLong(NoteColumns.ID) : INVALID_ID;//获取  note  对象的  id  字段的值,如果该字段不存在,则使用  INVALID_ID  作为默认值。
if (mIsCreate || mId != id) {//如果当前是创建新笔记,或者当前的  id  值与从  note  对象中获取的  id  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.ID, id);//将  id  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mId = id;//将从  note  对象中获取的  id  值赋值给当前笔记的  id  字段。
long alertDate = note.has(NoteColumns.ALERTED_DATE) ? note
.getLong(NoteColumns.ALERTED_DATE) : 0;//获取  note  对象的  alertDate  字段的值,如果该字段不存在,则使用 0 作为默认值。
if (mIsCreate || mAlertDate != alertDate) {//如果当前是创建新笔记,或者当前的  alertDate  值与从  note  对象中获取的  alertDate  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.ALERTED_DATE, alertDate);//将  alertDate  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
3
}
mAlertDate = alertDate;//将从  note  对象中获取的  alertDate  值赋值给当前笔记的  alertDate  字段。
int bgColorId = note.has(NoteColumns.BG_COLOR_ID) ? note
.getInt(NoteColumns.BG_COLOR_ID) : ResourceParser.getDefaultBgId(mContext);//获取  note  对象的  bgColorId  字段的值,如果该字段不存在,则使用默认的背景颜色 ID。
if (mIsCreate || mBgColorId != bgColorId) {//如果当前是创建新笔记,或者当前的  bgColorId  值与从  note  对象中获取的  bgColorId  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.BG_COLOR_ID, bgColorId);//将  bgColorId  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mBgColorId = bgColorId;//将从  note  对象中获取的  bgColorId  值赋值给当前笔记的  bgColorId  字段。
long createDate = note.has(NoteColumns.CREATED_DATE) ? note
.getLong(NoteColumns.CREATED_DATE) : System.currentTimeMillis();//获取  note  对象的  createDate  字段的值,如果该字段不存在,则使用当前时间作为默认值。
if (mIsCreate || mCreatedDate != createDate) {//如果当前是创建新笔记,或者当前的  createdDate  值与从  note  对象中获取的  createdDate  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.CREATED_DATE, createDate);//将  createdDate  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mCreatedDate = createDate;//将从  note  对象中获取的  createdDate  值赋值给当前笔记的  createdDate  字段。
int hasAttachment = note.has(NoteColumns.HAS_ATTACHMENT) ? note
.getInt(NoteColumns.HAS_ATTACHMENT) : 0;//获取  note  对象的  hasAttachment  字段的值,如果该字段不存在,则使用 0 作为默认值。
if (mIsCreate || mHasAttachment != hasAttachment) {//如果当前是创建新笔记,或者当前的  hasAttachment  值与从  note  对象中获取的  hasAttachment  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.HAS_ATTACHMENT, hasAttachment);//将  hasAttachment  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mHasAttachment = hasAttachment;//将从  note  对象中获取的  hasAttachment  值赋值给当前笔记的  hasAttachment  字段。
long modifiedDate = note.has(NoteColumns.MODIFIED_DATE) ? note
.getLong(NoteColumns.MODIFIED_DATE) : System.currentTimeMillis();//获取  note  对象的  modifiedDate  字段的值,如果该字段不存在,则使用当前时间作为默认值。
if (mIsCreate || mModifiedDate != modifiedDate) {//如果当前是创建新笔记,或者当前的  modifiedDate  值与从  note  对象中获取的  modifiedDate  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.MODIFIED_DATE, modifiedDate);//将  modifiedDate  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mModifiedDate = modifiedDate;//将从  note  对象中获取的  modifiedDate  值赋值给当前笔记的  modifiedDate  字段。
long parentId = note.has(NoteColumns.PARENT_ID) ? note
.getLong(NoteColumns.PARENT_ID) : 0;//获取  note  对象的  parentId  字段的值,如果该字段不存在,则使用 0 作为默认值。
if (mIsCreate || mParentId != parentId) {//如果当前是创建新笔记,或者当前的  parentId  值与从  note  对象中获取的  parentId  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.PARENT_ID, parentId);//将  parentId  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mParentId = parentId;//将从  note  对象中获取的  parentId  值赋值给当前笔记的  parentId  字段。
String snippet = note.has(NoteColumns.SNIPPET) ? note
.getString(NoteColumns.SNIPPET) : "";//获取  note  对象的  snippet  字段的值,如果该字段不存在,则使用空字符串作为默认值。
if (mIsCreate || !mSnippet.equals(snippet)) {//如果当前是创建新笔记,或者当前的  snippet  值与从  note  对象中获取的  snippet  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.SNIPPET, snippet);//将  snippet  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mSnippet = snippet;//将从  note  对象中获取的  snippet  值赋值给当前笔记的  snippet  字段。
int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE)
: Notes.TYPE_NOTE;//获取  note  对象的  type  字段的值,如果该字段不存在,则使用  Notes.TYPE_NOTE  作为默认值。
if (mIsCreate || mType != type) {//如果当前是创建新笔记,或者当前的  type  值与从  note  对象中获取的  type  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.TYPE, type);//将  type  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mType = type;//从  note  对象中获取的  type  值赋值给当前笔记的  type  字段。
int widgetId = note.has(NoteColumns.WIDGET_ID) ? note.getInt(NoteColumns.WIDGET_ID)
: AppWidgetManager.INVALID_APPWIDGET_ID;.//获取  note  对象的  widgetId  字段的值,如果该字段不存在,则使用无效的小部件 ID 作为默认值。
if (mIsCreate || mWidgetId != widgetId) {//如果当前是创建新笔记,或者当前的  widgetId  值与从  note  对象中获取的  widgetId  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.WIDGET_ID, widgetId);//将  widgetId  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mWidgetId = widgetId;//将从  note  对象中获取的  widgetId  值赋值给当前笔记的  widgetId  字段。
int widgetType = note.has(NoteColumns.WIDGET_TYPE) ? note
.getInt(NoteColumns.WIDGET_TYPE) : Notes.TYPE_WIDGET_INVALIDE;//获取  note  对象的  widgetType  字段的值,如果该字段不存在,则使用无效的小部件类型作为默认值。
if (mIsCreate || mWidgetType != widgetType) {//如果当前是创建新笔记,或者当前的  widgetType  值与从  note  对象中获取的  widgetType  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.WIDGET_TYPE, widgetType);//将  widgetType  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mWidgetType = widgetType;//将从  note  对象中获取的  widgetType  值赋值给当前笔记的  widgetType  字段。
long originParent = note.has(NoteColumns.ORIGIN_PARENT_ID) ? note
.getLong(NoteColumns.ORIGIN_PARENT_ID) : 0;//获取  note  对象的  originParent  字段的值,如果该字段不存在,则使用 0 作为默认值。
if (mIsCreate || mOriginParent != originParent) {//如果当前是创建新笔记,或者当前的  originParent  值与从  note  对象中获取的  originParent  值不相等,则执行以下操作。
mDiffNoteValues.put(NoteColumns.ORIGIN_PARENT_ID, originParent);//将  originParent  值添加到  mDiffNoteValues  对象中,以便在提交笔记时进行更新。
}
mOriginParent = originParent;//将从  note  对象中获取的  originParent  值赋值给当前笔记的  originParent  字段。
for (int i = 0; i < dataArray.length(); i++) {//遍历  dataArray  数组,对每个元素执行以下操作。
JSONObject data = dataArray.getJSONObject(i);//获取当前元素,并将其转换为  JSONObject  类型。
SqlData sqlData = null;.//创建一个  SqlData  对象,并将其初始化为  null 
if (data.has(DataColumns.ID)) {//如果  data  对象包含名为  DataColumns.ID  的字段,则执行以下操作
long dataId = data.getLong(DataColumns.ID);//获取该字段的值,并将其转换为  long  类型。
for (SqlData temp : mDataList) {//遍历  mDataList  列表,对每个元素执行以下操作。
if (dataId == temp.getId()) {//如果当前元素的  id  值与  dataId  相等,则执行以下操作。
sqlData = temp;//将当前元素赋值给  sqlData  变量。
}
}
}
if (sqlData == null) {//如果  sqlData  变量仍然为  null 则执行以下操作。
sqlData = new SqlData(mContext);//创建一个新的  SqlData  对象,并将其赋值给  sqlData  变量。
mDataList.add(sqlData);//新创建的  SqlData  对象添加到  mDataList  列表中。
}
sqlData.setContent(data);//将 data 的内容设置到 sqlData 中。
}
}
} catch (JSONException e) {//如果在解析 JSONObject 时发生 JSONException 异常则执行以下操作。
Log.e(TAG, e.toString());//使用 Log.e 方法输出错误日志其中包含异常的详细信息。
e.printStackTrace();//打印异常的堆栈跟踪信息。
return false;//返回 false 表示设置内容失败。
}
return true;//返回 true 表示设置内容成功。
}
public JSONObject getContent() {//定义一个公共方法 getContent 用于获取笔记的内容。
try {//在 try 代码块中执行以下操作。
JSONObject js = new JSONObject();//创建一个新的 JSONObject 对象 js 
if (mIsCreate) {//如果笔记是新创建的,则执行以下操作。
Log.e(TAG, "it seems that we haven't created this in database yet");//输出一条错误日志,提示笔记似乎还没有在数据库中创建。
return null;//返回 null 表示获取内容失败。
}
JSONObject note = new JSONObject();//创建一个新的 JSONObject 对象 note 
if (mType == Notes.TYPE_NOTE) {//如果笔记的类型是普通笔记,则执行以下操作。
note.put(NoteColumns.ID, mId);//将笔记的 ID 添加到 note 对象中。
note.put(NoteColumns.ALERTED_DATE, mAlertDate);//将笔记的提醒日期添加到 note 对象中。
note.put(NoteColumns.BG_COLOR_ID, mBgColorId);//将笔记的背景颜色 ID 添加到 note 对象中。
note.put(NoteColumns.CREATED_DATE, mCreatedDate);//将笔记的创建日期添加到 note 对象中。
note.put(NoteColumns.HAS_ATTACHMENT, mHasAttachment);//将笔记是否有附件添加到 note 对象中。
note.put(NoteColumns.MODIFIED_DATE, mModifiedDate);//将笔记的修改日期添加到 note 对象中。
note.put(NoteColumns.PARENT_ID, mParentId);//将笔记的父 ID 添加到 note 对象中。
note.put(NoteColumns.SNIPPET, mSnippet);//将笔记的片段添加到 note 对象中。
note.put(NoteColumns.TYPE, mType);//将笔记的类型添加到 note 对象中。
note.put(NoteColumns.WIDGET_ID, mWidgetId);//将笔记的小部件 ID 添加到 note 对象中。
note.put(NoteColumns.WIDGET_TYPE, mWidgetType);//将笔记的小部件类型添加到 note 对象中。
note.put(NoteColumns.ORIGIN_PARENT_ID, mOriginParent);//将笔记的原始父 ID 添加到 note 对象中。
js.put(GTaskStringUtils.META_HEAD_NOTE, note);//将 note 对象添加到 js 对象中键为 GTaskStringUtils.META_HEAD_NOTE 
JSONArray dataArray = new JSONArray();//创建一个新的 JSONArray 对象 dataArray 
for (SqlData sqlData : mDataList) {//遍历 mDataList 列表中的每个 SqlData 对象。
JSONObject data = sqlData.getContent();//获取当前 SqlData 对象的内容并将其转换为 JSONObject 对象。
if (data != null) {//如果 data 对象不为 null 则执行以下操作。
dataArray.put(data);//将 data 对象添加到 dataArray 对象中。
}
}
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);//将 dataArray 对象添加到 js 对象中键为 GTaskStringUtils.META_HEAD_DATA 
} else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) {//如果笔记的类型是文件夹或系统文件夹,则执行以下操作。
note.put(NoteColumns.ID, mId);//将笔记的 ID 添加到 note 对象中。
note.put(NoteColumns.TYPE, mType);//将笔记的类型添加到 note 对象中。
note.put(NoteColumns.SNIPPET, mSnippet);//将笔记的片段添加到 note 对象中。
js.put(GTaskStringUtils.META_HEAD_NOTE, note);// note 对象添加到 js 对象中键为 GTaskStringUtils.META_HEAD_NOTE 
}
return js;//返回 js 对象其中包含笔记的内容。
} catch (JSONException e) {//如果在创建 JSONObject  JSONArray 时发生 JSONException 异常则执行以下操作。
Log.e(TAG, e.toString());//使用 Log.e 方法输出错误日志其中包含异常的详细信息。
e.printStackTrace();//打印异常的堆栈跟踪信息。
}
return null;//返回 null 表示获取内容失败。
}
public void setParentId(long id) {//定义一个公共方法 setParentId 用于设置笔记的父 ID 
mParentId = id;//将 id 赋值给成员变量 mParentId 
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);//将 id 添加到 mDiffNoteValues 对象中以便在提交更改时更新数据库中的父 ID 
}
public void setGtaskId(String gid) {//定义一个公共方法 setGtaskId 用于设置笔记的 gtask_id 
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);//将 gid 添加到 mDiffNoteValues 对象中以便在提交更改时更新数据库中的 gtask_id 
}
public void setSyncId(long syncId) {//定义一个公共方法 setSyncId 用于设置笔记的同步 ID 
mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId);//将 syncId 添加到 mDiffNoteValues 对象中以便在提交更改时更新数据库中的同步 ID 
}
public void resetLocalModified() {//定义一个公共方法 resetLocalModified 用于重置笔记的本地修改状态。
mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0);//将 0 添加到 mDiffNoteValues 对象中以便在提交更改时将本地修改状态重置为 false 
}
public long getId() {//定义一个公共方法 getId 用于获取笔记的 ID 
return mId;//返回成员变量 mId 的值即笔记的 ID 
}
public long getParentId() {//定义一个公共方法 getParentId 用于获取笔记的父 ID 
return mParentId;//返回成员变量 mParentId 的值即笔记的父 ID 
}
public String getSnippet() {//定义一个公共方法 getSnippet 用于获取笔记的片段。
return mSnippet;//返回成员变量 mSnippet 的值即笔记的片段。
}
public boolean isNoteType() {//定义一个公共方法 isNoteType 用于判断笔记是否为普通笔记。
return mType == Notes.TYPE_NOTE;//返回一个布尔值,表示笔记的类型是否为普通笔记。
}
public void commit(boolean validateVersion) {//定义一个公共方法 commit 用于提交笔记的更改。
if (mIsCreate) {//如果笔记是新创建的,则执行以下操作。
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {//如果笔记的 ID 为无效值 INVALID_ID 并且 mDiffNoteValues 对象中包含 NoteColumns.ID 则执行以下操作。
mDiffNoteValues.remove(NoteColumns.ID);//从 mDiffNoteValues 对象中删除 NoteColumns.ID 键及其对应的值。
}
Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues);//使用 mContentResolver 对象的 insert 方法将 mDiffNoteValues 对象中的数据插入到数据库中并获取插入后生成的 Uri 对象。
try {//在 try 代码块中执行以下操作。
mId = Long.valueOf(uri.getPathSegments().get(1));//从 uri 对象中获取路径段的第二个元素并将其转换为 long 类型然后赋值给成员变量 mId 
} catch (NumberFormatException e) {//如果在将路径段元素转换为 long 类型时发生 NumberFormatException 异常则执行以下操作
Log.e(TAG, "Get note id error :" + e.toString());//使用 Log.e 方法输出错误日志其中包含异常的详细信息。
throw new ActionFailureException("create note failed");//抛出一个 ActionFailureException 异常提示创建笔记失败。
}
if (mId == 0) {//如果笔记的 ID 为 0则执行以下操作。
throw new IllegalStateException("Create thread id failed");//出一个 IllegalStateException 异常提示创建线程 ID 失败。
}
if (mType == Notes.TYPE_NOTE) {//果笔记的类型是普通笔记,则执行以下操作。
for (SqlData sqlData : mDataList) {//遍历 mDataList 列表中的每个 SqlData 对象。
sqlData.commit(mId, false, -1);//调用 sqlData 对象的 commit 方法将笔记的 ID 、是否验证版本和版本号作为参数传递给该方法。
}
}
} else {//如果笔记不是新创建的,则执行以下操作。
if (mId <= 0 && mId != Notes.ID_ROOT_FOLDER && mId != Notes.ID_CALL_RECORD_FOLDER) {//如果笔记的 ID 小于等于 0并且不等于根文件夹 ID 和通话记录文件夹 ID 则执行以下操作。
Log.e(TAG, "No such note");//使用 Log.e 方法输出错误日志提示没有找到这样的笔记。
throw new IllegalStateException("Try to update note with invalid id");//抛出一个 IllegalStateException 异常提示尝试使用无效的 ID 更新笔记。
}
if (mDiffNoteValues.size() > 0) {//如果 mDiffNoteValues 对象中包含的键值对数量大于 0则执行以下操作。
mVersion ++;//将成员变量 mVersion 的值加 1。
int result = 0;//定义一个整型变量 result 并将其初始化为 0。
if (!validateVersion) {//如果不验证版本,则执行以下操作。
result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "("
+ NoteColumns.ID + "=?)", new String[] {
String.valueOf(mId)
});//使用 mContentResolver 对象的 update 方法更新数据库中的笔记数据 mDiffNoteValues 对象中的键值对作为更新的数据 NoteColumns.ID 作为条件 mId 作为条件的值。
} else {
result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "("
+ NoteColumns.ID + "=?) AND (" + NoteColumns.VERSION + "<=?)",
new String[] {
String.valueOf(mId), String.valueOf(mVersion)
});//使用 mContentResolver 对象的 update 方法更新数据库中的笔记数据 mDiffNoteValues 对象中的键值对作为更新的数据 NoteColumns.ID  NoteColumns.VERSION 作为条件 mId  mVersion 作为条件的值。
}
if (result == 0) {//如果更新操作没有成功执行(即更新的行数为 0则执行以下操作。
Log.w(TAG, "there is no update. maybe user updates note when syncing");//使用 Log.w 方法输出警告日志提示没有更新笔记可能是用户在同步时更新了笔记。
}
}
if (mType == Notes.TYPE_NOTE) {//如果笔记的类型是普通笔记,则执行以下操作。
for (SqlData sqlData : mDataList) {//遍历 mDataList 列表中的每个 SqlData 对象。
sqlData.commit(mId, validateVersion, mVersion);//调用 sqlData 对象的 commit 方法将笔记的 ID 、是否验证版本和版本号作为参数传递给该方法。
}
}
}
// refresh local info
loadFromCursor(mId);//从数据库中加载笔记的最新信息。
if (mType == Notes.TYPE_NOTE)//如果笔记的类型是普通笔记,则执行以下操作。
loadDataContent();//加载笔记的数据内容。
mDiffNoteValues.clear();//清空 mDiffNoteValues 对象中的键值对。
mIsCreate = false;//将成员变量 mIsCreate 的值设置为 false 表示笔记不再是新创建的。
}
}