ContentProvider在Android中的作用是对外共享数据,也就是说可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对应用中数据进行添、删、改、查。使用ContentProvider对外共享数据的好处是,统一了数据的访问方式,它实际上是对SQLiteOpenHelper的进一步封装,通过Uri映射来判断选择需要操作数据库中的哪个表,并且进行增删改查处理。
ContentProvider为存储和读取数据提供了统一的接口
使用ContentProvider,应用程序可以实现数据共享
android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)。
Uri格式:
ContentProvider的schema已经由Android固定设置为content://。Authority用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。path是要操作的数据库表。id查询关键字是可选字段,指定特定的某一数据项。
Uri uri = Uri.parse("content://contacts/people");
Anroid系统根据Uri来定位注册到系统的ContentProvider中,找到ContentProvider之后会通过ContentResolver来操作。
-
UriMatcher类
因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher和ContentUris 。UriMatcher类用于匹配Uri:
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://com.cwd.provider.personprovider/person路径,返回匹配码为1
sMatcher.addURI("com.cwd.provider.personprovider", "person", 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://com.cwd.provider.personprovider/person/10路径,返回匹配码为2
sMatcher.addURI("com.cwd.provider.personprovider", "person/#", 2);//#号为通配符
switch (sMatcher.match(Uri.parse("content://com.cwd.provider.personprovider/person/10"))) {
case 1
break;
case 2
break;
default://不匹配
break;
}
-
ContentUris类
ContentUris类用于操作Uri路径后面的ID部分,它有两个方法:
withAppendedId(uri, id)用于为路径加上ID部分:
Uri uri = Uri.parse("content://com.cwd.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10);
parseId(uri)方法用于从路径中获取ID部分:
Uri uri = Uri.parse("content://com.cwd.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);
示例:
在ContentProvider中存储人员的信息,首先定义一个ContentProvider
public class UserInfoProvider extends ContentProvider{
private static final String CONTENT = "content://";
public static final String AUTHORIY = "com.book.jtm.info";
//该ContentProvider所返回的数据类型定义、数据集合
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd." +AUTHORIY;
//单项数据
public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd." + AUTHORIY;
//数据集合操作时的Uri
public static final Uri POSTCODE_URI = Uri.parse(CONTENT + AUTHORIY + "/" + UserInfoDbHelper.TABLE_USER_INFO);
private SQLiteDatabase mDatabase;
static final int USER_INFOS = 1;
static final int USER_INFO_ITEM = 2;
static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static{
uriMatcher.addURI(AUTHORIY, "userinfo", USER_INFOS);
uriMatcher.addURI(AUTHORIY, "userinfo/*", USER_INFOS_ITEM);
}
@Override
public String getType(Uri uri){
switch(uriMatcher.match(uri)){
case USER_INFOS:
return CONTENT_TYPE;
case USER_INFOS_ITEM:
return CONTENT_TYPE_ITEM;
default:
throw new RuntimeException("错误的Uri");
}
}
@Override
public boolean onCreate(){
mDatabase = new UserInfoDbHelper(getContext).getWritableDatabase();
return true;
}
@Override
public Uri insert(Uri uri, ContentValue values){
long newId = 0;
Uri newUri = null;
newId = mDatabase.insert(UserInfoDbHelper.TABLE_USER_INFO,null,values);
newUri = Uri.parse(CONTENT + AUTHORIY + "/" + UserInfoDbHelper.TABLE_USER_INFO + "/" + newId);
if(newId > 0){
return newId;
}
throw new IllegalArgumentException("Failed to insert row into " + uri);
}
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] seletionArgs, String sortOrder){
Cursor cursor = null;
switch(uriMatcher.match(uri)){
case USER_INFOS:
cursor = mDatabase.query(UserInfoDbHelper.TABLE_USER_INFO,projection, selection, selectionArgs, null, null, sortOrder);
break;
case USER_INFO_ITEM:
String tel = uri.getPathsegments().get(1);
cursor = mDatabase.query(UserInfoDbHelper.TABLE_USER_INFO,projection, "tel_num = ?", new String[] {tel}, null, null, sortOrder);
break;
}
return cursor;
}
}
忽略数据库操作类UserInfoDbHelper代码
创建一个ProviderActivity类,在该Activity中存储、查询用户信息,主要方法:
//存储
private void saveUserInfoRecoder(){
ContentValues newRecord = new ContentValues();
newRecord.put(UserInfoDbHelper.DESC_COLUM, mUserEditText.getText().toString());
newRecord.put(UserInfoDbHelper.TEL_COLUM, mUserTelEditText.getText().toString());
newRecord.put(UserInfoDbHelper.COMP_ID_COLUM, mCompidEditText.getText().toString());
getContentResolver().insert(UserInfoProvider.USERINFO_URI, newRecord);
}
//通过电话查询信息
private void queryPostCode(){
Uri queryUri = Uri.parse("content://com.book.jtm.info/userinfo/123456");
Cursor cursor = getContentResolver.query(queryUri, null, null, null. null);
if(cursor.moveToFirst()){
Toast.makeText(this, "电话:" + cursor.getString(2), Toast.LENGTH_SHORT).show();
}
}
```
***