基于上一篇的数据库操作,又写了一个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.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的就新修改的数据。 其他的实现没有写。可以类比。