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.
xiaomibiaoqian/NotesProvider.java

307 lines
14 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.

/*
* 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
*
* 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.
*/
package net.micode.notes.data;//放在data包中
import android.app.SearchManager; //提供对系统搜索的访问
import android.content.ContentProvider; //Android提供的应用程序之间的数据共享
import android.content.ContentUris; //用于获取uri路径后面的ID部分
import android.content.ContentValues; //一种存储机制
import android.content.Intent; //传输
import android.content.UriMatcher;//用于匹配URI
import android.database.Cursor; //用于Android数据库的操作
import android.database.sqlite.SQLiteDatabase; //Android数据库管理
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; //接口
public class NotesProvider extends ContentProvider { //继承于contentprovider
private static final UriMatcher mMatcher; //定义一个URImatcher类的私有静态常量对象
private NotesDatabaseHelper mHelper; //一个自己包中的类的私有对象
private static final String TAG = "NotesProvider"; //一个静态常量string类的对象
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 { //静态代码块在程序创建jvm时就运行只执行一次
mMatcher = new UriMatcher(UriMatcher.NO_MATCH); //创建并传入没有匹配的URI的返回码
mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); //
mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); // /#为通配符
mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA);
mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM); //adduri用来注册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); // /* 为任意字符
}
/**
* 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 + ","
+ "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;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Cursor c = null;
SQLiteDatabase db = mHelper.getReadableDatabase();
String id = null;
switch (mMatcher.match(uri)) { //现有的URI与注册的URI进行匹配
case URI_NOTE:
c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
sortOrder); //查询note表
break;
case URI_NOTE_ITEM:
id = uri.getPathSegments().get(1); //将URI分割1代表的是id
c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id
+ parseSelection(selection), selectionArgs, null, null, sortOrder); //查询id
break;
case URI_DATA:
c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null,
sortOrder); //查询data数据表
break;
case URI_DATA_ITEM:
id = uri.getPathSegments().get(1); //将URI分割获得id
c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id
+ parseSelection(selection), selectionArgs, null, null, sortOrder); //查询该id
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) { //截取的路径list表的大小
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 }); //sql语句查询并替换
} catch (IllegalStateException ex) {
Log.e(TAG, "got exception: " + ex.toString()); //记录日志
}
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri); //抛出异常
}
if (c != null) {
c.setNotificationUri(getContext().getContentResolver(), uri);
}
return c;
}
@Override
public Uri insert(Uri uri, ContentValues values) { //重写插入
SQLiteDatabase db = mHelper.getWritableDatabase(); //获得数据库对象
long dataId = 0, noteId = 0, insertedId = 0;
switch (mMatcher.match(uri)) { //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);
}
// 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);
}
return ContentUris.withAppendedId(uri, insertedId);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) { //重写delete方法
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase(); //获取数据库对象
boolean deleteData = false;
switch (mMatcher.match(uri)) { //获得匹配码
case URI_NOTE:
selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 ";
count = db.delete(TABLE.NOTE, selection, selectionArgs);
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;
}
count = db.delete(TABLE.NOTE,
NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); //删除
break;
case URI_DATA:
count = db.delete(TABLE.DATA, selection, selectionArgs); //删除data
deleteData = true;
break;
case URI_DATA_ITEM:
id = uri.getPathSegments().get(1);
count = db.delete(TABLE.DATA,
DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); //删除dataitem
deleteData = true;
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri); //抛出异常
}
if (count > 0) {
if (deleteData) {
getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null);
}
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
}
@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;
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 //note的更新
+ parseSelection(selection), selectionArgs);
break;
case URI_DATA:
count = db.update(TABLE.DATA, values, selection, selectionArgs); //data的更新
updateData = true;
break;
case URI_DATA_ITEM:
id = uri.getPathSegments().get(1);
count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id //dataitem的更新
+ parseSelection(selection), selectionArgs);
updateData = true;
break;
default:
throw new IllegalArgumentException("Unknown 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); //容量为120
sql.append("UPDATE "); //拼接更新
sql.append(TABLE.NOTE); //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;
}
}