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.
xiaomi-Notes/WorkingNote.java

446 lines
22 KiB

This file contains ambiguous Unicode 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.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;
public class WorkingNote {//定义了一个公开的类 WorkingNote。这个类是公开的意味着它可以被其他类访问。
// Note for the working note
private Note mNote;//定义了一个私有的 Note 类型的成员变量 mNote
// Note Id
private long mNoteId;//定义了一个私有的 long 类型的成员变量 mNoteId用于存储笔记的唯一标识符。
// Note content
private String mContent;//定义了一个私有的 String 类型的成员变量 mContent用于存储笔记的文本内容。
// Note mode
private int mMode;//定义了一个私有的 int 类型的成员变量 mMode
private long mAlertDate;//定义了一个私有的 long 类型的成员变量 mAlertDate用于存储笔记的提醒日期。
private long mModifiedDate;//定义了一个私有的 long 类型的成员变量 mModifiedDate用于存储笔记的最后修改日期。
private int mBgColorId;//定义了一个私有的 int 类型的成员变量 mBgColorId用于存储笔记背景颜色的ID。
private int mWidgetId;//定义了一个私有的 int 类型的成员变量 mWidgetId
private int mWidgetType;//定义了一个私有的 int 类型的成员变量 mWidgetType
private long mFolderId;//定义了一个私有的 long 类型的成员变量 mFolderId用于存储笔记所属的文件夹ID。
private Context mContext;//定义了一个私有的 Context 类型的成员变量 mContextContext 是一个抽象类,它允许访问特定资源和应用级操作,如启动活动、广播和接收意图等
private static final String TAG = "WorkingNote";//定义了一个私有的静态常量 TAG其值为字符串 "WorkingNote"。这个常量通常用于日志记录,以便识别日志消息来自哪个类。
private boolean mIsDeleted;//定义了一个私有的 boolean 类型的成员变量 mIsDeleted用于表示笔记是否被删除。
private NoteSettingChangedListener mNoteSettingStatusListener;//定义了一个私有的 NoteSettingChangedListener 类型的成员变量 mNoteSettingStatusListener。
public static final String[] DATA_PROJECTION = new String[] {
//定义了一个公开的静态常量 DATA_PROJECTION它是一个字符串数组包含了用于数据查询的列名。
DataColumns.ID,
DataColumns.CONTENT,
DataColumns.MIME_TYPE,
DataColumns.DATA1,
DataColumns.DATA2,
DataColumns.DATA3,
DataColumns.DATA4,
};
public static final String[] NOTE_PROJECTION = new String[] {
//public static final String[] NOTE_PROJECTION = new String[] { ... }; - 定义了一个公开的静态常量 NOTE_PROJECTION它也是一个字符串数组包含了用于笔记查询的列名
NoteColumns.PARENT_ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.MODIFIED_DATE
};
private static final int DATA_ID_COLUMN = 0;
private static final int DATA_CONTENT_COLUMN = 1;
private static final int DATA_MIME_TYPE_COLUMN = 2;
private static final int DATA_MODE_COLUMN = 3;
private static final int NOTE_PARENT_ID_COLUMN = 0;
private static final int NOTE_ALERTED_DATE_COLUMN = 1;
private static final int NOTE_BG_COLOR_ID_COLUMN = 2;
private static final int NOTE_WIDGET_ID_COLUMN = 3;
private static final int NOTE_WIDGET_TYPE_COLUMN = 4;
private static final int NOTE_MODIFIED_DATE_COLUMN = 5;
//以上代码定义了一系列的私有静态常量,它们被用作索引来标识从数据库查询返回的结果集中各个列的位置。
// New note construct
private WorkingNote(Context context, long folderId) {
//这是一个私有构造函数用于创建一个新的WorkingNote实例。它接收两个参数context应用程序的上下文和folderId笔记所属的文件夹ID
mContext = context; //将传入的context赋值给成员变量mContext以便后续使用。
mAlertDate = 0;//初始化提醒日期mAlertDate为0表示当前没有设置提醒。
mModifiedDate = System.currentTimeMillis();//初始化修改日期mModifiedDate为当前系统时间的毫秒数表示笔记刚刚被创建。
mFolderId = folderId;//将传入的folderId赋值给成员变量mFolderId。
mNote = new Note();//创建一个新的Note实例并赋值给成员变量mNote。
mNoteId = 0;//初始化笔记IDmNoteId为0表示当前是一个新的笔记还没有被保存到数据库中。
mIsDeleted = false;//初始化删除标记mIsDeleted为false表示笔记没有被删除。
mMode = 0;//初始化模式mMode为0具体的模式含义取决于业务逻辑。
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;//初始化小部件类型mWidgetType为Notes.TYPE_WIDGET_INVALIDE表示当前没有设置小部件类型。
}
// Existing note construct
private WorkingNote(Context context, long noteId, long folderId) {
//这是一个私有构造函数用于加载一个已存在的WorkingNote实例。它接收三个参数context应用程序的上下文、noteId要加载的笔记ID和folderId笔记所属的文件夹ID
mContext = context;//
mNoteId = noteId;
mFolderId = folderId;
mIsDeleted = false;
mNote = new Note();//这部分代码与第一个构造函数中的相应部分类似只是它直接设置了mNoteId和mFolderId。
loadNote();//调用loadNote方法来从数据库中加载笔记的详细信息。
}
private void loadNote() {//这是一个私有方法,用于从数据库中加载笔记的详细信息。
Cursor cursor = mContext.getContentResolver().query(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId), NOTE_PROJECTION, null,
null, null);//使用ContentResolver和ContentUris来构建一个查询以获取指定mNoteId的笔记。NOTE_PROJECTION是一个包含要查询的列名的数组。
if (cursor != null) {//检查查询返回的Cursor是否不为null。
if (cursor.moveToFirst()) {//移动Cursor到第一行如果有数据的话。
mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN);
mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN);
mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN);
mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN);
mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);
mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);
}//从Cursor中读取笔记的详细信息并赋值给相应的成员变量。
cursor.close();//关闭Cursor以释放资源。
} else {
Log.e(TAG, "No note with id:" + mNoteId);
throw new IllegalArgumentException("Unable to find note with id " + mNoteId);
}//如果Cursor为null则记录错误日志并抛出一个IllegalArgumentException异常。
loadNoteData();//调用loadNoteData方法来加载笔记的额外数据
}
private void loadNoteData() {//这是一个私有方法用于从数据库中加载与当前笔记ID (mNoteId) 相关联的笔记数据。
Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION,
DataColumns.NOTE_ID + "=?", new String[] {
String.valueOf(mNoteId)
}, null);
//使用ContentResolver执行查询以获取与mNoteId相关联的笔记数据。Notes.CONTENT_DATA_URI是数据的URIDATA_PROJECTION是包含要查询的列名的数组DataColumns.NOTE_ID + "=?"是选择条件表示只选择NOTE_ID等于mNoteId的行new String[] { String.valueOf(mNoteId) }是选择条件的参数null表示没有排序。
if (cursor != null) {//检查查询返回的Cursor是否不为null。
if (cursor.moveToFirst()) {//移动Cursor到第一行准备读取数据。
do {//开始一个循环,用于遍历所有匹配的行。
String type = cursor.getString(DATA_MIME_TYPE_COLUMN);//从当前行读取数据的MIME类型。
if (DataConstants.NOTE.equals(type)) {//如果MIME类型表示这是一个普通笔记。
mContent = cursor.getString(DATA_CONTENT_COLUMN);
mMode = cursor.getInt(DATA_MODE_COLUMN);
mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN));
//读取笔记的内容、模式和ID并设置到相应的成员变量和mNote对象中。
} else if (DataConstants.CALL_NOTE.equals(type)) {//如果MIME类型表示这是一个与通话相关的笔记。
mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN));//读取并设置与通话相关的数据的ID。
} else {
Log.d(TAG, "Wrong note type with type:" + type);//如果MIME类型不是预期的任何一种则记录一条调试日志
}
} while (cursor.moveToNext());//继续循环,直到遍历完所有匹配的行。
}
cursor.close();//关闭Cursor以释放资源。
} else {
Log.e(TAG, "No data with id:" + mNoteId);
throw new IllegalArgumentException("Unable to find note's data with id " + mNoteId);
}//如果Cursor为null则记录错误日志并抛出一个IllegalArgumentException异常。
}
public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
int widgetType, int defaultBgColorId) {
//这是一个公有的静态方法用于创建一个空的WorkingNote实例。它接收五个参数context应用程序的上下文、folderId笔记所属的文件夹ID、widgetId小部件ID、widgetType小部件类型和defaultBgColorId默认背景颜色ID
WorkingNote note = new WorkingNote(context, folderId);//使用提供的context和folderId创建一个新的WorkingNote实例。
note.setBgColorId(defaultBgColorId);
note.setWidgetId(widgetId);
note.setWidgetType(widgetType);
//设置笔记的背景颜色ID、小部件ID和小部件类型。
return note;//返回创建并设置好的WorkingNote实例。
}
public static WorkingNote load(Context context, long id) {
// 这是一个静态方法用于根据给定的上下文和ID加载一个WorkingNote实例。
return new WorkingNote(context, id, 0);
// 创建一个新的WorkingNote实例并传入上下文、ID和一个默认值0可能是用于文件夹ID或其他目的
}
public synchronized boolean saveNote() {
// 这是一个同步方法用于保存当前WorkingNote实例的数据。
if (isWorthSaving()) {
// 首先检查这个笔记是否值得保存(即是否有必要进行保存操作)。
if (!existInDatabase()) {
// 如果这个笔记还没有存在于数据库中即mNoteId小于或等于0根据existInDatabase方法的实现
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
// 尝试获取一个新的笔记ID如果失败即返回的ID为0则记录错误日志。
Log.e(TAG, "Create new note fail with id:" + mNoteId);
return false;
// 并返回false表示保存失败。
}
}
mNote.syncNote(mContext, mNoteId);
// 将当前笔记的数据同步到数据库中具体实现依赖于mNote对象的syncNote方法
/**
* Update widget content if there exist any widget of this note
*/
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE
&& mNoteSettingStatusListener != null) {
// 如果这个笔记关联了一个小部件,并且这个小部件的类型有效,同时存在一个监听器,
// 则调用监听器的onWidgetChanged方法来更新小部件的内容。
mNoteSettingStatusListener.onWidgetChanged();
}
return true;
// 如果一切顺利则返回true表示保存成功。
} else {
// 如果这个笔记不值得保存即没有必要进行保存操作则直接返回false。
return false;
}
}
public boolean existInDatabase() {
// 这个方法用于检查这个笔记是否已经存在于数据库中。
// 通过检查mNoteId是否大于0来判断假设mNoteId是在数据库中唯一标识笔记的ID
return mNoteId > 0;
}
private boolean isWorthSaving() {
// 这个私有方法用于检查这个笔记是否值得保存。
if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent))
|| (existInDatabase() && !mNote.isLocalModified())) {
// 如果笔记被标记为已删除,或者如果它还没有存在于数据库中但内容为空,
// 或者如果它已经存在于数据库中但本地没有修改过,则认为这个笔记不值得保存。
return false;
} else {
// 否则,认为这个笔记值得保存。
return true;
}
}
public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {
// 设置一个监听器,用于监听笔记设置状态的更改。
// NoteSettingChangedListener 是一个自定义接口,用于回调通知状态变化。
mNoteSettingStatusListener = l;
// 将传入的监听器赋值给成员变量 mNoteSettingStatusListener。
}
public void setAlertDate(long date, boolean set) {
// 设置笔记的提醒日期。
// date 是要设置的提醒日期(以长整型表示的时间戳)。
// set 是一个布尔值,表示是否要设置提醒日期(尽管在这个方法中未直接使用,但可能用于其他逻辑)。
if (date != mAlertDate) {
// 如果传入的日期与当前设置的提醒日期不同。
mAlertDate = date;
// 更新成员变量 mAlertDate。
mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate));
// 将更新后的提醒日期同步到笔记对象中(假设 NoteColumns.ALERTED_DATE 是数据库中的列名)。
}
if (mNoteSettingStatusListener != null) {
// 如果设置了监听器。
mNoteSettingStatusListener.onClockAlertChanged(date, set);
// 调用监听器的 onClockAlertChanged 方法,通知提醒日期已更改。
}
}
public void markDeleted(boolean mark) {
// 标记笔记为已删除或未删除状态。
// mark 是一个布尔值true 表示已删除false 表示未删除。
mIsDeleted = mark;
// 更新成员变量 mIsDeleted。
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) {
// 如果笔记关联了一个小部件,并且这个小部件的类型有效,同时存在一个监听器。
mNoteSettingStatusListener.onWidgetChanged();
// 调用监听器的 onWidgetChanged 方法,通知小部件需要更新。
}
}
public void setBgColorId(int id) {
// 设置笔记的背景颜色ID。
// id 是背景颜色的唯一标识符。
if (id != mBgColorId) {
// 如果传入的ID与当前设置的背景颜色ID不同。
mBgColorId = id;
// 更新成员变量 mBgColorId。
if (mNoteSettingStatusListener != null) {
// 如果设置了监听器。
mNoteSettingStatusListener.onBackgroundColorChanged();
// 调用监听器的 onBackgroundColorChanged 方法,通知背景颜色已更改。
}
mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id));
// 将更新后的背景颜色ID同步到笔记对象中假设 NoteColumns.BG_COLOR_ID 是数据库中的列名)。
}
}
public void setCheckListMode(int mode) {
// 设置笔记的待办事项模式。
// mode 是待办事项模式的标识符。
if (mMode != mode) {
// 如果传入的模式与当前设置的待办事项模式不同。
if (mNoteSettingStatusListener != null) {
// 如果设置了监听器。
mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);
// 调用监听器的 onCheckListModeChanged 方法,通知待办事项模式已更改。
// 注意:这里传递了旧模式和新模式作为参数。
}
mMode = mode;
// 更新成员变量 mMode。
mNote.setTextData(TextNote.MODE, String.valueOf(mMode));
// 将更新后的待办事项模式同步到笔记对象中(假设 TextNote.MODE 是用于存储模式的键)。
}
}
public void setWidgetType(int type) {
// 设置笔记关联的小部件类型。
// type 是小部件类型的标识符。
if (type != mWidgetType) {
// 如果传入的类型与当前设置的小部件类型不同。
mWidgetType = type;
// 更新成员变量 mWidgetType。
mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType));
// 将更新后的小部件类型同步到笔记对象中(假设 NoteColumns.WIDGET_TYPE 是数据库中的列名)。
}
}
// 定义一个方法用于设置小部件ID
public void setWidgetId(int id) {
// 如果传入的ID与当前的小部件ID不同
if (id != mWidgetId) {
// 更新当前的小部件ID
mWidgetId = id;
// 将新的小部件ID存储到笔记中
mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));
}
}
// 定义一个方法,用于设置工作文本
public void setWorkingText(String text) {
// 如果传入的文本与当前的内容不同
if (!TextUtils.equals(mContent, text)) {
// 更新当前的内容
mContent = text;
// 将新的内容存储到笔记的文本数据中
mNote.setTextData(DataColumns.CONTENT, mContent);
}
}
// 定义一个方法,用于将笔记转换为通话笔记
public void convertToCallNote(String phoneNumber, long callDate) {
// 设置通话日期
mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate));
// 设置电话号码
mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber);
// 设置笔记的父ID为通话记录文件夹的ID
mNote.setNoteValue(NoteColumns.PARENT_ID, String.valueOf(Notes.ID_CALL_RECORD_FOLDER));
}
// 定义一个方法,用于检查是否有闹钟提醒
public boolean hasClockAlert() {
// 如果闹钟日期大于0则返回true否则返回false
return (mAlertDate > 0 ? true : false);
}
// 定义一个方法,用于获取内容
public String getContent() {
return mContent;
}
// 定义一个方法,用于获取闹钟日期
public long getAlertDate() {
return mAlertDate;
}
// 定义一个方法,用于获取修改日期
public long getModifiedDate() {
return mModifiedDate;
}
// 定义一个方法用于获取背景颜色资源ID
public int getBgColorResId() {
return NoteBgResources.getNoteBgResource(mBgColorId);
}
// 定义一个方法用于获取背景颜色ID
public int getBgColorId() {
return mBgColorId;
}
// 定义一个方法用于获取标题背景资源ID
public int getTitleBgResId() {
return NoteBgResources.getNoteTitleBgResource(mBgColorId);
}
// 定义一个方法,用于获取检查列表模式
public int getCheckListMode() {
return mMode;
}
// 定义一个方法用于获取笔记ID
public long getNoteId() {
return mNoteId;
}
// 定义一个方法用于获取文件夹ID
public long getFolderId() {
return mFolderId;
}
// 定义一个方法用于获取小部件ID
public int getWidgetId() {
return mWidgetId;
}
// 定义一个方法,用于获取小部件类型
public int getWidgetType() {
return mWidgetType;
}
// 定义一个接口,用于监听笔记设置的更改
public interface NoteSettingChangedListener {
// 当当前笔记的背景颜色刚刚更改时调用
void onBackgroundColorChanged();
// 当用户设置闹钟时调用
void onClockAlertChanged(long date, boolean set);
// 当用户通过小部件创建笔记时调用
void onWidgetChanged();
// 当在检查列表模式和普通模式之间切换时调用
// @param oldMode 是更改之前的模式
// @param newMode 是新的模式
void onCheckListModeChanged(int oldMode, int newMode);
}