diff --git a/src/Notes-master/app/src/main/java/net/micode/notes/data/NotesProvider.java b/src/Notes-master/app/src/main/java/net/micode/notes/data/NotesProvider.java index edb0a60..d5dda17 100644 --- a/src/Notes-master/app/src/main/java/net/micode/notes/data/NotesProvider.java +++ b/src/Notes-master/app/src/main/java/net/micode/notes/data/NotesProvider.java @@ -16,7 +16,6 @@ package net.micode.notes.data; - import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentUris; @@ -34,22 +33,25 @@ import net.micode.notes.data.Notes.DataColumns; import net.micode.notes.data.Notes.NoteColumns; import net.micode.notes.data.NotesDatabaseHelper.TABLE; - +/** + * NotesProvider是一个内容提供者,用于管理小米便签应用的数据访问。 + * 它通过统一的URI接口对外提供便签和文件夹的CRUD操作,并支持搜索功能。 + */ public class NotesProvider extends ContentProvider { + // URI匹配器,用于解析不同的URI请求类型 private static final UriMatcher mMatcher; - private NotesDatabaseHelper mHelper; - private static final String TAG = "NotesProvider"; - private static final int URI_NOTE = 1; - private static final int URI_NOTE_ITEM = 2; - private static final int URI_DATA = 3; - private static final int URI_DATA_ITEM = 4; - - private static final int URI_SEARCH = 5; - private static final int URI_SEARCH_SUGGEST = 6; + // URI匹配码常量 + private static final int URI_NOTE = 1; // 匹配所有便签/文件夹 + private static final int URI_NOTE_ITEM = 2; // 匹配单个便签/文件夹 + private static final int URI_DATA = 3; // 匹配所有数据项 + private static final int URI_DATA_ITEM = 4; // 匹配单个数据项 + private static final int URI_SEARCH = 5; // 匹配搜索请求 + private static final int URI_SEARCH_SUGGEST = 6; // 匹配搜索建议请求 + // 初始化URI匹配器 static { mMatcher = new UriMatcher(UriMatcher.NO_MATCH); mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); @@ -62,8 +64,8 @@ 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 + "," + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + "," @@ -73,28 +75,46 @@ public class NotesProvider extends ContentProvider { + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + "," + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA; + /** + * 便签搜索的SQL查询语句 + * 搜索便签内容并排除回收站中的便签 + */ 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; + /** + * 初始化ContentProvider + * @return 初始化成功返回true + */ @Override public boolean onCreate() { mHelper = NotesDatabaseHelper.getInstance(getContext()); return true; } + /** + * 根据URI查询数据 + * @param uri 查询的URI + * @param projection 需要返回的列 + * @param selection 查询条件 + * @param selectionArgs 查询条件参数 + * @param sortOrder 排序方式 + * @return 返回符合条件的Cursor + */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor c = null; SQLiteDatabase db = mHelper.getReadableDatabase(); String id = null; + + // 根据不同的URI类型执行不同的查询操作 switch (mMatcher.match(uri)) { case URI_NOTE: - c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, - sortOrder); + c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, sortOrder); break; case URI_NOTE_ITEM: id = uri.getPathSegments().get(1); @@ -102,8 +122,7 @@ public class NotesProvider extends ContentProvider { + parseSelection(selection), selectionArgs, null, null, sortOrder); break; case URI_DATA: - c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null, - sortOrder); + c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null, sortOrder); break; case URI_DATA_ITEM: id = uri.getPathSegments().get(1); @@ -112,11 +131,13 @@ public class NotesProvider extends ContentProvider { break; case URI_SEARCH: case URI_SEARCH_SUGGEST: + // 搜索功能不支持自定义排序和投影 if (sortOrder != null || projection != null) { throw new IllegalArgumentException( "do not specify sortOrder, selection, selectionArgs, or projection" + "with this query"); } + // 提取搜索关键词 String searchString = null; if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) { if (uri.getPathSegments().size() > 1) { @@ -126,14 +147,15 @@ public class NotesProvider extends ContentProvider { searchString = uri.getQueryParameter("pattern"); } + // 关键词为空则返回空结果 if (TextUtils.isEmpty(searchString)) { return null; } try { + // 执行模糊搜索 searchString = String.format("%%%s%%", searchString); - c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, - new String[] { searchString }); + c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, new String[] { searchString }); } catch (IllegalStateException ex) { Log.e(TAG, "got exception: " + ex.toString()); } @@ -141,16 +163,26 @@ public class NotesProvider extends ContentProvider { default: throw new IllegalArgumentException("Unknown URI " + uri); } + + // 设置通知URI,当数据变化时通知观察者 if (c != null) { c.setNotificationUri(getContext().getContentResolver(), uri); } return c; } + /** + * 向指定URI插入数据 + * @param uri 插入数据的目标URI + * @param values 要插入的数据 + * @return 返回插入数据的URI + */ @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = mHelper.getWritableDatabase(); long dataId = 0, noteId = 0, insertedId = 0; + + // 根据不同的URI类型执行不同的插入操作 switch (mMatcher.match(uri)) { case URI_NOTE: insertedId = noteId = db.insert(TABLE.NOTE, null, values); @@ -166,13 +198,13 @@ public class NotesProvider extends ContentProvider { default: throw new IllegalArgumentException("Unknown URI " + uri); } - // Notify the note uri + + // 通知数据变化 if (noteId > 0) { getContext().getContentResolver().notifyChange( ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null); } - // Notify the data uri if (dataId > 0) { getContext().getContentResolver().notifyChange( ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null); @@ -181,12 +213,21 @@ public class NotesProvider extends ContentProvider { return ContentUris.withAppendedId(uri, insertedId); } + /** + * 根据URI删除数据 + * @param uri 删除数据的目标URI + * @param selection 删除条件 + * @param selectionArgs 删除条件参数 + * @return 返回删除的行数 + */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count = 0; String id = null; SQLiteDatabase db = mHelper.getWritableDatabase(); boolean deleteData = false; + + // 根据不同的URI类型执行不同的删除操作 switch (mMatcher.match(uri)) { case URI_NOTE: selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; @@ -194,10 +235,7 @@ public class NotesProvider extends ContentProvider { break; case URI_NOTE_ITEM: id = uri.getPathSegments().get(1); - /** - * ID that smaller than 0 is system folder which is not allowed to - * trash - */ + // 不允许删除系统文件夹 long noteId = Long.valueOf(id); if (noteId <= 0) { break; @@ -218,6 +256,8 @@ public class NotesProvider extends ContentProvider { default: throw new IllegalArgumentException("Unknown URI " + uri); } + + // 通知数据变化 if (count > 0) { if (deleteData) { getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); @@ -227,12 +267,22 @@ public class NotesProvider extends ContentProvider { return count; } + /** + * 根据URI更新数据 + * @param uri 更新数据的目标URI + * @param values 要更新的数据 + * @param selection 更新条件 + * @param selectionArgs 更新条件参数 + * @return 返回更新的行数 + */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; String id = null; SQLiteDatabase db = mHelper.getWritableDatabase(); boolean updateData = false; + + // 根据不同的URI类型执行不同的更新操作 switch (mMatcher.match(uri)) { case URI_NOTE: increaseNoteVersion(-1, selection, selectionArgs); @@ -258,6 +308,7 @@ public class NotesProvider extends ContentProvider { throw new IllegalArgumentException("Unknown URI " + uri); } + // 通知数据变化 if (count > 0) { if (updateData) { getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); @@ -267,10 +318,21 @@ public class NotesProvider extends ContentProvider { return count; } + /** + * 解析查询条件,处理条件为空的情况 + * @param selection 原始查询条件 + * @return 处理后的查询条件 + */ private String parseSelection(String selection) { return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); } + /** + * 增加便签的版本号,用于数据同步 + * @param id 便签ID,如果为-1则更新所有符合条件的便签 + * @param selection 更新条件 + * @param selectionArgs 更新条件参数 + */ private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { StringBuilder sql = new StringBuilder(120); sql.append("UPDATE "); @@ -279,6 +341,7 @@ public class NotesProvider extends ContentProvider { sql.append(NoteColumns.VERSION); sql.append("=" + NoteColumns.VERSION + "+1 "); + // 构建WHERE子句 if (id > 0 || !TextUtils.isEmpty(selection)) { sql.append(" WHERE "); } @@ -293,13 +356,18 @@ public class NotesProvider extends ContentProvider { sql.append(selectString); } + // 执行SQL语句 mHelper.getWritableDatabase().execSQL(sql.toString()); } + /** + * 获取URI对应的数据类型 + * @param uri 目标URI + * @return 返回数据类型的MIME类型 + */ @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } - -} +} \ No newline at end of file