1. 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferencesAPI读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。
当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:
publicclass PersonContentProvider extends ContentProvider{
public boolean onCreate()
public Uri insert(Uri uri, ContentValuesvalues)
public int delete(Uri uri, String selection,String[] selectionArgs)
public int update(Uri uri, ContentValuesvalues, String selection, String[] selectionArgs)
public Cursor query(Uri uri, String[]projection, String selection, String[] selectionArgs, String sortOrder)
public String getType(Uri uri)}
第二步需要在AndroidManifest.xml使用<provider>对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider, ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:
<manifest.... >
<applicationandroid:icon="@drawable/icon" android:label="@string/app_name">
<providerandroid:name=".PersonContentProvider"android:authorities="cn.itcast.provider.personprovider"/>
</application>
</manifest>
注意:一旦应用继承了ContentProvider类,后面我们就会把这个应用称为ContentProvider(内容提供者)。
2. 部分代码如下:
packagecn.itcast.action;
importcn.itcast.db.utils.DatabaseHelper;
importandroid.content.ContentProvider;
importandroid.content.ContentUris;
importandroid.content.ContentValues;
importandroid.content.UriMatcher;
importandroid.database.Cursor;
importandroid.database.SQLException;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.net.Uri;
importandroid.text.TextUtils;
publicclass PersonContentProvider extends ContentProvider{
//数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头
public static final String PERSONS_TYPE ="vnd.android.cursor.dir/person";
//单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头
public static final String PERSONS_ITEM_TYPE= "vnd.android.cursor.item/person";
public static final String AUTHORITY ="cn.itcast.provider.personprovider";//主机名
/*自定义匹配码*/
public static final int PERSONS = 1;
/*自定义匹配码*/
public static final int PERSON = 2;
public static final Uri PERSONS_URI =Uri.parse("content://" + AUTHORITY + "/person");
/*这里UriMatcher是用来匹配Uri的类,使用match()方法匹配路径时返回匹配码*/
private static final UriMatcher sMatcher;
static {
sMatcher = newUriMatcher(UriMatcher.NO_MATCH);//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
//如果match()方法匹配content://cn.itcast.provider.personprovider/person路径,返回匹配码为PERSONS
sMatcher.addURI(AUTHORITY,"person", PERSONS);
//如果match()方法匹配content://cn.itcast.provider.personprovider/person/230路径,返回匹配码为PERSON
sMatcher.addURI(AUTHORITY,"person/#", PERSON);
}
private DatabaseHelper databaseHelper;
@Override
public boolean onCreate() {
databaseHelper = newDatabaseHelper(this.getContext());
return true;
}
@Override
public Uri insert(Uri uri, ContentValuesvalues) {
SQLiteDatabase db =databaseHelper.getWritableDatabase();
if (sMatcher.match(uri) != PERSONS) {
throw newIllegalArgumentException("Unknown URI " + uri);
}
long rowId = db.insert("person","personid", values);//往person表添加一条记录
db.close();
if(rowId>0){//如果添加成功
//ContentUris是contentURI的一个辅助类。下面方法负责把rowId和PERSONS_URI连接成一个新的Uri,
//生成的Uri如:content://cn.itcast.provider.personprovider/person/10
returnContentUris.withAppendedId(PERSONS_URI, rowId);
}
throw new SQLException("Failed toinsert row into " + uri);//抛出添加失败信息
}
@Override
public int delete(Uri uri, String selection,String[] selectionArgs) {
SQLiteDatabase db =databaseHelper.getWritableDatabase();
int count = 0;
switch (sMatcher.match(uri)) {
case PERSONS:
count = db.delete("person",selection, selectionArgs);
break;
case PERSON:
//下面的方法用于从URI中解析出id,对这样的路径content://cn.itcast.provider.personprovider/person/10进行解析,返回值为10
long personid =ContentUris.parseId(uri);
String where = "personid="+personid;//删除指定id的记录
where +=!TextUtils.isEmpty(selection) ? " and ("+ selection +")" :"";//把其它条件附加上
count = db.delete("person",where, selectionArgs);
break;
default:
throw new IllegalArgumentException("UnknownURI " + uri);
}
db.close();
return count;
}
@Override
public int update(Uri uri, ContentValuesvalues, String selection, String[] selectionArgs) {
SQLiteDatabase db =databaseHelper.getWritableDatabase();
int count = 0;
switch (sMatcher.match(uri)) {
case PERSONS:
count = db.update("person",values, selection, selectionArgs);
break;
case PERSON:
long personid =ContentUris.parseId(uri);
String where = "personid="+personid;//删除指定id的记录
where += !TextUtils.isEmpty(selection)? " and ("+ selection +")" : "";//把其它条件附加上
count = db.update("person",values, where, selectionArgs);
break;
default:
throw newIllegalArgumentException("Unknown URI " + uri);
}
db.close();
return count;
}
@Override
public Cursor query(Uri uri, String[]projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db =databaseHelper.getReadableDatabase();
Cursor cursor;
switch (sMatcher.match(uri)) {
case PERSONS:
cursor = db.query("person",projection, selection, selectionArgs, null, null, sortOrder);
break;
case PERSON:
long personid =ContentUris.parseId(uri);
String where = "personid="+personid;//删除指定id的记录
where +=!TextUtils.isEmpty(selection) ? " and ("+ selection +")" :"";//把其它条件附加上
cursor = db.query("person",projection, where, selectionArgs, null, null, sortOrder);
break;
default:
throw newIllegalArgumentException("Unknown URI " + uri);
}
cursor.getCount();//在数据库关闭前获取所有数据
db.close();
return cursor;
}
@Override
public String getType(Uri uri) {
switch (sMatcher.match(uri)) {
case PERSONS:
return PERSONS_TYPE;
case PERSON:
return PERSONS_ITEM_TYPE;
default:
throw new IllegalArgumentException("UnknownURI " + uri);
}
}
}