在Android我们能通过建立当前应用的数据库SQLiteDataBase,供本应用对数据的存取。但当多个应用需要共用同一数据时,我们怎么办呢?在Android系统中没有一个公共的内存区域,供多个应用共享存储数据。这里就要用到ContentProvider(内容提供者)。
Android中的ContentProvider机制可支持在多个应用中存储和读取数据。这也是跨应用共享数据的唯一方式。
ContentProvider 实际上就是提供一个接口方法,多个应用可以通过接口方法访问同一数据库的内容,即用到ContentResolver(内容解析者)来调用方法。
在配置文件中声明ContentProvider并设置权限(authorities),其他应用通过权限获取访问内容提供者的资格。
<provider android:name=".StudentProvider" android:authorities="com.exmple.android_contentProvider.StudentProvider"/>
首先创建一个数据库,可见上一篇博客。
然后实现内容提供者类实现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);
}
}