内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据的共享功能,是android的四大组件之一。内容提供器的用法一般有两种,一种是使用向右的内容提供器来读取和操作相应程序中的数据;另一种是创建自己的内容提供其给自己程序要共享出去的数据提供外部访问接口。
- 访问其他应用程序中的数据
- 通过Context中的getContentResolver()方法得到ContentResolver对象。Resolver意思是分解器,溶剂,把内容提供器提供的一块数据分析溶解,呵呵,我的理解。ContentResolver提供了一系列对数据进行CRUD操作。
- URI给内容提供器中的数据建立了唯一的标识符,需要作为传入CRUD的操作方法里。URI由两部分组成,”content://权限+路径”。权限是”包名.provide”。如果有子表,在provider后面加上”/table”。
Public static final Uri CONTENT_URI = Uri.parse(“content://com.WangWeiDa.MyContentProvider/users”); - 调用具体的CRUD操作方法就可以了。
Cursor cursor=null;
try {
cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
while(cursor.moveToNext()){
String name=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactList.add(name+"\n"+number);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(cursor!=null)
cursor.close();
}
- 创建自己的内容提供器
- 自定义一个provider类继承自ContentProvider。重写实现ContentProvider的所有方法(query、insert、update、delete、getType、onCreate);
- URI格式主要有两种,以路径结尾就表示期望访问该表的中的所有数据;以id结尾就表示期望访问该表中拥有相应id的数据。我们可以利用UriMatcher对象的addURI()和match()来匹配URI。
- 在getType()方法中返回Uri对象对应的MIME类型。MIME格式
1、以vnd开头
2、如果uri以路径结尾,则后接android.cursor.dir/;如果以id结尾,则后接android.cursor.item/。
3、最后接上vnd.< authority>.< path>。
“vnd.android.cursor.dir/vnd.com.example.databasetest.provider.book”; - android中四大组件都是要在AndroidManifest中注册,ContentProvider也不例外。需要在android:name属性中制定该自定义Provider类的全名,在android:authroities属性中指定该内容提供器权限。另外,我实践过这样写还是不能让外部程序访问到我们的ContentProvider,还需要添加android:exported=”true”才行,书上并没有加这一属性,不知为何、、、
<provider
android:authorities="com.example.tlh.databasetest.provider"
android:name="com.example.tlh.databasetest.MyProvider"
android:exported = "true">
</provider>
public class MyProvider extends ContentProvider {
private MyDatabaseHelper dbHelper;
public static final int TABLE1_DIR=0;
public static final int TABLE1_ITEM=1;
public static final int TABLE2_DIR=2;
public static final int TABLE2_ITEM=3;
public static final String AUTHORITY="com.example.tlh.databasetest.provider";
private static UriMatcher uriMatcher;
static {
uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY,"book",TABLE1_DIR);
uriMatcher.addURI(AUTHORITY,"book/#",TABLE1_ITEM);
uriMatcher.addURI(AUTHORITY,"category",TABLE2_DIR);
uriMatcher.addURI(AUTHORITY,"category/#",TABLE2_ITEM);
//当后面调用uriMatcher.match()时返回相应自定义常量。
}
@Override
public boolean onCreate() {//当且仅当有外部程序的ContentResolver尝试访问我们的程序数据时,初始化内容提供器,会调用此方法,若成功则return true.
//得到数据库帮助类实例便于以后调用数据库的CURD操作方法。
dbHelper=new MyDatabaseHelper(getContext(),"BookStore.db");
return true;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db=dbHelper.getWritableDatabase();
Cursor cursor=null;
switch (uriMatcher.match(uri)){
case TABLE1_DIR:
cursor=db.query("Book",projection,null,null,null,null,sortOrder);
break;
case TABLE1_ITEM:
String bookID=uri.getPathSegments().get(1);
cursor=db.query("Book",projection,"id=?",new String[]{"bookID"},null,null,sortOrder);
break;
case TABLE2_DIR:
cursor=db.query("Category",projection,null,null,null,null,sortOrder);
break;
case TABLE2_ITEM:
String categoryID=uri.getPathSegments().get(1);
cursor=db.query("Category",projection,"id=?",new String[]{"categoryID"},null,null,sortOrder);
break;
}
return cursor;
}
@Nullable
@Override
public String getType(Uri uri) {//调用ContentResolver的CURD方法传递过来的URI参数
switch (uriMatcher.match(uri)){
case TABLE1_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.book";
case TABLE1_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.book";
case TABLE2_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.category";
case TABLE2_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.category";
}
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db=dbHelper.getWritableDatabase();
Uri uriReturn=null;
switch(uriMatcher.match(uri)){
case TABLE1_DIR:
case TABLE1_ITEM:
Long bookID=db.insert("Book",null,values);
uriReturn=Uri.parse("content://"+AUTHORITY+"/Book/"+bookID);
break;
case TABLE2_DIR:
case TABLE2_ITEM:
Long categoryID=db.insert("Category",null,values);
uriReturn=Uri.parse("content://"+AUTHORITY+"/Category/"+categoryID);
break;
}
return uriReturn;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db=dbHelper.getWritableDatabase();
int deleteLine=0;
switch (uriMatcher.match(uri)){
case TABLE1_DIR:
deleteLine=db.delete("Book",selection,selectionArgs);
break;
case TABLE1_ITEM:
String bookID=uri.getPathSegments().get(1);
deleteLine=db.delete("Book","id=?",new String[]{bookID});
break;
case TABLE2_DIR:
deleteLine=db.delete("Category",selection,selectionArgs);
break;
case TABLE2_ITEM:
String categoryID=uri.getPathSegments().get(1);
deleteLine=db.delete("Category","id=?",new String[]{categoryID});
break;
}
return deleteLine;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db=dbHelper.getWritableDatabase();
int updateLine=0;
switch (uriMatcher.match(uri)){
case TABLE1_DIR:
updateLine=db.update("Book",values,selection,selectionArgs);
break;
case TABLE1_ITEM:
String bookID=uri.getPathSegments().get(1);
updateLine=db.delete("Book","id=?",new String[]{bookID});
break;
case TABLE2_DIR:
updateLine=db.delete("Category",selection,selectionArgs);
break;
case TABLE2_ITEM:
String categoryID=uri.getPathSegments().get(1);
updateLine=db.delete("Category","id=?",new String[]{categoryID});
break;
}
return updateLine;
}
}