上一篇博客讲了怎样去生成自己的数据库,以及对数据库的一些基本操作。在Android系统中,我们发现很多数据都是通过一个URi查询的,如联系人、短信等。要使你的数据支持通过Uri查询就需要实现自己的ContentProvider。
是否需要构建自己的ContentProvider
在你创建自己的ContentProvider之前,你得搞清楚自己的需求是否真的需要实现一个ContentProvider,满足以下一个或者多个需求的时候,你才需要创建自己的ContentProvider,否则不需要:
1、你的应用程序需要给其他应用提供复杂数据,如联系人,除了本身使用联系人数据外,还要把这些数据共享短信等应用;
2、你想给搜索框架提供自定义的搜索建议。
设计你的查询Uri
一个查询URI是由"scheme"、"authority"、"path"组成,还有一个可选择的"id"部分,带有id的URI对应了表格中的某一行。"scheme"一般指定为"content";为了各个Provider之间不产生冲突,"authority"推荐使用应用程序的包名,例如例子中使用的是"com.ns.note";"path"设置成表格名称即可。在构建URI的过程中,我们可以借助"Uri.Builder()"工具类,如:
Uri CONTENT_URI = new Uri.Builder().scheme(SCHEME).authority(AUTHORITY).path(TABLE_NAME).build();
处理Content URI中的ID
使用URI进行数据查询时,我们可以在URI中接一个ID,用来查询表格中"_id"字段等于ID的对应行的数据,我们可以通过下面代码所示的方式,解析出URI里面的ID:
long id = ContentUris.parseId(uri);
匹配Content URI
为了帮助我们搞清楚传递进来的URI要做的事情,Provider API为我们提供了UriMather类,该类能够根据事先约定好的规则,把URI匹配到一个整数,然后你可以根据这个整数来做对应的操作并返回对应的数据。
可以使用以下通配符来匹配URI:
*:匹配任意长度的有效字符;
#:匹配任一长度的整数字符("12");
private static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
mUriMatcher.addURI(NotesContract.AUTHORITY, NotesContract.Notes.TABLE_NAME, NOTE);
mUriMatcher.addURI(NotesContract.AUTHORITY, NotesContract.Notes.TABLE_NAME + "/#", NOTE_ID);
}
下面是一个完整的ContentProvider的例子:
package com.ns.sqlite;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
public class NotesProvider extends ContentProvider {
private MaikuDBHelper mDbHelper = null;
private static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int NOTE = 1;
private static final int NOTE_ID = 2;
static {
mUriMatcher.addURI(NotesContract.AUTHORITY, NotesContract.Notes.TABLE_NAME, NOTE);
mUriMatcher.addURI(NotesContract.AUTHORITY, NotesContract.Notes.TABLE_NAME + "/#", NOTE_ID);
}
@Override
public boolean onCreate() {
mDbHelper = new MaikuDBHelper(getContext());
return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int result = -1;
int match = mUriMatcher.match(uri);
switch (match) {
case 1:
result = mDbHelper.getWritableDatabase().delete(NotesContract.Notes.TABLE_NAME, selection, selectionArgs);
break;
case 2:
long id = ContentUris.parseId(uri);
String where = NotesContract.Notes._ID + " = " + id;
if (selection != null && selection.trim().length()> 0) {
where = selection + " and " + where;
}
result = mDbHelper.getWritableDatabase().delete(NotesContract.Notes.TABLE_NAME, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
//通知观察者数据发生变化
getContext().getContentResolver().notifyChange(uri, null);
return result;
}
@Override
public String getType(Uri arg0) {
int match = mUriMatcher.match(arg0);
switch (match) {
case 1:
return "vnd.android.cursor.dir/note";
case 2:
return "vnd.android.cursor.item/person";
default:
throw new IllegalArgumentException("Unkwon Uri:" + arg0.toString());
}
}
@Override
public Uri insert(Uri uri, ContentValues arg1) {
long id = mDbHelper.getWritableDatabase().insert(NotesContract.Notes.TABLE_NAME, null, arg1);
//通知观察者数据发生变化
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(NotesContract.Notes.CONTENT_URI, id);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor cursor = null;
int match = mUriMatcher.match(uri);
switch (match) {
case 1:
cursor = mDbHelper.getReadableDatabase().query(NotesContract.Notes.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
break;
case 2:
long id = ContentUris.parseId(uri);
String where = NotesContract.Notes._ID + " = " + id;
if (selection != null && selection.trim().length() > 0) {
where = selection + " and "+ where;
}
cursor = mDbHelper.getReadableDatabase().query(NotesContract.Notes.TABLE_NAME, projection, where, selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("unknow uri" + uri.toString());
}
if (cursor != null) {
cursor.setNotificationUri(getContext().getContentResolver(), uri);
}
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int result = -1;
int match = mUriMatcher.match(uri);
switch (match) {
case 1:
result = mDbHelper.getWritableDatabase().update(NotesContract.Notes.TABLE_NAME, values, selection, selectionArgs);
break;
case 2:
long id = ContentUris.parseId(uri);
String where = NotesContract.Notes._ID + " = " + id;
if (selection != null && selection.trim().length() > 0) {
where = selection + " and " + where;
}
result = mDbHelper.getWritableDatabase().update(NotesContract.Notes.TABLE_NAME, values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("unknow uri" + uri.toString());
}
//通知观察者数据发生变化
getContext().getContentResolver().notifyChange(uri, null);
return result;
}
}
待续.....
说明:由于是第一次比较正经的写博客,可能内容组织不是太好,我会慢慢修改,知道自己满意为止。