();
}
@@ -44,7 +49,9 @@ public class Contact {
if(sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);
}
-
+//缓存没有,就查询数据库
+ //构造一个SQL查询条件:CALLER_ID_SELECTION中的"+"被替换为电话号码的最小匹配值
+ //然后执行查询语句
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
Cursor cursor = context.getContentResolver().query(
@@ -53,6 +60,13 @@ public class Contact {
selection,
new String[] { phoneNumber },
null);
+//判断查询结果:
+ //查询结果不为空,且能够移动到第一条记录:
+ // 那么就尝试从Cursor中获取联系人姓名,并将其存入缓存sContactCache。然后返回联系人姓名。
+ // 异常情况:如果在获取字符串时发生数组越界异常,则记录一个错误日志并返回null。
+ // 最后都要确保关闭Cursor对象,以避免内存泄漏。
+ //如果查询结果为空或者没有记录可以移动到(即没有找到匹配的联系人):
+ // 则记录一条调试日志并返回null
if (cursor != null && cursor.moveToFirst()) {
try {
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/data/Notes.java b/src/Notesmaster/app/src/main/java/net/micode/notes/data/Notes.java
index f240604..59e0e2c 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/data/Notes.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/data/Notes.java
@@ -18,8 +18,10 @@ package net.micode.notes.data;
import android.net.Uri;
public class Notes {
+ // 这里是定义了基本的信息,即认证信息和日志输出时的标志,方便我们了解日志信息是由谁发出的。
public static final String AUTHORITY = "micode_notes";
public static final String TAG = "Notes";
+ // 这边定义了note表中,类型行的3种取值:
public static final int TYPE_NOTE = 0;
public static final int TYPE_FOLDER = 1;
public static final int TYPE_SYSTEM = 2;
@@ -30,11 +32,16 @@ public class Notes {
* {@link Notes#ID_TEMPARAY_FOLDER } is for notes belonging no folder
* {@link Notes#ID_CALL_RECORD_FOLDER} is to store call records
*/
+ // ID_ROOT_FOLDER:默认文件夹
+ // ID_TEMPARAY_FOLDER:不属于文件夹的笔记
+ // ID_CALL_RECORD_FOLDER:用于存储通话记录,以便返回
+ // ID_TRASH_FOLER:垃圾回收站
public static final int ID_ROOT_FOLDER = 0;
public static final int ID_TEMPARAY_FOLDER = -1;
public static final int ID_CALL_RECORD_FOLDER = -2;
public static final int ID_TRASH_FOLER = -3;
+ // 个人理解为就是定义一些布局的ID,这部分就是用于设置UI界面的一些布局或小组件的id。
public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date";
public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id";
public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id";
@@ -46,6 +53,7 @@ public class Notes {
public static final int TYPE_WIDGET_2X = 0;
public static final int TYPE_WIDGET_4X = 1;
+ // 这里定义了两种数据类型:文本便签和通话记录
public static class DataConstants {
public static final String NOTE = TextNote.CONTENT_ITEM_TYPE;
public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE;
@@ -54,12 +62,16 @@ public class Notes {
/**
* Uri to query all notes and folders
*/
+ // Android开发中常见的用于定义内容提供者(Content Provider)URI,内容提供者是一种Android组件,它允许应用程序共享和存储数据。这里定义了一个URI来查询数据
public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note");
/**
* Uri to query data
*/
public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data");
+ //这个接口定义了一系列静态的、最终的字符串常量,这些常量代表数据库表中的列名。
+ //
+ //里面定义的属性有:ID、父级ID、创建日期、修改日期、提醒日期、文件(标签)名(摘要?)、小部件ID、小部件类型、背景颜色ID、附件、文件中的标签数量、 文件(标签)类型、最后一个同步ID、本地修改标签、移动前的ID、谷歌任务ID、代码版本信息
public interface NoteColumns {
/**
@@ -179,30 +191,35 @@ public class Notes {
* Type: Text
*/
public static final String MIME_TYPE = "mime_type";
+ //MIME类型是一种标准,用于标识文档、文件或字节流的性质和格式。在数据库中,这个字段可以用来识别不同类型的数据,例如文本、图片、音频或视频等。
/**
* The reference id to note that this data belongs to
* Type: INTEGER (long)
*/
public static final String NOTE_ID = "note_id";
+ // 归属的Note的ID
/**
* Created data for note or folder
* Type: INTEGER (long)
*/
public static final String CREATED_DATE = "created_date";
+ //创建日期
/**
* Latest modified date
* Type: INTEGER (long)
*/
public static final String MODIFIED_DATE = "modified_date";
+ //最近修改日期
/**
* Data's content
* Type: TEXT
*/
public static final String CONTENT = "content";
+ //数据内容
/**
@@ -210,6 +227,10 @@ public class Notes {
* integer data type
* Type: INTEGER
*/
+
+ // 以下5个是通用数据列,它们的具体意义取决于MIME类型(由MIME_TYPE字段指定)。
+ // 不同的MIME类型可能需要存储不同类型的数据,这5个字段提供了灵活性,允许根据MIME类型来存储相应的数据。
+ // 读后面的代码感觉这部分是在表示内容的不同状态?
public static final String DATA1 = "data1";
/**
@@ -241,39 +262,43 @@ public class Notes {
public static final String DATA5 = "data5";
}
+ //以下是文本便签的定义
public static final class TextNote implements DataColumns {
/**
* Mode to indicate the text in check list mode or not
* Type: Integer 1:check list mode 0: normal mode
*/
+ //模式?这个被存在DATA1列中
public static final String MODE = DATA1;
-
+ //所处检查列表模式?
public static final int MODE_CHECK_LIST = 1;
-
+ // 定义了MIME类型,用于标识文本标签的目录
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note";
-
+ // 定义了MIME类型,用于标识文本标签的单个项
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note";
-
+ //文本标签内容提供者(Content Provider)的URI,用于访问文本标签数据
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note");
}
-
+ // 通话记录的定义
public static final class CallNote implements DataColumns {
/**
* Call date for this record
* Type: INTEGER (long)
*/
+ //一个字符串常量,表示通话记录的日期
public static final String CALL_DATE = DATA1;
/**
* Phone number for this record
* Type: TEXT
*/
+ //意味着在数据库表中,这个电话号码信息将被存储在DATA3列中
public static final String PHONE_NUMBER = DATA3;
-
+ // 同样定义了MIME类型,是用于标识通话记录的目录。
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note";
-
+ // 同样定义了MIME类型,是用于标识通话记录的单个项。
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note";
-
+ //定义了通话记录内容提供者的URI,用于访问通话记录数据。
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note");
}
}
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java b/src/Notesmaster/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java
index ffe5d57..30d9287 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java
@@ -28,194 +28,264 @@ import net.micode.notes.data.Notes.NoteColumns;
public class NotesDatabaseHelper extends SQLiteOpenHelper {
+ // 数据库帮助类,用于管理名为 note.db 的 SQLite 数据库。
+ // 它继承自 SQLiteOpenHelper 类,这是 Android提供的一个方便的工具类,用于管理数据库的创建和版本更新.
+ // 数据库的基本信息;数据库名称和版本信息(在创建实例对象时会用到)
private static final String DB_NAME = "note.db";
private static final int DB_VERSION = 4;
-
+ //内部接口:个人理解为两个表名,一个note,一个data
public interface TABLE {
public static final String NOTE = "note";
public static final String DATA = "data";
}
-
+ //一个标签,方便日志输出时识别出信息来自哪里
private static final String TAG = "NotesDatabaseHelper";
-
+ //静态所有变量,提供一个全局访问点来获取数据库辅助类的唯一实例,使得在应用的任何地方都可以方便地使用它
private static NotesDatabaseHelper mInstance;
-
+ /* 以下都是一些SQL语句,辅助我们来对数据库进行操作 */
+ //创建note表的语句,这里的NoteColumns就是我们刚刚在Notes中定义的一个接口,里面定义了一系列静态的数据库表中的列名
private static final String CREATE_NOTE_TABLE_SQL =
- "CREATE TABLE " + TABLE.NOTE + "(" +
- NoteColumns.ID + " INTEGER PRIMARY KEY," +
- NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.ALERTED_DATE + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.BG_COLOR_ID + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
- NoteColumns.HAS_ATTACHMENT + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
- NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," +
- NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," +
- NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," +
- NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" +
- ")";
-
+ "CREATE TABLE " + TABLE.NOTE + "(" +
+ NoteColumns.ID + " INTEGER PRIMARY KEY," +
+ NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.ALERTED_DATE + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.BG_COLOR_ID + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
+ NoteColumns.HAS_ATTACHMENT + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
+ NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," +
+ NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," +
+ NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," +
+ NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" +
+ ")";
+ //同上,创建data表的语句,这里的DataColumns就是我们刚刚在Notes中定义的一个接口,里面定义了一系列静态的数据库表中的列名
private static final String CREATE_DATA_TABLE_SQL =
- "CREATE TABLE " + TABLE.DATA + "(" +
- DataColumns.ID + " INTEGER PRIMARY KEY," +
- DataColumns.MIME_TYPE + " TEXT NOT NULL," +
- DataColumns.NOTE_ID + " INTEGER NOT NULL DEFAULT 0," +
- NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
- NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
- DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," +
- DataColumns.DATA1 + " INTEGER," +
- DataColumns.DATA2 + " INTEGER," +
- DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," +
- DataColumns.DATA4 + " TEXT NOT NULL DEFAULT ''," +
- DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" +
- ")";
+ "CREATE TABLE " + TABLE.DATA + "(" +
+ DataColumns.ID + " INTEGER PRIMARY KEY," +
+ DataColumns.MIME_TYPE + " TEXT NOT NULL," +
+ DataColumns.NOTE_ID + " INTEGER NOT NULL DEFAULT 0," +
+ NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
+ NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
+ DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," +
+ DataColumns.DATA1 + " INTEGER," +
+ DataColumns.DATA2 + " INTEGER," +
+ DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," +
+ DataColumns.DATA4 + " TEXT NOT NULL DEFAULT ''," +
+ DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" +
+ ")";
+ // 功能简介:
+ // 创建一个以note的ID为索引
+ // 解读:
+ // 用于在TABLE.DATA表上创建一个名为note_id_index的索引。
+ // 这个索引是基于DataColumns.NOTE_ID列的。IF NOT EXISTS确保了如果索引已经存在,那么就不会尝试重新创建它,避免了可能的错误。
+ // 索引通常用于提高查询性能,特别是在对某个字段进行频繁查询时。
private static final String CREATE_DATA_NOTE_ID_INDEX_SQL =
- "CREATE INDEX IF NOT EXISTS note_id_index ON " +
- TABLE.DATA + "(" + DataColumns.NOTE_ID + ");";
+ "CREATE INDEX IF NOT EXISTS note_id_index ON " +
+ TABLE.DATA + "(" + DataColumns.NOTE_ID + ");";
+
+ /* 以下是一些对便签增删改定义的触发器 */
+ /* 总结
+ * 这些触发器都是用来维护NOTE表和与之相关联的DATA表之间数据一致性的。
+ * 当在NOTE表中发生删除或更新操作时,这些触发器会自动执行相应的数据清理或更新操作,确保数据库中的数据保持正确和一致。
+ * 特别是在处理文件夹和回收站等逻辑时,这些触发器起到了非常重要的作用,可以自动管理数据的移动和删除。*/
/**
* Increase folder's note count when move note to the folder
*/
+ // 功能简介:
+ // 添加触发器:增加文件夹的便签个数记录(因为我们会移动便签进入文件夹,这时候文件夹的计数要进行更新)
+ // 解读:
+ // 定义了一个SQL触发器increase_folder_count_on_update。
+ // 触发器是一种特殊的存储过程,它会在指定表上的指定事件(如INSERT、UPDATE、DELETE)发生时自动执行。
+ // 这个触发器会在TABLE.NOTE表的NoteColumns.PARENT_ID字段更新后执行。
+ // 触发器的逻辑是:当某个笔记的PARENT_ID(即父文件夹ID)被更新时,它会找到对应的文件夹(通过新的PARENT_ID),并将该文件夹的NOTES_COUNT(即笔记数)增加1。
+
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER =
- "CREATE TRIGGER increase_folder_count_on_update "+
- " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
- " BEGIN " +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
- " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
- " END";
+ "CREATE TRIGGER increase_folder_count_on_update "+
+ " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
+ " BEGIN " +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
+ " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
+ " END";
/**
* Decrease folder's note count when move note from folder
*/
+ // 功能简介:(触发器和上面的 “增加文件夹的便签个数记录” 同理,就不细节解读了)
+ // 添加触发器:减少文件夹的便签个数记录(因为我们会移动便签移出文件夹,这时候文件夹的计数要进行更新)
+
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER =
- "CREATE TRIGGER decrease_folder_count_on_update " +
- " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
- " BEGIN " +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
- " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
- " AND " + NoteColumns.NOTES_COUNT + ">0" + ";" +
- " END";
+ "CREATE TRIGGER decrease_folder_count_on_update " +
+ " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
+ " BEGIN " +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
+ " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
+ " AND " + NoteColumns.NOTES_COUNT + ">0" + ";" +
+ " END";
/**
* Increase folder's note count when insert new note to the folder
*/
+ // 功能简介:(触发器原理和上面的 “增加文件夹的便签个数记录” 同理,就不细节解读了)
+ // 添加触发器:当我们在文件夹插入便签时,增加文件夹的便签个数记录
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER =
- "CREATE TRIGGER increase_folder_count_on_insert " +
- " AFTER INSERT ON " + TABLE.NOTE +
- " BEGIN " +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
- " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
- " END";
+ "CREATE TRIGGER increase_folder_count_on_insert " +
+ " AFTER INSERT ON " + TABLE.NOTE +
+ " BEGIN " +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
+ " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
+ " END";
/**
* Decrease folder's note count when delete note from the folder
*/
+ // 功能简介:(触发器原理和上面的 “增加文件夹的便签个数记录” 同理,就不细节解读了)
+ // 添加触发器:当我们在文件夹删除便签时,减少文件夹的便签个数记录
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER =
- "CREATE TRIGGER decrease_folder_count_on_delete " +
- " AFTER DELETE ON " + TABLE.NOTE +
- " BEGIN " +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
- " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
- " AND " + NoteColumns.NOTES_COUNT + ">0;" +
- " END";
+ "CREATE TRIGGER decrease_folder_count_on_delete " +
+ " AFTER DELETE ON " + TABLE.NOTE +
+ " BEGIN " +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
+ " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
+ " AND " + NoteColumns.NOTES_COUNT + ">0;" +
+ " END";
/**
* Update note's content when insert data with type {@link DataConstants#NOTE}
*/
+ // 功能简介:
+ // 添加触发器:当向DATA表中插入类型为NOTE(便签)的数据时,更新note表对应的笔记内容。
+ // 解读:
+ // 在DATA表上进行INSERT操作后,如果新插入的数据的MIME_TYPE为NOTE,则触发此操作。
+ // 它会更新NOTE表,将与新插入数据相关联的标签的SNIPPET(摘要)字段设置为新插入数据的CONTENT字段的值
+
private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER =
- "CREATE TRIGGER update_note_content_on_insert " +
- " AFTER INSERT ON " + TABLE.DATA +
- " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
- " BEGIN" +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
- " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
- " END";
+ "CREATE TRIGGER update_note_content_on_insert " +
+ " AFTER INSERT ON " + TABLE.DATA +
+ " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
+ " BEGIN" +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
+ " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
+ " END";
/**
* Update note's content when data with {@link DataConstants#NOTE} type has changed
*/
+ // 功能简介:
+ // 添加触发器:当DATA表中,类型为NOTE(便签)的数据更改时,更新note表对应的笔记内容。
+ // 解读:
+ // 在DATA表上进行UPDATE操作后,如果更新前的数据的MIME_TYPE为NOTE,则触发此操作。
+ // 它会更新NOTE表,将与更新后的数据相关联的笔记的SNIPPET字段设置为新数据的CONTENT字段的值
+
private static final String DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER =
- "CREATE TRIGGER update_note_content_on_update " +
- " AFTER UPDATE ON " + TABLE.DATA +
- " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
- " BEGIN" +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
- " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
- " END";
+ "CREATE TRIGGER update_note_content_on_update " +
+ " AFTER UPDATE ON " + TABLE.DATA +
+ " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
+ " BEGIN" +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
+ " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
+ " END";
/**
* Update note's content when data with {@link DataConstants#NOTE} type has deleted
*/
+ // 功能简介:
+ // 添加触发器:当DATA表中,类型为NOTE(便签)的数据删除时,更新note表对应的笔记内容(置空)。
+ // 解读:
+ // 在DATA表上进行DELETE操作后,如果删除的数据的MIME_TYPE为NOTE,则触发此操作。
+ // 它会更新NOTE表,将与删除的数据相关联的笔记的SNIPPET字段设置为空字符串。
+
private static final String DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER =
- "CREATE TRIGGER update_note_content_on_delete " +
- " AFTER delete ON " + TABLE.DATA +
- " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
- " BEGIN" +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.SNIPPET + "=''" +
- " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" +
- " END";
+ "CREATE TRIGGER update_note_content_on_delete " +
+ " AFTER delete ON " + TABLE.DATA +
+ " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
+ " BEGIN" +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.SNIPPET + "=''" +
+ " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" +
+ " END";
/**
* Delete datas belong to note which has been deleted
*/
+ // 功能简介:
+ // 添加触发器:当从NOTE表中删除笔记时,删除与该笔记相关联的数据(就是删除data表中为该note的数据)
+ // 解读:
+ // 在NOTE表上进行DELETE操作后,此触发器被激活。
+ // 它会从DATA表中删除所有与已删除的笔记(由old.ID表示)相关联的数据行(通过比较DATA表中的NOTE_ID字段与已删除笔记的ID来实现)
+
private static final String NOTE_DELETE_DATA_ON_DELETE_TRIGGER =
- "CREATE TRIGGER delete_data_on_delete " +
- " AFTER DELETE ON " + TABLE.NOTE +
- " BEGIN" +
- " DELETE FROM " + TABLE.DATA +
- " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" +
- " END";
+ "CREATE TRIGGER delete_data_on_delete " +
+ " AFTER DELETE ON " + TABLE.NOTE +
+ " BEGIN" +
+ " DELETE FROM " + TABLE.DATA +
+ " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" +
+ " END";
/**
* Delete notes belong to folder which has been deleted
*/
+ // 功能简介:
+ // 添加触发器:当从NOTE表中删除一个文件夹时,删除该文件夹下的所有笔记。
+ // 解读:
+ // 在NOTE表上进行DELETE操作后,如果删除的是一个文件夹(由old.ID表示)
+ // 触发器会删除所有以该文件夹为父级(PARENT_ID)的笔记(通过比较NOTE表中的PARENT_ID字段与已删除文件夹的ID来实现)
+
private static final String FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER =
- "CREATE TRIGGER folder_delete_notes_on_delete " +
- " AFTER DELETE ON " + TABLE.NOTE +
- " BEGIN" +
- " DELETE FROM " + TABLE.NOTE +
- " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
- " END";
+ "CREATE TRIGGER folder_delete_notes_on_delete " +
+ " AFTER DELETE ON " + TABLE.NOTE +
+ " BEGIN" +
+ " DELETE FROM " + TABLE.NOTE +
+ " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
+ " END";
/**
* Move notes belong to folder which has been moved to trash folder
*/
- private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER =
- "CREATE TRIGGER folder_move_notes_on_trash " +
- " AFTER UPDATE ON " + TABLE.NOTE +
- " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
- " BEGIN" +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
- " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
- " END";
+ // 功能简介:
+ // 添加触发器:当某个文件夹被移动到回收站时,移动该文件夹下的所有笔记到回收站
+ // 解读:
+ // 在NOTE表上进行UPDATE操作后,如果某个文件夹的新PARENT_ID字段值等于回收站的ID(Notes.ID_TRASH_FOLER)
+ // 触发器会更新所有以该文件夹为父级(PARENT_ID)的笔记,将它们也移动到回收站。
+ private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER =
+ "CREATE TRIGGER folder_move_notes_on_trash " +
+ " AFTER UPDATE ON " + TABLE.NOTE +
+ " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
+ " BEGIN" +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
+ " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
+ " END";
+ // 构造器
public NotesDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
-
+ // 创建note(标签)表
public void createNoteTable(SQLiteDatabase db) {
db.execSQL(CREATE_NOTE_TABLE_SQL);
reCreateNoteTableTriggers(db);
createSystemFolder(db);
Log.d(TAG, "note table has been created");
}
+ // 重新创建或更新与笔记表相关的触发器。
+ // 首先,使用DROP TRIGGER IF EXISTS语句删除已存在的触发器。确保在重新创建触发器之前,不存在同名的触发器。
+ // 然后,使用db.execSQL()方法执行预定义的SQL语句,这些语句用于创建新的触发器。
private void reCreateNoteTableTriggers(SQLiteDatabase db) {
db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_update");
@@ -234,6 +304,17 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER);
db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER);
}
+ /* 以下部分是操作SQLite数据库部分 */
+ // 功能简介:
+ // 创建通话记录文件夹、默认文件夹、临时文件夹和回收站,并插入相关数据
+ // 具体解读:
+ // ContentValues是一个用于存储键值对的类,常用于SQLite数据库的插入操作
+ // values.put方法可以向ContentValues对象中添加数据。
+ // NoteColumns.ID是存储文件夹ID的列名,Notes.ID_CALL_RECORD_FOLDER是通话记录文件夹的ID。
+ // NoteColumns.TYPE是存储文件夹类型的列名,Notes.TYPE_SYSTEM表示这是一个系统文件夹。
+ // 使用db.insert方法将values中的数据插入到TABLE.NOTE(即标签表)中。
+ // 每次插入新数据前,都使用values.clear()方法清除ContentValues对象中的旧数据,确保不会重复插入旧数据。
+ // 然后分别创建默认文件夹、临时文件夹和回收站,并以同样的方法插入数据。
private void createSystemFolder(SQLiteDatabase db) {
ContentValues values = new ContentValues();
@@ -248,6 +329,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
/**
* root folder which is default folder
*/
+ // 创建默认文件夹:重复上述步骤,但这次是为根文件夹插入数据。
values.clear();
values.put(NoteColumns.ID, Notes.ID_ROOT_FOLDER);
values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
@@ -256,6 +338,8 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
/**
* temporary folder which is used for moving note
*/
+ // 创建“临时”文件夹:同样地,为临时文件夹插入数据。
+
values.clear();
values.put(NoteColumns.ID, Notes.ID_TEMPARAY_FOLDER);
values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
@@ -264,11 +348,21 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
/**
* create trash folder
*/
+ // 创建“回收站”文件夹:最后,为回收站文件夹插入数据。
+
values.clear();
values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER);
values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
db.insert(TABLE.NOTE, null, values);
}
+ //功能简介:
+ //创建data(数据)表
+ //解读:
+ //这个方法用于创建数据表,以及与之相关的触发器。
+ //创建数据表:使用db.execSQL方法执行预定义的SQL语句CREATE_DATA_TABLE_SQL,用于创建数据表。
+ //重新创建数据表触发器:调用reCreateDataTableTriggers方法,用于删除并重新创建与数据表相关的触发器。
+ //创建索引:使用db.execSQL方法执行CREATE_DATA_NOTE_ID_INDEX_SQL语句,为数据表创建索引。
+ //记录日志:使用Log.d方法记录一条调试级别的日志,表示数据表已经创建。
public void createDataTable(SQLiteDatabase db) {
db.execSQL(CREATE_DATA_TABLE_SQL);
@@ -276,6 +370,11 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL);
Log.d(TAG, "data table has been created");
}
+ //和上面的note表的reCreate...同理
+ //重新创建或更新与笔记表相关的触发器。
+ //首先,使用DROP TRIGGER IF EXISTS语句删除已存在的触发器。确保在重新创建触发器之前,不存在同名的触发器。
+ //然后,使用db.execSQL()方法执行预定义的SQL语句,这些语句用于创建新的触发器。
+
private void reCreateDataTableTriggers(SQLiteDatabase db) {
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert");
@@ -286,6 +385,11 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER);
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER);
}
+ //解读:
+ //synchronized关键字确保在多线程环境下,只有一个线程能够进入这个方法,防止了同时创建多个实例的情况
+ //getInstance(Context context)方法使用了单例模式来确保整个应用程序中只有一个NotesDatabaseHelper实例。
+ //它首先检查mInstance(类的静态成员变量,没有在代码片段中显示)是否为null。
+ //如果是null,则创建一个新的NotesDatabaseHelper实例,并将其赋值给mInstance。最后返回mInstance。
static synchronized NotesDatabaseHelper getInstance(Context context) {
if (mInstance == null) {
@@ -293,13 +397,19 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
}
return mInstance;
}
-
+ //功能简介:
+ //当数据库首次创建时,onCreate方法会被调用。
+ //这里重写onCreate方法,它调用了上述createNoteTable(db)和createDataTable(db)两个方法
+ //这样首次创建数据库时就多出了两张表。
@Override
public void onCreate(SQLiteDatabase db) {
createNoteTable(db);
createDataTable(db);
}
+ //功能简介:
+ //当数据库需要升级时(即数据库的版本号改变),onUpgrade方法会被调用。
+ //该方法会根据当前的oldVersion和新的newVersion来执行相应的升级操作
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
boolean reCreateTriggers = false;
@@ -332,6 +442,11 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
+ "fails");
}
}
+ //功能简介:
+ // 将数据库从版本1升级到版本2。
+ //解读:
+ // 首先,它删除了已经存在的NOTE和DATA表(如果存在的话)。DROP TABLE IF EXISTS语句确保了即使这些表不存在,也不会抛出错误。
+ // 然后,它调用了createNoteTable(db)和createDataTable(db)方法来重新创建这两个表。这意味着在升级到版本2时,这两个表的内容会被完全清除,并重新创建新的空表。
private void upgradeToV2(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE);
@@ -339,6 +454,12 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
createNoteTable(db);
createDataTable(db);
}
+ //功能简介:
+ // 将数据库从版本2(或可能是跳过版本2的某个状态)升级到版本3。
+ //解读:
+ // 首先,删除了三个不再使用的触发器(如果存在的话)。触发器是数据库中的一种对象,可以在插入、更新或删除记录时自动执行某些操作。
+ // 然后,使用ALTER TABLE语句修改表结构,向NOTE表中添加了一个名为GTASK_ID的新列,并设置默认值为空字符串。
+ // 最后,向NOTE表中插入了一条新的系统文件夹记录,表示一个名为“trash folder”的系统文件夹。这可能是用于存储已删除笔记的回收站功能。
private void upgradeToV3(SQLiteDatabase db) {
// drop unused triggers
@@ -354,7 +475,10 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
db.insert(TABLE.NOTE, null, values);
}
-
+ //功能简介:
+ // 这个方法负责将数据库从版本3升级到版本4。
+ //解读:
+ // 它向NOTE表中添加了一个名为VERSION的新列,并设置了默认值为0。这个新列用于记录标签版本信息。
private void upgradeToV4(SQLiteDatabase db) {
db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION
+ " INTEGER NOT NULL DEFAULT 0");
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/data/NotesProvider.java b/src/Notesmaster/app/src/main/java/net/micode/notes/data/NotesProvider.java
index edb0a60..67a9b43 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/data/NotesProvider.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/data/NotesProvider.java
@@ -36,12 +36,20 @@ import net.micode.notes.data.NotesDatabaseHelper.TABLE;
public class NotesProvider extends ContentProvider {
+ // Android 应用程序中的一部分:内容提供者(ContentProvider)。
+ // 内容提供者是 Android 四大组件之一,它允许应用程序之间共享数据。
+ //
+ // 概述:
+ // NotesProvider的主要功能是作为一个内容提供者,为其他应用程序或组件提供对“Notes”数据的访问。
+ // 它允许其他应用程序查询、插入、更新或删除标签数据。
+ // 通过URI匹配,NotesProvider能够区分对哪种数据类型的请求,并执行相应的操作。
+ // 用于匹配不同URI的UriMatcher对象,通常用于解析传入的URI,并确定应该执行哪种操作。
private static final UriMatcher mMatcher;
-
+ //NotesDatabaseHelper实类,用来操作SQLite数据库,负责创建、更新和查询数据库。
private NotesDatabaseHelper mHelper;
-
+ //标签,输出日志时用来表示是该类发出的消息
private static final String TAG = "NotesProvider";
-
+ //6个URI的匹配码,用于区分不同的URI类型
private static final int URI_NOTE = 1;
private static final int URI_NOTE_ITEM = 2;
private static final int URI_DATA = 3;
@@ -49,14 +57,23 @@ public class NotesProvider extends ContentProvider {
private static final int URI_SEARCH = 5;
private static final int URI_SEARCH_SUGGEST = 6;
-
+ //进一步定义了URI匹配规则和搜索查询的投影
+ //功能概述:
+ //初始化了一个UriMatcher对象mMatcher,并添加了一系列的URI匹配规则。
+ //解读:
static {
+ //创建了一个UriMatcher实例,并设置默认匹配码为NO_MATCH,表示如果没有任何URI匹配,则返回这个码。
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ //添加规则,当URI的authority为Notes.AUTHORITY,路径为note时,返回匹配码URI_NOTE。
mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE);
+ //添加规则,当URI的authority为Notes.AUTHORITY,路径为note/后跟一个数字(#代表数字)时,返回匹配码URI_NOTE_ITEM。
mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM);
+ //和上面两句同理,但用于匹配数据相关的URI
mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA);
mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM);
+ //用于匹配搜索相关的URI
mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH);
+ //这两行用于匹配搜索建议相关的URI
mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST);
mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST);
}
@@ -65,33 +82,66 @@ public class NotesProvider extends ContentProvider {
* x'0A' represents the '\n' character in sqlite. For title and content in the search result,
* we will trim '\n' and white space in order to show more information.
*/
- private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + ","
+ //功能概述:
+ //一个 SQL 查询的投影部分,用于定义查询返回的结果集中应该包含哪些列。
+ //解读:(每行对应)
+ //返回笔记的 ID。
+ //笔记的 ID 也被重命名为 SUGGEST_COLUMN_INTENT_EXTRA_DATA,这通常用于 Android 的搜索建议中,作为传递给相关 Intent 的额外数据。
+ //对 SNIPPET 列的处理:首先使用 REPLACE 函数将 x'0A'(即换行符 \n)替换为空字符串,然后使用 TRIM 函数删除前后的空白字符,处理后的结果分别重命名为 SUGGEST_COLUMN_TEXT_1
+ //对 SNIPPET 列的处理:首先使用 REPLACE 函数将 x'0A'(即换行符 \n)替换为空字符串,然后使用 TRIM 函数删除前后的空白字符,处理后的结果分别重命名为 SUGGEST_COLUMN_TEXT_2
+ //返回一个用于搜索建议图标的资源 ID,并命名为 SUGGEST_COLUMN_ICON_1。
+ //返回一个固定的 Intent 动作 ACTION_VIEW,并命名为 SUGGEST_COLUMN_INTENT_ACTION。
+ //返回一个内容类型,并命名为 SUGGEST_COLUMN_INTENT_DATA。
+
+ private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + ","//返回笔记的 ID
+ NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + ","
+ "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + ","
+ "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + ","
+ R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + ","
+ "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + ","
+ "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA;
+//功能概述:
+ //完整的 SQL 查询语句,用于从 TABLE.NOTE 表中检索信息
+ //解读:
+ // 使用上面定义的投影来选择数据。
+ // 并指定从哪个表中选择数据。
+ //WHERE子句包含三个条件:
+ // ①搜索 SNIPPET 列中包含特定模式的行(? 是一个占位符,实际查询时会用具体的值替换)。
+ // ②父ID不为回收站的ID:排除那些父 ID 为回收站的行。
+ // ③只选择类型为note(标签)的行。
private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION
+ " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.SNIPPET + " LIKE ?"
+ " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER
+ " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE;
+//重写onCreate方法:
+ //getContext() 方法被调用以获取当前组件的上下文(Context),以便 NotesDatabaseHelper 能够访问应用程序的资源和其他功能
+ //mHelper用于存储从 NotesDatabaseHelper.getInstance 方法返回的实例。这样,该实例就可以在整个组件的其他方法中被访问和使用。
@Override
public boolean onCreate() {
mHelper = NotesDatabaseHelper.getInstance(getContext());
return true;
}
-
+ //功能:查询数据
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
+ //初始化变量:
+ //Cursor对象 c,用来存储查询结果
+ //使用 NotesDatabaseHelper 的实例 mHelper来获取一个可读的数据库实例
+ //定义一个字符串id,用来存储从URI中解析出的ID
Cursor c = null;
+ //根据匹配不同的URI来进行不同的查询
SQLiteDatabase db = mHelper.getReadableDatabase();
String id = null;
switch (mMatcher.match(uri)) {
+ // URI_NOTE:查询整个 NOTE 表。
+ // URI_NOTE_ITEM:查询 NOTE 表中的特定项。ID 从 URI 的路径段中获取,并添加到查询条件中。
+ // URI_DATA:查询整个 DATA 表。
+ // URI_DATA_ITEM:查询 DATA 表中的特定项。ID 的获取和处理方式与 URI_NOTE_ITEM 相同。
+
case URI_NOTE:
c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
sortOrder);
@@ -101,6 +151,12 @@ public class NotesProvider extends ContentProvider {
c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id
+ parseSelection(selection), selectionArgs, null, null, sortOrder);
break;
+ //URI_SEARCH 和 URI_SEARCH_SUGGEST:处理搜索查询。
+ // 代码首先检查是否提供了不应与搜索查询一起使用的参数(如 sortOrder, selection, selectionArgs, 或 projection)。
+ // 如果提供了这些参数,则抛出一个 IllegalArgumentException。
+ // 根据 URI 类型,从 URI 的路径段或查询参数中获取搜索字符串 searchString。
+ // 如果 searchString 为空或无效,则返回 null,表示没有搜索结果
+
case URI_DATA:
c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null,
sortOrder);
@@ -129,7 +185,8 @@ public class NotesProvider extends ContentProvider {
if (TextUtils.isEmpty(searchString)) {
return null;
}
-
+//字符串格式化:格式化后的字符串就会是 "%s%",即包含s是任何文本
+ //然后执行原始SQL查询
try {
searchString = String.format("%%%s%%", searchString);
c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY,
@@ -138,19 +195,29 @@ public class NotesProvider extends ContentProvider {
Log.e(TAG, "got exception: " + ex.toString());
}
break;
+ //未知URI处理:
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
+ //如果查询结果不为空(即 Cursor 对象 c 不是 null),则为其设置一个通知 URI。
+ //这意味着当与这个 URI 关联的数据发生变化时,任何注册了监听这个 URI 的 ContentObserver 都会被通知。
if (c != null) {
c.setNotificationUri(getContext().getContentResolver(), uri);
}
return c;
}
-
+ //功能:插入数据
+ //参数:Uri 用来标识要插入数据的表,ContentValues对象包含要插入的键值对
@Override
public Uri insert(Uri uri, ContentValues values) {
+ //获取数据库
+ //三个长整型变量,分别用来存储数据项ID、便签ID 和插入行的ID
SQLiteDatabase db = mHelper.getWritableDatabase();
long dataId = 0, noteId = 0, insertedId = 0;
+ //对于 URI_NOTE,将values插入到 TABLE.NOTE 表中,并返回插入行的 ID。
+ //对于 URI_DATA,首先检查values是否包含 DataColumns.NOTE_ID,如果包含,则获取其值。如果不包含,记录一条日志信息。然后,将 values 插入到 TABLE.DATA 表中,并返回插入行的 ID。
+ //如果 uri 不是已知的 URI 类型,则抛出一个 IllegalArgumentException。
+
switch (mMatcher.match(uri)) {
case URI_NOTE:
insertedId = noteId = db.insert(TABLE.NOTE, null, values);
@@ -166,6 +233,11 @@ public class NotesProvider extends ContentProvider {
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
+ //功能:通知变化
+ //如果noteId 或 dataId 大于 0(即成功插入了数据),则使用 ContentResolver 的 notifyChange 方法通知监听这些 URI 的观察者,告知数据已经改变。
+ //ContentUris.withAppendedId 方法用于在基本 URI 后面追加一个 ID,形成完整的 URI。
+ // Notify the note uri
+
// Notify the note uri
if (noteId > 0) {
getContext().getContentResolver().notifyChange(
@@ -177,17 +249,28 @@ public class NotesProvider extends ContentProvider {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null);
}
-
+//返回包含新插入数据项ID 的 Uri。允许调用者知道新插入的数据项的位置
return ContentUris.withAppendedId(uri, insertedId);
}
+//功能:删除数据项
+ //参数:uri:标识要删除数据的表或数据项。 selection:一个可选的 WHERE 子句,用于指定删除条件。 selectionArgs:一个可选的字符串数组,用于替换 selection 中的占位符
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
+ //count:记录被删除的行数。
+ //id:用于存储从 URI 中解析出的数据项 ID。
+ //db:可写的数据库对象,用于执行删除操作。
+ //deleteData:一个布尔值,用于标记是否删除了 DATA 表中的数据。
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase();
boolean deleteData = false;
switch (mMatcher.match(uri)) {
+ //URI_NOTE: 修改 selection 语句:确保只删除 ID 大于 0 的笔记。然后执行删除操作并返回被删除的行数。
+ //URI_NOTE_ITEM: 从 URI 中解析出 ID。检查 ID 是否小于等于 0,如果是,则不执行删除操作;否则执行删除操作并返回被删除的行数
+ //URI_DATA: 执行删除操作并返回被删除的行数。设置 deleteData 为 true,表示删除了 DATA 表中的数据。
+ //URI_DATA_ITEM: 先从 URI 中解析出 ID,然后执行删除操作并返回被删除的行数,并设置 deleteData 为 true,表示删除了 DATA 表中的数据。
+
case URI_NOTE:
selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 ";
count = db.delete(TABLE.NOTE, selection, selectionArgs);
@@ -218,6 +301,9 @@ public class NotesProvider extends ContentProvider {
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
+ //如果 count 大于 0,说明有数据被删除。
+ //如果 deleteData 为 true,则通知监听 Notes.CONTENT_NOTE_URI 的观察者,数据已改变。
+ //通知监听传入 uri 的观察者数据已改变。
if (count > 0) {
if (deleteData) {
getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null);
@@ -226,14 +312,26 @@ public class NotesProvider extends ContentProvider {
}
return count;
}
+//功能:更新数据库的数据
+ //参数:uri:标识要更新数据的表或数据项。 values:一个包含新值的键值对集合。
+ // selection:一个可选的 WHERE 子句,用于指定更新条件。 selectionArgs:一个可选的字符串数组,用于替换 selection 中的占位符。
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ //count:记录被更新的行数。
+ //id:用于存储从 URI 中解析出的数据项 ID。
+ //db:可写的 SQLite 数据库对象,用于执行更新操作。
+ //updateData:用于标记是否更新了 data 表中的数据。
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase();
boolean updateData = false;
switch (mMatcher.match(uri)) {
+ //URI_NOTE:调用 increaseNoteVersion 方法(用于增加便签版本),然后在note表执行更新操作并返回被更新的行数。
+ //URI_NOTE_ITEM:从 URI 中解析出 ID,并调用 increaseNoteVersion 方法,传入解析出的 ID,最后在note表执行更新操作并返回被更新的行数。
+ //URI_DATA:在data表执行更新操作并返回被更新的行数。设置 updateData 为 true,表示更新了 DATA 表中的数据。
+ //URI_DATA_ITEM:从 URI 中解析出 ID。执行更新操作并返回被更新的行数。置 updateData 为 true,表示更新了 DATA 表中的数据。
+
case URI_NOTE:
increaseNoteVersion(-1, selection, selectionArgs);
count = db.update(TABLE.NOTE, values, selection, selectionArgs);
@@ -257,7 +355,9 @@ public class NotesProvider extends ContentProvider {
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
-
+//如果 count 大于 0,说明有数据被更新。
+ //如果 updateData 为 true,则通知监听 Notes.CONTENT_NOTE_URI 的观察者数据已改变。
+ //通知监听传入 uri 的观察者数据已改变。
if (count > 0) {
if (updateData) {
getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null);
@@ -266,11 +366,11 @@ public class NotesProvider extends ContentProvider {
}
return count;
}
-
+ //解析传入的条件语句:一个 SQL WHERE 子句的一部分
private String parseSelection(String selection) {
return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : "");
}
-
+ //更新note表的version列,将其值增加 1。
private void increaseNoteVersion(long id, String selection, String[] selectionArgs) {
StringBuilder sql = new StringBuilder(120);
sql.append("UPDATE ");
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/MetaData.java b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/MetaData.java
index 3a2050b..a64148c 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/MetaData.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/MetaData.java
@@ -26,11 +26,14 @@ import org.json.JSONObject;
public class MetaData extends Task {
+ //功能描述:得到类的简写名称存入字符串TAG中
private final static String TAG = MetaData.class.getSimpleName();
private String mRelatedGid = null;
-
+//功能描述:设置数据,即生成元数据库
+//实现过程:调用JSONObject库函数put (),Task类中的setNotes ()和setName ()函数
public void setMeta(String gid, JSONObject metaInfo) {
+ //对函数块进行注释
try {
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
} catch (JSONException e) {
@@ -43,12 +46,12 @@ public class MetaData extends Task {
public String getRelatedGid() {
return mRelatedGid;
}
+ // 功能描述:判断当前数据是否为空,若为空则返回真即值得保存
@Override
public boolean isWorthSaving() {
return getNotes() != null;
- }
-
+ }//功能描述:使用远程json数据对象设置元数据内容 实现过程:调用父类Task中的setContentByRemoteJSON ()函数
@Override
public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js);
@@ -62,21 +65,22 @@ public class MetaData extends Task {
}
}
}
-
+ //功能描述:使用本地json数据对象设置元数据内容,一般不会用到,若用到,则抛出异常 Made By CuiCan
@Override
public void setContentByLocalJSON(JSONObject js) {
// this function should not be called
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
}
-
+//功能描述:从元数据内容中获取本地json对象,一般不会用到,若用到,则抛出异常 Made By CuiCan
@Override
public JSONObject getLocalJSONFromContent() {
throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called");
}
+ //传递非法参数异常 Made By Cui Can/ 功能描述:获取同步动作状态,一般不会用到,若用到,则抛出异常 Made By CuiCan
@Override
public int getSyncAction(Cursor c) {
throw new IllegalAccessError("MetaData:getSyncAction should not be called");
- }
-}
+
+//传递非法参数异常 Made By Cui Can
\ No newline at end of file
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/Node.java b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/Node.java
index 63950e0..599f013 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/Node.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/Node.java
@@ -20,32 +20,32 @@ import android.database.Cursor;
import org.json.JSONObject;
-public abstract class Node {
- public static final int SYNC_ACTION_NONE = 0;
+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_REMOTE = 1;// 需要在远程云端增加内容
- public static final int SYNC_ACTION_ADD_LOCAL = 2;
+ 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_REMOTE = 3;// 需要在远程云端删除内容
- public static final int SYNC_ACTION_DEL_LOCAL = 4;
+ 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_REMOTE = 5;// 需要将本地内容更新到远程云端
- public static final int SYNC_ACTION_UPDATE_LOCAL = 6;
+ public static final int SYNC_ACTION_UPDATE_LOCAL = 6;// 需要将远程云端内容更新到本地
- public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
+ public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;// 同步出现冲突
- public static final int SYNC_ACTION_ERROR = 8;
+ public static final int SYNC_ACTION_ERROR = 8;// 同步出现错误
private String mGid;
private String mName;
- private long mLastModified;
+ private long mLastModified;//记录最后一次修改时间
- private boolean mDeleted;
+ private boolean mDeleted;//表征是否被删除
public Node() {
mGid = null;
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlData.java b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlData.java
index d3ec3be..1f7dc00 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlData.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlData.java
@@ -36,15 +36,23 @@ import org.json.JSONObject;
public class SqlData {
+ /*
+ * 功能描述:得到类的简写名称存入字符串TAG中
+ * 实现过程:调用getSimpleName ()函数
+ * Made By CuiCan
+ */
private static final String TAG = SqlData.class.getSimpleName();
private static final int INVALID_ID = -99999;
+ //来自Notes类中定义的DataColumn中的一些常量
+
+ // 集合了interface DataColumns中所有SF常量
public static final String[] PROJECTION_DATA = new String[] {
DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
DataColumns.DATA3
};
-
+ //以下五个变量作为sql表中5列的编号
public static final int DATA_ID_COLUMN = 0;
public static final int DATA_MIME_TYPE_COLUMN = 1;
@@ -56,6 +64,7 @@ public class SqlData {
public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
private ContentResolver mContentResolver;
+ //判断是否直接用Content生成,是为true,否则为false
private boolean mIsCreate;
@@ -70,6 +79,13 @@ public class SqlData {
private String mDataContentData3;
private ContentValues mDiffDataValues;
+ /*
+ * 功能描述:构造函数,用于初始化数据
+ * 参数注解:mContentResolver用于获取ContentProvider提供的数据
+ * 参数注解: mIsCreate表征当前数据是用哪种方式创建(两种构造函数的参数不同)
+ * 参数注解:
+ * Made By CuiCan
+ */
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
@@ -81,6 +97,13 @@ public class SqlData {
mDataContentData3 = "";
mDiffDataValues = new ContentValues();
}
+ /*
+ * 功能描述:构造函数,初始化数据
+ * 参数注解:mContentResolver用于获取ContentProvider提供的数据
+ * 参数注解: mIsCreate表征当前数据是用哪种方式创建(两种构造函数的参数不同)
+ * 参数注解:
+ * Made By CuiCan
+ */
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
@@ -88,7 +111,11 @@ public class SqlData {
loadFromCursor(c);
mDiffDataValues = new ContentValues();
}
-
+ /*
+ * 功能描述:从光标处加载数据
+ * 从当前的光标处将五列的数据加载到该类的对象
+ * Made By CuiCan
+ */
private void loadFromCursor(Cursor c) {
mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
@@ -96,8 +123,13 @@ public class SqlData {
mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN);
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
-
+ /*
+ * 功能描述:设置用于共享的数据,并提供异常抛出与处理机制
+ * 参数注解:
+ * Made By CuiCan
+ */
public void setContent(JSONObject js) throws JSONException {
+ //如果传入的JSONObject对象中有DataColumns.ID这一项,则设置,否则设为INVALID_ID
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) {
mDiffDataValues.put(DataColumns.ID, dataId);
@@ -129,12 +161,17 @@ public class SqlData {
}
mDataContentData3 = dataContentData3;
}
-
+ /*
+ * 功能描述:获取共享的数据内容,并提供异常抛出与处理机制
+ * 参数注解:
+ * Made By CuiCan
+ */
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
+ //创建JSONObject对象。并将相关数据放入其中,并返回。
JSONObject js = new JSONObject();
js.put(DataColumns.ID, mDataId);
js.put(DataColumns.MIME_TYPE, mDataMimeType);
@@ -143,7 +180,11 @@ public class SqlData {
js.put(DataColumns.DATA3, mDataContentData3);
return js;
}
-
+ /*
+ * 功能描述:commit函数用于把当前造作所做的修改保存到数据库
+ * 参数注解:
+ * Made By CuiCan
+ */
public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) {
@@ -182,7 +223,12 @@ public class SqlData {
mDiffDataValues.clear();
mIsCreate = false;
}
-
+ /*
+ * 功能描述:获取当前id
+ * 实现过程:
+ * 参数注解:
+ * Made By CuiCan
+ */
public long getId() {
return mDataId;
}
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java
index 79a4095..336cb64 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java
@@ -14,8 +14,17 @@
* limitations under the License.
*/
+/*
+ * Description:用于支持小米便签最底层的数据库相关操作,和sqlnote的关系上是子集关系,即data是note的子集(节点)。
+ * SqlData其实就是也就是所谓数据中的数据
+ */
package net.micode.notes.gtask.data;
-
+/*
+ * 功能描述:
+ * 实现过程:
+ * 参数注解:
+ * Made By CuiCan
+ */
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -38,10 +47,17 @@ import org.json.JSONObject;
import java.util.ArrayList;
-public class SqlNote {
+public class SqlNote {/*
+ * 功能描述:得到类的简写名称存入字符串TAG中
+ * 实现过程:调用getSimpleName ()函数
+ * Made By CuiCan
+ */
private static final String TAG = SqlNote.class.getSimpleName();
- private static final int INVALID_ID = -99999;
+ private static final int INVALID_ID = -99999;//为mDataId置初始值-99999
+ //来自Notes类中定义的DataColumn中的一些常量
+
+ // 集合了interface DataColumns中所有SF常量
public static final String[] PROJECTION_NOTE = new String[] {
NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID,
@@ -51,7 +67,7 @@ public class SqlNote {
NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID,
NoteColumns.VERSION
};
-
+ //以下五个变量作为sql表中5列的编号
public static final int ID_COLUMN = 0;
public static final int ALERTED_DATE_COLUMN = 1;
@@ -89,7 +105,7 @@ public class SqlNote {
private Context mContext;
private ContentResolver mContentResolver;
-
+ //判断是否直接用Content生成,是为true,否则为false
private boolean mIsCreate;
private long mId;
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java
index a1deb99..f6fe68e 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java
@@ -82,7 +82,10 @@ public class GTaskASyncTask extends AsyncTask {
Notification notification=builder.getNotification();
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
}
+<<<<<<< Updated upstream
+=======
+>>>>>>> Stashed changes
@Override
protected Integer doInBackground(Void... unused) {
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java
index c67dfdf..c1fc748 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java
@@ -120,7 +120,7 @@ public class GTaskClient {
// need to re-login after account switch
if (mLoggedin
&& !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity
- .getSyncAccountName(activity))) {
+ .getSyncAccountName(activity))) {
mLoggedin = false;
}
@@ -582,4 +582,4 @@ public class GTaskClient {
public void resetUpdateArray() {
mUpdateArray = null;
}
-}
+}
\ No newline at end of file
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/tool/GTaskStringUtils.java b/src/Notesmaster/app/src/main/java/net/micode/notes/tool/GTaskStringUtils.java
index 666b729..6f76a71 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/tool/GTaskStringUtils.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/tool/GTaskStringUtils.java
@@ -19,95 +19,96 @@ package net.micode.notes.tool;
public class GTaskStringUtils {
public final static String GTASK_JSON_ACTION_ID = "action_id";
-
+//表示在任务相关的 JSON 数据中,用于标识动作的 ID 的字符串常量
public final static String GTASK_JSON_ACTION_LIST = "action_list";
-
+//可能用于在 JSON 中表示动作列表相关的键。
public final static String GTASK_JSON_ACTION_TYPE = "action_type";
-
+//用于在 JSON 中表示动作类型的键,并且定义了几种具体的动作类型常量
public final static String GTASK_JSON_ACTION_TYPE_CREATE = "create";
-
+//创建动作类型
public final static String GTASK_JSON_ACTION_TYPE_GETALL = "get_all";
-
+//获取所有的动作类型
public final static String GTASK_JSON_ACTION_TYPE_MOVE = "move";
-
+//移动动作类型
public final static String GTASK_JSON_ACTION_TYPE_UPDATE = "update";
-
+//更新动作类型
public final static String GTASK_JSON_CREATOR_ID = "creator_id";
-
+//在 JSON 数据中用于标识任务创建者 ID 的键。
public final static String GTASK_JSON_CHILD_ENTITY = "child_entity";
-
+//可能与任务的子实体相关的 JSON 键。。
public final static String GTASK_JSON_CLIENT_VERSION = "client_version";
-
+//用于在 JSON 中表示客户端版本的键。
public final static String GTASK_JSON_COMPLETED = "completed";
-
+//可能用于表示任务是否完成的 JSON 键。
public final static String GTASK_JSON_CURRENT_LIST_ID = "current_list_id";
-
+//与当前列表 ID 相关的 JSON 键。
public final static String GTASK_JSON_DEFAULT_LIST_ID = "default_list_id";
-
+//表示默认列表 ID 的 JSON 键。
public final static String GTASK_JSON_DELETED = "deleted";
-
+//可能用于表示任务是否已删除的 JSON 键。
public final static String GTASK_JSON_DEST_LIST = "dest_list";
-
+//与目标列表相关的 JSON 键,可能用于移动等操作中表示目标列表。
public final static String GTASK_JSON_DEST_PARENT = "dest_parent";
-
+//用于表示目标父级相关的 JSON 键。
public final static String GTASK_JSON_DEST_PARENT_TYPE = "dest_parent_type";
-
+//用于表示目标父级类型的 JSON 键。
public final static String GTASK_JSON_ENTITY_DELTA = "entity_delta";
-
+//可能与实体变化量相关的 JSON 键。
public final static String GTASK_JSON_ENTITY_TYPE = "entity_type";
-
+//用于在 JSON 中表示实体类型的键。
public final static String GTASK_JSON_GET_DELETED = "get_deleted";
-
+//可能与获取已删除任务相关的 JSON 操作的键。
public final static String GTASK_JSON_ID = "id";
-
+//用于在 JSON 中标识任务等实体的 ID 的通用键。
public final static String GTASK_JSON_INDEX = "index";
-
+//可能用于表示索引的 JSON 键,比如任务在列表中的索引。
public final static String GTASK_JSON_LAST_MODIFIED = "last_modified";
-
+//用于在 JSON 中表示最后修改时间的键。
public final static String GTASK_JSON_LATEST_SYNC_POINT = "latest_sync_point";
-
+//可能与最新同步点相关的 JSON 键。
public final static String GTASK_JSON_LIST_ID = "list_id";
-
+//用于在 JSON 中表示列表 ID 的键。
public final static String GTASK_JSON_LISTS = "lists";
-
+//用于在 JSON 中表示列表的键,可能是多个列表的集合相关。
public final static String GTASK_JSON_NAME = "name";
-
+//用于在 JSON 中表示任务或实体名称的键。
public final static String GTASK_JSON_NEW_ID = "new_id";
-
+//可能用于在某些操作后表示新的 ID 的 JSON 键。
public final static String GTASK_JSON_NOTES = "notes";
-
+//用于在 JSON 中表示备注信息的键。
public final static String GTASK_JSON_PARENT_ID = "parent_id";
-
+//用于在 JSON 中表示父级 ID 的键。
public final static String GTASK_JSON_PRIOR_SIBLING_ID = "prior_sibling_id";
-
+//可能用于表示前一个同级 ID 的 JSON 键。
public final static String GTASK_JSON_RESULTS = "results";
-
+//用于在 JSON 中表示操作结果的键。
public final static String GTASK_JSON_SOURCE_LIST = "source_list";
-
+//与源列表相关的 JSON 键,与GTASK_JSON_DEST_LIST相对应,用于移动等操作中表示原始列表。
public final static String GTASK_JSON_TASKS = "tasks";
-
+//用于在 JSON 中表示任务集合的键。
public final static String GTASK_JSON_TYPE = "type";
-
+//用于在 JSON 中表示类型的键,并定义了具体类型常量
public final static String GTASK_JSON_TYPE_GROUP = "GROUP";
-
+//组类型
public final static String GTASK_JSON_TYPE_TASK = "TASK";
-
+//任务类型
public final static String GTASK_JSON_USER = "user";
-
+//用于在 JSON 中表示用户相关的键
public final static String MIUI_FOLDER_PREFFIX = "[MIUI_Notes]";
-
+//定义了一个与 MIUI 文件夹相关的前缀字符串[MIUI_Notes],可能用于标识特定的 MIUI 笔记相关的文件夹。
public final static String FOLDER_DEFAULT = "Default";
-
+//表示默认文件夹的字符串常量
public final static String FOLDER_CALL_NOTE = "Call_Note";
-
+//表示通话笔记文件夹的字符串常量。
public final static String FOLDER_META = "METADATA";
-
+//表示元数据文件夹的字符串常量。
public final static String META_HEAD_GTASK_ID = "meta_gid";
-
+//用于在元数据中表示任务 ID 的头部相关的字符串常量。
public final static String META_HEAD_NOTE = "meta_note";
-
+//用于在元数据中表示笔记相关的头部字符串常量。
public final static String META_HEAD_DATA = "meta_data";
-
+//用于在元数据中表示数据相关的头部字符串常量。
public final static String META_NOTE_NAME = "[META INFO] DON'T UPDATE AND DELETE";
-
+//定义了一个元数据笔记名称的常量[META INFO] DON'T UPDATE AND DELETE,可能用于提醒不要对特定元数据笔记进行更新和删除操作。
}
+//这个类主要是通过定义一系列的字符串常量来规范在处理与任务相关的 JSON 数据以及可能涉及到的文件夹和元数据相关操作时所使用的键名和标识字符串等,以便在整个项目中保持一致性和可维护性。
\ No newline at end of file
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/tool/ResourceParser.java b/src/Notesmaster/app/src/main/java/net/micode/notes/tool/ResourceParser.java
index 1ad3ad6..ee450fe 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/tool/ResourceParser.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/tool/ResourceParser.java
@@ -38,7 +38,8 @@ public class ResourceParser {
public static final int TEXT_SUPER = 3;
public static final int BG_DEFAULT_FONT_SIZE = TEXT_MEDIUM;
-
+//定义了一系列表示颜色和字体大小的常量。颜色方面,用整数常量YELLOW、BLUE等分别代表不同颜色,并且指定了默认背景颜色BG_DEFAULT_COLOR为YELLOW。
+//在字体大小方面,定义了TEXT_SMALL等常量,并设定了默认字体大小BG_DEFAULT_FONT_SIZE为TEXT_MEDIUM。
public static class NoteBgResources {
private final static int [] BG_EDIT_RESOURCES = new int [] {
R.drawable.edit_yellow,
@@ -64,7 +65,9 @@ public class ResourceParser {
return BG_EDIT_TITLE_RESOURCES[id];
}
}
-
+//这个内部类用于管理笔记编辑相关的背景资源。
+//定义了两个数组BG_EDIT_RESOURCES和BG_EDIT_TITLE_RESOURCES,分别存储不同颜色的笔记编辑背景图片资源和笔记编辑标题背景图片资源的引用(通过R.drawable)。
+//提供了getNoteBgResource和getNoteTitleBgResource方法,根据传入的id参数返回对应的背景图片资源引用。
public static int getDefaultBgId(Context context) {
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) {
@@ -73,7 +76,8 @@ public class ResourceParser {
return BG_DEFAULT_COLOR;
}
}
-
+//该方法用于获取默认的背景颜色id。
+//虽然看起来PreferenceManager.getDefaultSharedPreferences(context).getBoolean(NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)中的getBoolean在PREFERENCE_SET_BG_COLOR_KEY是final string的情况下似乎总是执行else分支,但这里可能存在其他逻辑使得这个偏好设置的值在某些情况下会被改变。比如可能在应用的其他地方有代码会根据用户的某些操作(如在设置界面手动切换了某个与背景颜色设置相关的开关)来更新这个偏好设置的值,所以不能简单地认为它总是返回false,因此这样的写法是为了根据实际的偏好设置值来决定是返回随机的背景颜色id还是默认的背景颜色id(BG_DEFAULT_COLOR)。
public static class NoteItemBgResources {
private final static int [] BG_FIRST_RESOURCES = new int [] {
R.drawable.list_yellow_up,
@@ -127,7 +131,9 @@ public class ResourceParser {
return R.drawable.list_folder;
}
}
-
+//这个内部类用于管理笔记项相关的背景资源。
+//定义了多个数组,如BG_FIRST_RESOURCES、BG_NORMAL_RESOURCES等,分别存储不同状态(如列表中的第一项、中间项、最后一项、单独一项)下的笔记项背景图片资源引用。
+//提供了相应的get方法,根据传入的id参数返回对应的背景图片资源引用,以及一个getFolderBgRes方法用于获取文件夹背景图片资源引用。
public static class WidgetBgResources {
private final static int [] BG_2X_RESOURCES = new int [] {
R.drawable.widget_2x_yellow,
@@ -153,7 +159,9 @@ public class ResourceParser {
return BG_4X_RESOURCES[id];
}
}
-
+//该内部类用于管理小部件相关的背景资源。
+//定义了两个数组BG_2X_RESOURCES和BG_4X_RESOURCES,分别存储不同倍数(2x和4x)下的小部件背景图片资源引用。
+//提供了getWidget2xBgResource和getWidget4xBgResource方法,根据传入的id参数返回对应的小部件背景图片资源引用。
public static class TextAppearanceResources {
private final static int [] TEXTAPPEARANCE_RESOURCES = new int [] {
R.style.TextAppearanceNormal,
@@ -179,3 +187,6 @@ public class ResourceParser {
}
}
}
+//这个内部类用于管理文本外观相关的资源。
+//定义了一个数组TEXTAPPEARANCE_RESOURCES,存储不同文本外观样式的资源引用(通过R.style)。
+//提供了getTexAppearanceResource方法,用于根据传入的id参数返回对应的文本外观资源引用,并且做了容错处理,如果传入的id大于资源数组的长度,就返回默认的字体大小资源引用(BG_DEFAULT_FONT_SIZE)。还提供了getResourcesSize方法用于获取资源数组的长度。
\ No newline at end of file
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DeviceList.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DeviceList.java
new file mode 100644
index 0000000..72c2ea5
--- /dev/null
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DeviceList.java
@@ -0,0 +1,4 @@
+package net.micode.notes.ui;
+
+public class DeviceList {
+}
diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
index 96a9ff8..e8023ba 100644
--- a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
+++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
@@ -358,8 +358,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|| ev.getX() > (x + view.getWidth())
|| ev.getY() < y
|| ev.getY() > (y + view.getHeight())) {
- return false;
- }
+ return false;
+ }
return true;
}
@@ -418,7 +418,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
- mWorkingNote.getWidgetId()
+ mWorkingNote.getWidgetId()
});
sendBroadcast(intent);
@@ -430,7 +430,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
- - View.VISIBLE);
+ View.VISIBLE);
} else if (sBgSelectorBtnsMap.containsKey(id)) {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
@@ -504,7 +504,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
return true;
}
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -623,7 +622,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (mWorkingNote.getNoteId() > 0) {
Intent intent = new Intent(this, AlarmReceiver.class);
intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId()));
- PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
showAlertHeader();
if(!set) {
@@ -870,4 +869,4 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
-}
+}
\ No newline at end of file
diff --git a/src/Notesmaster/app/src/main/res/values/styles.xml b/src/Notesmaster/app/src/main/res/values/styles.xml
index d750e65..c1eddb2 100644
--- a/src/Notesmaster/app/src/main/res/values/styles.xml
+++ b/src/Notesmaster/app/src/main/res/values/styles.xml
@@ -63,7 +63,6 @@
\ No newline at end of file
diff --git a/src/Notesmaster/build.gradle.kts b/src/Notesmaster/build.gradle.kts
index 3756278..327342f 100644
--- a/src/Notesmaster/build.gradle.kts
+++ b/src/Notesmaster/build.gradle.kts
@@ -1,4 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
-}
\ No newline at end of file
+}
diff --git a/src/Notesmaster/gradle/libs.versions.toml b/src/Notesmaster/gradle/libs.versions.toml
index 08c8f02..0bc05fc 100644
--- a/src/Notesmaster/gradle/libs.versions.toml
+++ b/src/Notesmaster/gradle/libs.versions.toml
@@ -1,5 +1,5 @@
[versions]
-agp = "8.7.2"
+agp = "8.6.0"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
@@ -7,6 +7,7 @@ appcompat = "1.6.1"
material = "1.10.0"
activity = "1.8.0"
constraintlayout = "2.1.4"
+firebaseCrashlyticsBuildtools = "3.0.2"
[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
@@ -16,6 +17,7 @@ appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "a
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
diff --git a/src/Notesmaster/gradle/wrapper/gradle-wrapper.properties b/src/Notesmaster/gradle/wrapper/gradle-wrapper.properties
index bdebd24..aa06c61 100644
--- a/src/Notesmaster/gradle/wrapper/gradle-wrapper.properties
+++ b/src/Notesmaster/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,10 @@
+<<<<<<< Updated upstream
#Sat Nov 02 15:11:55 CST 2024
+=======
+#Sat Nov 02 20:32:20 CST 2024
+>>>>>>> Stashed changes
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/src/Notesmaster/settings.gradle.kts b/src/Notesmaster/settings.gradle.kts
index 5300e56..a95826f 100644
--- a/src/Notesmaster/settings.gradle.kts
+++ b/src/Notesmaster/settings.gradle.kts
@@ -21,3 +21,4 @@ dependencyResolutionManagement {
rootProject.name = "Notesmaster"
include(":app")
+
\ No newline at end of file