基于上一篇的数据库操作,又写了一个ContentProvider的示例。把SQLiter 的数据提供出去供别的项目进行访问。
这一篇的代码要求熟悉SQLiter 的API.
首先,我们编写一个类extents ContentProvider ,重写他的方法。
URI 在http 中我们称为统一资源定位符,就是可以通过uri定位到网络上某一资源。比方如:http://blog.youkuaiyun.com/liuc0317/article/details/6771233,
http:// 是网终协议,是一个标准和规定。
- public boolean onCreate() {}是在项目首次使用ContentProvider 的时候调用,只会调用一次,适合初始化一些数据。
- public Uri insert(Uri uri, ContentValues values) {} 是否可供外部插入数据,如果需要插入数据就重写。
- public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {}是否可供外部更新数据,如果需要更新数据就重写。
- public int delete(Uri uri, String selection, String[] selectionArgs) {}是否可供外部删除数据,如果需要删除数据就重写。
- public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {}是否可供外部查询数据,如果需要查询数据就重写。
- public String getType(Uri uri) {} 可以获取到操作的类弄,如果是集合类型就会返回。vnd.android.cursor.dir/ 。如果是单条数据就返回vnd.android.cursor.item/
重写这么方法后需要填写一个可以精确定位到此ContentProvider 的声明:
<application android:icon="@drawable/icon" android:label="@string/app_name">
......
<provider android:name=".PersonContentProvoider" android:authorities="com.hkrt.providers.personprovider"/>
</application>
具体实现如下:
PersonContentProvider.java
package com.hkrt.db;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import com.hkrt.server.PersonHelper;
/**
* 内容的提供者不一定是数据库 可以是xml 或是网上资源
* 在这里我们需要学习ContentProvider 和ContentUris工具类的使用方法
* @author Administrator
*
*/
public class PersonContentProvoider extends ContentProvider {
private PersonHelper helper;
private static final String TABLENAME="person";
private static final String ID="id";
private static final UriMatcher MATCHER=new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSONS=1;
private static final int PERSON=2;
static{
MATCHER.addURI("com.hkrt.providers.personprovider", "person", PERSONS);// 配置模式1 person 表中所有的记录数据
MATCHER.addURI("com.hkrt.providers.personprovider", "person/#", PERSON); //配置模式2 person 表中id为指定的数据,# 是指标识
}
// 允许删除数据
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
int num=0;
switch (MATCHER.match(uri)) {
case PERSONS:
num=db.delete(TABLENAME, selection, selectionArgs);
break;
case PERSON:
long personId = ContentUris.parseId(uri);
String where=ID+"="+personId;
num=db.delete(TABLENAME, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unkown url:"+uri);
}
return num;
}
@Override
public String getType(Uri uri) {
switch (MATCHER.match(uri)) {
case PERSONS:
return "vnd.android.cursor.dir/";
case PERSON:
return "vnd.android.cursor.item/";
default:
break;
}
return null;
}
//允许插入数据
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db =helper.getWritableDatabase();
switch (MATCHER.match(uri)) {
case 1:
long rowid = db.insert(TABLENAME, null, values);
return ContentUris.withAppendedId(uri, rowid);
default:
throw new IllegalArgumentException("Unkown URI:"+uri);
}
}
//ContentProvider 第一次被调用时获取数据库的使用权
@Override
public boolean onCreate() {
helper = new PersonHelper(this.getContext());
return true;
}
//允许查询数据
@Override
public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor;
switch (MATCHER.match(uri)) {
case PERSONS:
cursor = db.query(TABLENAME, projection, selection, selectionArgs, null, null, sortOrder);
break;
case PERSON:
long personId= ContentUris.parseId(uri);
String where =ID+"="+personId;
if(selection!=null && !"".equals(selection.trim())){
where+=selection;
}
cursor = db.query(TABLENAME, null, where, selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Unkown uri:"+uri);
}
return cursor;
}
//允许更新数据
//person
//person/12
@Override
public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
SQLiteDatabase db =helper.getWritableDatabase();
int num=0;
switch (MATCHER.match(uri)) {
case PERSONS:
num =db.update(TABLENAME, values, selection, selectionArgs);
break;
case PERSON:
long personid= ContentUris.parseId(uri);
String where=ID +"=" + personid;
if(selection!=null && !"".equals(selection.trim())){
where+=" and "+selection;
}
num =db.update(TABLENAME, values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unkown URI:"+uri);
}
return num;
}
}
以上的代码就可以把person 数据表中所有操作,提供出来供别的程序访问了。
工具类ContentUris 的使用:
Uri uri=Uri.parse("content://com.hkrt.providers.personprovider/person");
String rowid="2"
Uri uri2=Uri.parse("content://com.hkrt.providers.personprovider/person/2");
- ContentUris.withAppendedId(uri, rowid); // 现在的结果就是com.hkrt.providers.personprovider/person/2
- ContentUris.parseId(uri2);// 那么也在的就结果就是2
再下来我们测试我写的代码是否正确,我们需要使用androidTestCase 进行测试,测试环境还需要搭建。
我在其他的项目中新建了一个类进行对ContentProvider 的代码进行测试。实现代码如下:
package com.hkrt;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;
public class ContentProviderTest extends AndroidTestCase {
String TAG="ContentProviderTest";
// 测试访问ContentProvider 插入数据
public void testAccessContentProvider() throws Throwable{
Uri uri = Uri.parse("content://com.hkrt.providers.personprovider/person");
ContentResolver resolver = this.getContext().getContentResolver();
ContentValues values = new ContentValues();
values.put("name", "宋江");
Uri url = resolver.insert(uri, values);
Log.i(TAG, url.toString());
}
//测试访问ContentProvider 更新数据
public void updateContentProvider() throws Throwable{
Uri uri = Uri.parse("content://com.hkrt.providers.personprovider/person/2");
ContentResolver resolver = this.getContext().getContentResolver();
long personId = ContentUris.parseId(uri);
String where ="id=?";
ContentValues values = new ContentValues();
values.put("name", "刘成");
String [] result ={String.valueOf(personId)};
int rowid = resolver.update(uri, values, where, result);
Log.i(TAG, String.valueOf(rowid));
}
}
经过我的测试没有问题。我把结果导出后的插图如下:

注:id为6的新插入的数据,id为2的就新修改的数据。 其他的实现没有写。可以类比。