基于上一篇的数据库操作,又写了一个ContentProvider的示例。把SQLiter 的数据提供出去供别的项目进行访问。
这一篇的代码要求熟悉SQLiter 的API.
首先,我们编写一个类extents ContentProvider ,重写他的方法。
URI 在http 中我们称为统一资源定位符,就是可以通过uri定位到网络上某一资源。比方如:http://blog.csdn.net/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.javapackage 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为指定的数据,# 是指标识}// 允许删除数据@Overridepublic 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;}@Overridepublic 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;}//允许插入数据@Overridepublic 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 第一次被调用时获取数据库的使用权@Overridepublic boolean onCreate() {helper = new PersonHelper(this.getContext());return true;}//允许查询数据 @Overridepublic 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 @Overridepublic 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的就新修改的数据。 其他的实现没有写。可以类比。