在Android我们能通过建立当前应用的数据库SQLiteDataBase,供本应用对数据的存取。但当多个应用需要共用同一数据时,我们怎么办呢?在Android系统中没有一个公共的内存区域,供多个应用共享存储数据。这里就要用到ContentProvider(内容提供者)。
Android中的ContentProvider机制可支持在多个应用中存储和读取数据。这也是跨应用共享数据的唯一方式。
ContentProvider 实际上就是提供一个接口方法,多个应用可以通过接口方法访问同一数据库的内容,即用到ContentResolver(内容解析者)来调用方法。
在配置文件中声明ContentProvider并设置权限(authorities),其他应用通过权限获取访问内容提供者的资格。
首先创建一个数据库,可见上一篇博客。
然后实现内容提供者类实现ContentProvider接口,并实现其中的方法
public class StudentProvider extends ContentProvider { private StudentDb dbhelp=null; //声明创建数据库的SQLiteOpenHelper //创建一个路径适配对象,用于匹配访问应用给的访问路径,默认没有匹配 private static final UriMatcher URI_MATCH=new UriMatch(UriMatcher.NO_MATCH); private static final int STUDENT=1; //操作单条数据库记录 private static final int STUDENTS=2; //操作多条数据库记录 //定义匹配规则,#匹配任何数字,*匹配任何文字 static{ URI_MATCH.addURI("com.exmple.android_contentProvider.StudentProvider/#", "student", STUDENT); URI_MATCH.addURI("com.exmple.android_contentProvider.StudentProvider", "student", STUDENTS); } @Override public boolean onCreate() { dbhelp=new StudentDb(getContext()); //获取创建数据库的容器 return false; } //查询数据 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor=null; int flag=URI_MATCH.match(uri); //匹配 SQLiteDatabase database=dbhelp.getWritableDatabase();//获取数据库 switch (flag) { case STUDENT: long id=ContentUris.parseId(uri); //获取记录的id值, String where_value=" id="+id; if(selection!=null&&!"".equals(selection)){ where_value=where_value+" and "+selection; } cursor=database.query("student", null, where_value, selectionArgs, null, null, null); //数据库执行查询语句返回一个游标 break; case STUDENTS: //查询多条记录 cursor=database.query("student", null, selection, selectionArgs, null, null, null, null); default: break; } return cursor; //返回数据库的游标 } //重写getType方法,处理uri头部信息 @Override public String getType(Uri uri) { int flag=URI_MATCH.match(uri); switch (flag) { case STUDENT: return "vnd.android.cursor.item/student "; case STUDENTS: return "vnd.android.cursor.dir/student "; } return null; } //插入数据 @Override public Uri insert(Uri uri, ContentValues values) { Uri resultUri=null; int flag=URI_MATCH.match(uri); switch (flag) { case STUDENTS: SQLiteDatabase database=dbhelp.getWritableDatabase(); long id=database.insert("student",null, values); resultUri=ContentUris.withAppendedId(uri, id); break; default: break; } return resultUri; } //删除数据 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count=-1; //影响数据库的行数 int flag=URI_MATCH.match(uri); //匹配路径 SQLiteDatabase database=dbhelp.getWritableDatabase(); switch (flag) { case STUDENT: //通过客户端传过来id long id=ContentUris.parseId(uri); String where_value=" id="+id; if(selection!=null&&!"".equals(selection)){ where_value=where_value+" and "+selection; //获取删除条件 } count=database.delete("student", where_value, selectionArgs); break; case STUDENTS: count=database.delete("student",selection, selectionArgs); break; default: break; } return count; } //更新数据 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count=-1; int flag=URI_MATCH.match(uri); SQLiteDatabase database=dbhelp.getWritableDatabase(); switch (flag) { case STUDENT: long id=ContentUris.parseId(uri); String where_value=" id="+id; if(selection!=null&&!"".equals(selection)){ where_value=where_value+" and "+selection; } count=database.update("student", values, where_value, selectionArgs); break; default: break; } return count; } }
内容解析者通过调用内容提供者的方法处理数据库,注意路径的规则:content://+权限
public class MyTest extends AndroidTestCase { //向内容提供者数据库中插入数据 public void insert(){ //获取内容解析者 ContentResolver resolver=getContext().getContentResolver(); //content://+权限 Uri url=Uri.parse("content://com.exmple.android_contentProvider.StudentProvider/student"); ContentValues values=new ContentValues(); values.put("name","fangbing"); values.put("address", "hunan"); resolver.insert(url, values); } }