內容提供器(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;
}
}