From bb2a2cce6864648169cdc20ed8854712e4ac04d7 Mon Sep 17 00:00:00 2001 From: hmh <2150887269@qq.com> Date: Thu, 12 Jun 2025 14:53:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=AF=B9model=E9=87=8C?= =?UTF-8?q?=E9=9D=A2=E4=B8=A4=E4=B8=AAjava=E6=96=87=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/net/micode/notes/model/Note.java | 116 ++++++++-- .../net/micode/notes/model/WorkingNote.java | 217 +++++++++++++++--- 2 files changed, 285 insertions(+), 48 deletions(-) diff --git a/src/Notes/Notes/app/src/main/java/net/micode/notes/model/Note.java b/src/Notes/Notes/app/src/main/java/net/micode/notes/model/Note.java index 6706cf6..fef9168 100644 --- a/src/Notes/Notes/app/src/main/java/net/micode/notes/model/Note.java +++ b/src/Notes/Notes/app/src/main/java/net/micode/notes/model/Note.java @@ -15,6 +15,7 @@ */ package net.micode.notes.model; + import android.content.ContentProviderOperation; import android.content.ContentProviderResult; import android.content.ContentUris; @@ -33,16 +34,25 @@ import net.micode.notes.data.Notes.TextNote; import java.util.ArrayList; - +/** + * Note 类用于管理笔记的相关数据,包括创建新笔记 ID、设置笔记值、同步笔记数据等操作。 + */ public class Note { + // 笔记差异值 private ContentValues mNoteDiffValues; + // 笔记数据对象 private NoteData mNoteData; + // 日志标签 private static final String TAG = "Note"; + /** - * Create a new note id for adding a new note to databases + * 创建一个新的笔记 ID 用于添加新笔记到数据库 + * @param context 上下文对象 + * @param folderId 文件夹 ID + * @return 新的笔记 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(); values.put(NoteColumns.CREATED_DATE, createdTime); @@ -50,6 +60,7 @@ public class Note { values.put(NoteColumns.TYPE, Notes.TYPE_NOTE); values.put(NoteColumns.LOCAL_MODIFIED, 1); values.put(NoteColumns.PARENT_ID, folderId); + // 插入新笔记到数据库 Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values); long noteId = 0; @@ -65,41 +76,81 @@ public class Note { return noteId; } + /** + * 构造函数,初始化笔记差异值和笔记数据对象 + */ public Note() { mNoteDiffValues = new ContentValues(); mNoteData = new NoteData(); } + /** + * 设置笔记的某个值 + * @param key 键 + * @param value 值 + */ public void setNoteValue(String key, String value) { mNoteDiffValues.put(key, value); mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1); mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis()); } + /** + * 设置文本笔记数据的某个值 + * @param key 键 + * @param value 值 + */ public void setTextData(String key, String value) { mNoteData.setTextData(key, value); } + /** + * 设置文本笔记数据的 ID + * @param id 文本笔记数据的 ID + */ public void setTextDataId(long id) { mNoteData.setTextDataId(id); } + /** + * 获取文本笔记数据的 ID + * @return 文本笔记数据的 ID + */ public long getTextDataId() { return mNoteData.mTextDataId; } + /** + * 设置通话笔记数据的 ID + * @param id 通话笔记数据的 ID + */ public void setCallDataId(long id) { mNoteData.setCallDataId(id); } + /** + * 设置通话笔记数据的某个值 + * @param key 键 + * @param value 值 + */ public void setCallData(String key, String value) { mNoteData.setCallData(key, value); } + /** + * 判断笔记是否有本地修改 + * @return 是否有本地修改 + */ public boolean isLocalModified() { return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified(); } + /** + * 同步笔记数据到数据库 + * @param context 上下文对象 + * @param noteId 笔记 ID + * @return 同步是否成功 + */ public boolean syncNote(Context context, long noteId) { if (noteId <= 0) { throw new IllegalArgumentException("Wrong note id:" + noteId); @@ -110,15 +161,14 @@ public class Note { } /** - * 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 + * 理论上,一旦数据发生变化,笔记的 LOCAL_MODIFIED 和 MODIFIED_DATE 应该更新。 + * 为了数据安全,即使更新笔记失败,也会更新笔记数据信息。 */ if (context.getContentResolver().update( ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), mNoteDiffValues, null, null) == 0) { Log.e(TAG, "Update note error, should not happen"); - // Do not return, fall through + // 不返回,继续执行 } mNoteDiffValues.clear(); @@ -130,17 +180,24 @@ public class Note { 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"; + /** + * 构造函数,初始化文本和通话笔记数据的值和 ID + */ public NoteData() { mTextDataValues = new ContentValues(); mCallDataValues = new ContentValues(); @@ -148,10 +205,18 @@ public class Note { mCallDataId = 0; } + /** + * 判断笔记数据是否有本地修改 + * @return 是否有本地修改 + */ boolean isLocalModified() { return mTextDataValues.size() > 0 || mCallDataValues.size() > 0; } + /** + * 设置文本笔记数据的 ID + * @param id 文本笔记数据的 ID + */ void setTextDataId(long id) { if(id <= 0) { throw new IllegalArgumentException("Text data id should larger than 0"); @@ -159,6 +224,10 @@ public class Note { mTextDataId = id; } + /** + * 设置通话笔记数据的 ID + * @param id 通话笔记数据的 ID + */ void setCallDataId(long id) { if (id <= 0) { throw new IllegalArgumentException("Call data id should larger than 0"); @@ -166,21 +235,37 @@ public class Note { mCallDataId = id; } + /** + * 设置通话笔记数据的某个值 + * @param key 键 + * @param value 值 + */ void setCallData(String key, String value) { mCallDataValues.put(key, value); mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1); mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis()); } + /** + * 设置文本笔记数据的某个值 + * @param key 键 + * @param value 值 + */ void setTextData(String key, String value) { mTextDataValues.put(key, value); mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1); mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis()); } + /** + * 将笔记数据推送到 ContentResolver 中 + * @param context 上下文对象 + * @param noteId 笔记 ID + * @return 操作结果的 Uri + */ Uri pushIntoContentResolver(Context context, long noteId) { /** - * Check for safety + * 安全检查 */ if (noteId <= 0) { throw new IllegalArgumentException("Wrong note id:" + noteId); @@ -192,6 +277,7 @@ public class Note { if(mTextDataValues.size() > 0) { mTextDataValues.put(DataColumns.NOTE_ID, noteId); if (mTextDataId == 0) { + // 插入新的文本笔记数据 mTextDataValues.put(DataColumns.MIME_TYPE, TextNote.CONTENT_ITEM_TYPE); Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI, mTextDataValues); @@ -203,6 +289,7 @@ public class Note { return null; } } else { + // 更新现有的文本笔记数据 builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mTextDataId)); builder.withValues(mTextDataValues); @@ -214,6 +301,7 @@ public class Note { if(mCallDataValues.size() > 0) { mCallDataValues.put(DataColumns.NOTE_ID, noteId); if (mCallDataId == 0) { + // 插入新的通话笔记数据 mCallDataValues.put(DataColumns.MIME_TYPE, CallNote.CONTENT_ITEM_TYPE); Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI, mCallDataValues); @@ -225,6 +313,7 @@ public class Note { return null; } } else { + // 更新现有的通话笔记数据 builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mCallDataId)); builder.withValues(mCallDataValues); @@ -235,6 +324,7 @@ public class Note { if (operationList.size() > 0) { try { + // 批量执行操作 ContentProviderResult[] results = context.getContentResolver().applyBatch( Notes.AUTHORITY, operationList); return (results == null || results.length == 0 || results[0] == null) ? null @@ -250,4 +340,4 @@ public class Note { return null; } } -} +} \ No newline at end of file diff --git a/src/Notes/Notes/app/src/main/java/net/micode/notes/model/WorkingNote.java b/src/Notes/Notes/app/src/main/java/net/micode/notes/model/WorkingNote.java index be081e4..92b223e 100644 --- a/src/Notes/Notes/app/src/main/java/net/micode/notes/model/WorkingNote.java +++ b/src/Notes/Notes/app/src/main/java/net/micode/notes/model/WorkingNote.java @@ -31,37 +31,41 @@ import net.micode.notes.data.Notes.NoteColumns; import net.micode.notes.data.Notes.TextNote; import net.micode.notes.tool.ResourceParser.NoteBgResources; - +/** + * WorkingNote 类用于管理和操作笔记的相关信息,包括笔记的基本属性、内容、模式等, + * 同时提供了创建、加载、保存笔记等功能。 + */ public class WorkingNote { - // Note for the working note + // 笔记对象 private Note mNote; - // Note Id + // 笔记的 ID private long mNoteId; - // Note content + // 笔记的内容 private String mContent; - // Note mode + // 笔记的模式 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; - + // 笔记设置变化监听器 private NoteSettingChangedListener mNoteSettingStatusListener; + // 数据查询的投影列 public static final String[] DATA_PROJECTION = new String[] { DataColumns.ID, DataColumns.CONTENT, @@ -72,6 +76,7 @@ public class WorkingNote { DataColumns.DATA4, }; + // 笔记查询的投影列 public static final String[] NOTE_PROJECTION = new String[] { NoteColumns.PARENT_ID, NoteColumns.ALERTED_DATE, @@ -81,27 +86,32 @@ public class WorkingNote { 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; - + // 笔记父 ID 列的索引 private static final int NOTE_PARENT_ID_COLUMN = 0; - + // 笔记提醒日期列的索引 private static final int NOTE_ALERTED_DATE_COLUMN = 1; - + // 笔记背景颜色 ID 列的索引 private static final int NOTE_BG_COLOR_ID_COLUMN = 2; - + // 笔记小部件 ID 列的索引 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 + /** + * 新建笔记的构造函数 + * @param context 上下文对象 + * @param folderId 文件夹 ID + */ private WorkingNote(Context context, long folderId) { mContext = context; mAlertDate = 0; @@ -114,7 +124,12 @@ public class WorkingNote { mWidgetType = Notes.TYPE_WIDGET_INVALIDE; } - // Existing note construct + /** + * 加载现有笔记的构造函数 + * @param context 上下文对象 + * @param noteId 笔记 ID + * @param folderId 文件夹 ID + */ private WorkingNote(Context context, long noteId, long folderId) { mContext = context; mNoteId = noteId; @@ -124,13 +139,18 @@ public class WorkingNote { loadNote(); } + /** + * 加载笔记的基本信息 + */ private void loadNote() { + // 查询笔记的基本信息 Cursor cursor = mContext.getContentResolver().query( ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId), NOTE_PROJECTION, null, null, null); if (cursor != null) { if (cursor.moveToFirst()) { + // 获取笔记的相关信息 mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN); mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN); mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN); @@ -143,10 +163,15 @@ public class WorkingNote { Log.e(TAG, "No note with id:" + mNoteId); throw new IllegalArgumentException("Unable to find note with id " + mNoteId); } + // 加载笔记的数据 loadNoteData(); } + /** + * 加载笔记的数据信息 + */ private void loadNoteData() { + // 查询笔记的数据信息 Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION, DataColumns.NOTE_ID + "=?", new String[] { String.valueOf(mNoteId) @@ -155,12 +180,15 @@ public class WorkingNote { if (cursor != null) { if (cursor.moveToFirst()) { do { + // 获取数据的 MIME 类型 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); mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN)); } else if (DataConstants.CALL_NOTE.equals(type)) { + // 通话笔记数据 mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN)); } else { Log.d(TAG, "Wrong note type with type:" + type); @@ -174,6 +202,15 @@ public class WorkingNote { } } + /** + * 创建一个空的笔记 + * @param context 上下文对象 + * @param folderId 文件夹 ID + * @param widgetId 小部件 ID + * @param widgetType 小部件类型 + * @param defaultBgColorId 默认背景颜色 ID + * @return 新创建的 WorkingNote 对象 + */ public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId, int widgetType, int defaultBgColorId) { WorkingNote note = new WorkingNote(context, folderId); @@ -183,23 +220,34 @@ public class WorkingNote { return note; } + /** + * 加载一个已有的笔记 + * @param context 上下文对象 + * @param id 笔记 ID + * @return 加载的 WorkingNote 对象 + */ public static WorkingNote load(Context context, long id) { return new WorkingNote(context, id, 0); } + /** + * 保存笔记 + * @return 保存是否成功 + */ 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 @@ -212,10 +260,18 @@ public class WorkingNote { } } + /** + * 判断笔记是否存在于数据库中 + * @return 是否存在 + */ public boolean existInDatabase() { return mNoteId > 0; } + /** + * 判断笔记是否值得保存 + * @return 是否值得保存 + */ private boolean isWorthSaving() { if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent)) || (existInDatabase() && !mNote.isLocalModified())) { @@ -225,10 +281,19 @@ public class WorkingNote { } } + /** + * 设置笔记设置变化监听器 + * @param l 监听器对象 + */ public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) { mNoteSettingStatusListener = l; } + /** + * 设置笔记的提醒日期 + * @param date 提醒日期 + * @param set 是否设置提醒 + */ public void setAlertDate(long date, boolean set) { if (date != mAlertDate) { mAlertDate = date; @@ -239,6 +304,10 @@ public class WorkingNote { } } + /** + * 标记笔记是否被删除 + * @param mark 是否删除 + */ public void markDeleted(boolean mark) { mIsDeleted = mark; if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID @@ -247,6 +316,10 @@ public class WorkingNote { } } + /** + * 设置笔记的背景颜色 ID + * @param id 背景颜色 ID + */ public void setBgColorId(int id) { if (id != mBgColorId) { mBgColorId = id; @@ -257,6 +330,10 @@ public class WorkingNote { } } + /** + * 设置笔记的清单模式 + * @param mode 清单模式 + */ public void setCheckListMode(int mode) { if (mMode != mode) { if (mNoteSettingStatusListener != null) { @@ -267,6 +344,10 @@ public class WorkingNote { } } + /** + * 设置笔记关联的小部件类型 + * @param type 小部件类型 + */ public void setWidgetType(int type) { if (type != mWidgetType) { mWidgetType = type; @@ -274,6 +355,10 @@ public class WorkingNote { } } + /** + * 设置笔记关联的小部件 ID + * @param id 小部件 ID + */ public void setWidgetId(int id) { if (id != mWidgetId) { mWidgetId = id; @@ -281,6 +366,10 @@ public class WorkingNote { } } + /** + * 设置笔记的文本内容 + * @param text 文本内容 + */ public void setWorkingText(String text) { if (!TextUtils.equals(mContent, text)) { mContent = text; @@ -288,81 +377,139 @@ public class WorkingNote { } } + /** + * 将笔记转换为通话笔记 + * @param phoneNumber 电话号码 + * @param callDate 通话日期 + */ public void convertToCallNote(String phoneNumber, long callDate) { mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate)); mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber); mNote.setNoteValue(NoteColumns.PARENT_ID, String.valueOf(Notes.ID_CALL_RECORD_FOLDER)); } + /** + * 判断笔记是否设置了提醒 + * @return 是否设置了提醒 + */ public boolean hasClockAlert() { return (mAlertDate > 0 ? true : false); } + /** + * 获取笔记的内容 + * @return 笔记内容 + */ public String getContent() { return mContent; } + /** + * 获取笔记的提醒日期 + * @return 提醒日期 + */ public long getAlertDate() { return mAlertDate; } + /** + * 获取笔记的修改日期 + * @return 修改日期 + */ public long getModifiedDate() { return mModifiedDate; } + /** + * 获取笔记的背景颜色资源 ID + * @return 背景颜色资源 ID + */ public int getBgColorResId() { return NoteBgResources.getNoteBgResource(mBgColorId); } + /** + * 获取笔记的背景颜色 ID + * @return 背景颜色 ID + */ public int getBgColorId() { return mBgColorId; } + /** + * 获取笔记标题的背景资源 ID + * @return 标题背景资源 ID + */ public int getTitleBgResId() { return NoteBgResources.getNoteTitleBgResource(mBgColorId); } + /** + * 获取笔记的清单模式 + * @return 清单模式 + */ public int getCheckListMode() { return mMode; } + /** + * 获取笔记的 ID + * @return 笔记 ID + */ public long getNoteId() { return mNoteId; } + /** + * 获取笔记所在的文件夹 ID + * @return 文件夹 ID + */ public long getFolderId() { return mFolderId; } + /** + * 获取笔记关联的小部件 ID + * @return 小部件 ID + */ public int getWidgetId() { return mWidgetId; } + /** + * 获取笔记关联的小部件类型 + * @return 小部件类型 + */ 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 + * 当用户设置提醒时调用 + * @param date 提醒日期 + * @param set 是否设置提醒 */ 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 + * 当笔记的清单模式发生切换时调用 + * @param oldMode 旧模式 + * @param newMode 新模式 */ void onCheckListModeChanged(int oldMode, int newMode); } -} +} \ No newline at end of file