diff --git a/Notes-master/src/net/micode/notes/data/NotesProvider.java b/Notes-master/src/net/micode/notes/data/NotesProvider.java index edb0a60..6d3ccfe 100644 --- a/Notes-master/src/net/micode/notes/data/NotesProvider.java +++ b/Notes-master/src/net/micode/notes/data/NotesProvider.java @@ -2,21 +2,15 @@ * 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 + * 您可以在遵守License的前提下使用本文件 + * 具体License内容可查阅:http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * 软件按"原样"分发,不提供任何形式的明示或暗示的保证 + * 详见License中关于权限和限制的具体条款 */ package net.micode.notes.data; - import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentUris; @@ -34,23 +28,28 @@ import net.micode.notes.data.Notes.DataColumns; import net.micode.notes.data.Notes.NoteColumns; import net.micode.notes.data.NotesDatabaseHelper.TABLE; - +/** + * 笔记应用的内容提供者 + * 实现了Android ContentProvider接口,提供标准化的数据访问API + * 支持笔记和附属数据的CRUD操作以及全文搜索功能 + */ public class NotesProvider extends ContentProvider { + // URI匹配器,用于解析不同的URI请求 private static final UriMatcher mMatcher; - private NotesDatabaseHelper mHelper; - + 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; // 搜索建议 static { + // 初始化URI匹配器 mMatcher = new UriMatcher(UriMatcher.NO_MATCH); mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); @@ -62,8 +61,12 @@ 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. + * 笔记搜索投影定义 + * 定义了搜索结果的字段映射关系,包括: + * - 笔记ID + * - 搜索建议文本(去除换行符) + * - 图标资源 + * - 点击意图(查看笔记详情) */ private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + "," + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + "," @@ -73,18 +76,31 @@ 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; + /** + * 内容提供者初始化 + * 获取数据库辅助类实例 + */ @Override public boolean onCreate() { mHelper = NotesDatabaseHelper.getInstance(getContext()); return true; } + /** + * 查询数据 + * 根据不同的URI类型执行相应的数据库查询操作 + * 支持笔记查询、附属数据查询和搜索功能 + */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { @@ -93,25 +109,30 @@ public class NotesProvider extends ContentProvider { String id = null; switch (mMatcher.match(uri)) { case URI_NOTE: + // 查询所有笔记 c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, sortOrder); break; case URI_NOTE_ITEM: + // 查询单个笔记 id = uri.getPathSegments().get(1); c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs, null, null, sortOrder); break; case URI_DATA: + // 查询所有附属数据 c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null, sortOrder); break; case URI_DATA_ITEM: + // 查询单个附属数据 id = uri.getPathSegments().get(1); c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs, null, null, sortOrder); 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"); @@ -131,6 +152,7 @@ public class NotesProvider extends ContentProvider { } try { + // 构建模糊搜索条件并执行查询 searchString = String.format("%%%s%%", searchString); c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, new String[] { searchString }); @@ -142,20 +164,28 @@ public class NotesProvider extends ContentProvider { throw new IllegalArgumentException("Unknown URI " + uri); } if (c != null) { + // 设置通知URI,数据变化时通知观察者 c.setNotificationUri(getContext().getContentResolver(), uri); } return c; } + /** + * 插入数据 + * 根据不同的URI类型执行相应的插入操作 + * 插入后通知数据变化 + */ @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = mHelper.getWritableDatabase(); long dataId = 0, noteId = 0, insertedId = 0; switch (mMatcher.match(uri)) { case URI_NOTE: + // 插入笔记 insertedId = noteId = db.insert(TABLE.NOTE, null, values); break; case URI_DATA: + // 插入附属数据 if (values.containsKey(DataColumns.NOTE_ID)) { noteId = values.getAsLong(DataColumns.NOTE_ID); } else { @@ -166,13 +196,12 @@ public class NotesProvider extends ContentProvider { default: throw new IllegalArgumentException("Unknown URI " + uri); } - // Notify the note uri + // 通知笔记和数据的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,6 +210,12 @@ public class NotesProvider extends ContentProvider { return ContentUris.withAppendedId(uri, insertedId); } + /** + * 删除数据 + * 根据不同的URI类型执行相应的删除操作 + * 不允许删除系统文件夹(ID <= 0) + * 删除后通知数据变化 + */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count = 0; @@ -195,8 +230,7 @@ public class NotesProvider extends ContentProvider { case URI_NOTE_ITEM: id = uri.getPathSegments().get(1); /** - * ID that smaller than 0 is system folder which is not allowed to - * trash + * ID <= 0 的是系统文件夹,不允许删除 */ long noteId = Long.valueOf(id); if (noteId <= 0) { @@ -219,6 +253,7 @@ public class NotesProvider extends ContentProvider { throw new IllegalArgumentException("Unknown URI " + uri); } if (count > 0) { + // 通知数据变化 if (deleteData) { getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); } @@ -227,6 +262,12 @@ public class NotesProvider extends ContentProvider { return count; } + /** + * 更新数据 + * 根据不同的URI类型执行相应的更新操作 + * 更新笔记时自动增加版本号 + * 更新后通知数据变化 + */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; @@ -235,20 +276,24 @@ public class NotesProvider extends ContentProvider { boolean updateData = false; switch (mMatcher.match(uri)) { case URI_NOTE: + // 更新笔记集合,增加版本号 increaseNoteVersion(-1, selection, selectionArgs); count = db.update(TABLE.NOTE, values, selection, selectionArgs); break; case URI_NOTE_ITEM: + // 更新单个笔记,增加版本号 id = uri.getPathSegments().get(1); increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); break; case URI_DATA: + // 更新附属数据集合 count = db.update(TABLE.DATA, values, selection, selectionArgs); updateData = true; break; case URI_DATA_ITEM: + // 更新单个附属数据 id = uri.getPathSegments().get(1); count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); @@ -259,6 +304,7 @@ public class NotesProvider extends ContentProvider { } if (count > 0) { + // 通知数据变化 if (updateData) { getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); } @@ -267,10 +313,18 @@ public class NotesProvider extends ContentProvider { return count; } + /** + * 解析查询条件 + * 将附加的查询条件添加到主条件中 + */ private String parseSelection(String selection) { return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); } + /** + * 增加笔记版本号 + * 用于记录数据变更,支持同步冲突检测 + */ private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { StringBuilder sql = new StringBuilder(120); sql.append("UPDATE "); @@ -279,6 +333,7 @@ public class NotesProvider extends ContentProvider { sql.append(NoteColumns.VERSION); sql.append("=" + NoteColumns.VERSION + "+1 "); + // 构建更新条件 if (id > 0 || !TextUtils.isEmpty(selection)) { sql.append(" WHERE "); } @@ -296,10 +351,13 @@ public class NotesProvider extends ContentProvider { mHelper.getWritableDatabase().execSQL(sql.toString()); } + /** + * 获取URI对应的MIME类型 + * 目前未实现,返回null + */ @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } - -} +} \ No newline at end of file