You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
test-1/NotesProvider.java

319 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package net.micode.notes.data;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import net.micode.notes.R;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.NotesDatabaseHelper.TABLE;
// 继承自ContentProvider用于提供对笔记数据的访问接口
public class NotesProvider extends ContentProvider {
// UriMatcher用于匹配传入的Uri确定操作类型
private static final UriMatcher mMatcher;
// 数据库帮助类实例
private NotesDatabaseHelper mHelper;
private static final String TAG = "NotesProvider";
// 定义不同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 {
// 初始化UriMatcher
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// 添加note表的Uri匹配规则
mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE);
mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM);
// 添加data表的Uri匹配规则
mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA);
mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM);
// 添加搜索相关的Uri匹配规则
mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH);
mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST);
mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST);
}
// 用于搜索结果的投影包括笔记的ID、标题、内容等信息
private static final String NOTES_SEARCH_PROJECTION = NoteColumns.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;
// 用于搜索笔记片段的查询语句
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执行相应的查询操作并返回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:
// 查询note表
c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
sortOrder);
break;
case URI_NOTE_ITEM:
// 查询单个note项
id = uri.getPathSegments().get(1);
c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id
+ parseSelection(selection), selectionArgs, null, null, sortOrder);
break;
case URI_DATA:
// 查询data表
c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null,
sortOrder);
break;
case URI_DATA_ITEM:
// 查询单个data项
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");
}
String searchString = null;
if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) {
if (uri.getPathSegments().size() > 1) {
searchString = uri.getPathSegments().get(1);
}
} else {
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});
} catch (IllegalStateException ex) {
Log.e(TAG, "got exception: " + ex.toString());
}
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
// 设置通知Uri以便数据变化时通知观察者
if (c!= null) {
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;
// 根据Uri匹配码执行不同的插入操作
switch (mMatcher.match(uri)) {
case URI_NOTE:
// 插入note表
insertedId = noteId = db.insert(TABLE.NOTE, null, values);
break;
case URI_DATA:
// 插入data表
if (values.containsKey(DataColumns.NOTE_ID)) {
noteId = values.getAsLong(DataColumns.NOTE_ID);
} else {
Log.d(TAG, "Wrong data format without note id:" + values.toString());
}
insertedId = dataId = db.insert(TABLE.DATA, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
// 通知note表的Uri数据变化
if (noteId > 0) {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null);
}
// 通知data表的Uri数据变化
if (dataId > 0) {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null);
}
return ContentUris.withAppendedId(uri, insertedId);
}
// 删除数据的方法根据Uri从相应的表中删除数据
@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:
// 删除note表中的数据
selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 ";
count = db.delete(TABLE.NOTE, selection, selectionArgs);
break;
case URI_NOTE_ITEM:
// 删除单个note项
id = uri.getPathSegments().get(1);
long noteId = Long.valueOf(id);
if (noteId <= 0) {
break;
}
count = db.delete(TABLE.NOTE,
NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs);
break;
case URI_DATA:
// 删除data表中的数据
count = db.delete(TABLE.DATA, selection, selectionArgs);
deleteData = true;
break;
case URI_DATA_ITEM:
// 删除单个data项
id = uri.getPathSegments().get(1);
count = db.delete(TABLE.DATA,
DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs);
deleteData = true;
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
// 如果删除了数据通知相关Uri的数据变化
if (count > 0) {
if (deleteData) {
getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null);
}
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
}
// 更新数据的方法根据Uri更新相应表中的数据
@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:
// 更新note表中的数据
increaseNoteVersion(-1, selection, selectionArgs);
count = db.update(TABLE.NOTE, values, selection, selectionArgs);
break;
case URI_NOTE_ITEM:
// 更新单个note项
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:
// 更新data表中的数据
count = db.update(TABLE.DATA, values, selection, selectionArgs);
updateData = true;
break;
case URI_DATA_ITEM:
// 更新单个data项
id = uri.getPathSegments().get(1);
count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id
+ parseSelection(selection), selectionArgs);
updateData = true;
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
// 如果更新了数据通知相关Uri的数据变化
if (count > 0) {
if (updateData) {
getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null);
}
getContext().getContentResolver().notifyChange(uri, null);
}
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 ");
sql.append(TABLE.NOTE);
sql.append(" SET ");
sql.append(NoteColumns.VERSION);
sql.append("=" + NoteColumns.VERSION + "+1 ");
if (id > 0 ||!TextUtils.isEmpty(selection)) {
sql.append(" WHERE ");
}
if (id > 0) {
sql.append(NoteColumns.ID + "=" + String.valueOf(id));
}
if (!TextUtils.isEmpty(selection)) {
String selectString = id > 0? parseSelection(selection) : selection;
for (String args : selectionArgs) {
selectString = selectString.replaceFirst("\\?", args);
}
sql.append(selectString);
}
mHelper.getWritableDatabase().execSQL(sql.toString());
}
// 获取数据类型的方法(未实现)
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
}