1 简介
本篇将对内容提供者做个介绍,并做个简单的实践。
内容提供者简单来说就是就是实现不同应用之间数据共享的一种方式。
通常情况下,android应用只需要使用自己应用的沙盒中管理数据,实现数据的CRUD操作即可;然而,有很多种情况,我们需要共享数据,比如获取手机联系人,又或者自己开发的两款应用需要访问共有的用户系统。
2 数据共享方式
这里总结android开发中数据共享的方式:
- SharePreference
两个应用直接均需使用同一套API进行访问,且数据量较小,局限性较强,CRUD操作效率较低。 - ContentProvider
ContentProvider对数据的共享提供了一套标准的机制,无论存储者使用何种方式存储数据,调用者都无需关心,相对来说更加方便。由于ContentResolver无需关心存储技术的实现和细节,所以无论数据量的大小,都可以采用该方案实现。 - sharedUserId
两个应用直接均需使用同一套API进行访问,且数据量较小,局限性较强,CRUD操作效率较低。还需要求应用打包签名一致等条件,单纯为了数据存储,代价有点高了。 - 文件读写
两个应用直接均需使用同一套API进行访问,且数据量较小,CRUD操作效率较低。
3 实践
ContentProvider端主要代码
public class PersonContentProvider extends ContentProvider {
private final String TAG = "hh";
private PersonDao personDao = null;
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSON = 1;
private static final int PERSONS = 2;
static {
URI_MATCHER.addURI("com.example.studentProvider","person",PERSONS);
URI_MATCHER.addURI("com.example.studentProvider",
"person/#", PERSON);
}
@Override
public Bundle call(String method, String arg, Bundle extras) {
Log.i(TAG, "--->>" + method);
Bundle bundle = new Bundle();
bundle.putString("returnCall", "call被执行了");
return bundle;
}
@Override
public boolean onCreate() {
personDao = new PersonDao(getContext());
Log.i(TAG,"onCreate");
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
Cursor cursor = null;
int flag = URI_MATCHER.match(uri);
if(flag == PERSON)
{
long id = ContentUris.parseId(uri);
Log.i(TAG,"查询,id=" + id);
String where_value = " id = ?";
String[] args = {String.valueOf(id)};
cursor = personDao.queryPersons(where_value,args);
}else
{
cursor = personDao.queryPersons(selection,selectionArgs);
}
return cursor;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
int flag = URI_MATCHER.match(uri);
switch (flag)
{
case PERSON:
return "vnd.android.cursor.item/person";
case PERSONS:
return "vnd.android.cursor.dir/persons";
}
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
Uri resultUri = null;
int flag = URI_MATCHER.match(uri);
if(flag == PERSONS)
{
long id = personDao.insertPerson(values);
resultUri = ContentUris.withAppendedId(uri,id);
Log.i(TAG,"插入成功,id="+id);
Log.i(TAG,"插入成功,resultUri="+resultUri.toString());
}
return resultUri;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
int count = -1;
int flag = URI_MATCHER.match(uri);
if(flag == PERSON)
{
long id = ContentUris.parseId(uri);
String where_value = "id = ?";
String[] args = {String.valueOf(id)};
count = personDao.deletePerson(where_value,args);
}else{
count = personDao.deletePerson(selection,selectionArgs);
}
Log.i(TAG,"删除成功,count = " + count);
return count;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
int count = -1;
int flag = URI_MATCHER.match(uri);
if(flag == PERSON)
{
long id = ContentUris.parseId(uri);
String where_value = "id = ?";
String[] args = {String.valueOf(id)};
count = personDao.updatePerson(values,where_value,args);
}else
{
count = personDao.updatePerson(values,selection,selectionArgs);
}
Log.i(TAG,"更新成功,count=" + count);
return count;
}
}
<provider
android:exported="true"
android:authorities="com.example.studentProvider"
android:name="com.example.wanghaoqiang.contentproviderdemo.PersonContentProvider"></provider>
这里需要注意的是xml中的android:authorities需要和URI_MATCHER.addURI(“com.example.studentProvider”,“person”,PERSONS);加入的authorities一致,同时android:exported="true"记住一定要设置,不然其他进程无法访问。
ContentResolver端的主要代码
ContentResolver contentResolver = getApplicationContext().getContentResolver();
Uri uri = Uri.parse("content://com.example.studentProvider/person");
ContentValues values = new ContentValues();
values.put("name", "生命贰号");
values.put("address", "湖北");
contentResolver.insert(uri,values);