ContentProvider


ContentProvider在Android中的作用是對外共享數(shù)據(jù),也就是說可以通過ContentProvider把應用中的數(shù)據(jù)共享給其他應用訪問,其他應用可以通過ContentProvider對應用中數(shù)據(jù)進行添、刪、改、查。使用ContentProvider對外共享數(shù)據(jù)的好處是,統(tǒng)一了數(shù)據(jù)的訪問方式,它實際上是對SQLiteOpenHelper的進一步封裝,通過Uri映射來判斷選擇需要操作數(shù)據(jù)庫中的哪個表,并且進行增刪改查處理。

  • ContentProvider為存儲和讀取數(shù)據(jù)提供了統(tǒng)一的接口

  • 使用ContentProvider,應用程序可以實現(xiàn)數(shù)據(jù)共享

  • android內(nèi)置的許多數(shù)據(jù)都是使用ContentProvider形式,供開發(fā)者調(diào)用的(如視頻,音頻,圖片,通訊錄等)。

Uri格式:

Uri格式.png

ContentProvider的schema已經(jīng)由Android固定設置為content://。Authority用于唯一標識這個ContentProvider,外部調(diào)用者可以根據(jù)這個標識來找到它。path是要操作的數(shù)據(jù)庫表。id查詢關鍵字是可選字段,指定特定的某一數(shù)據(jù)項。

Uri uri = Uri.parse("content://contacts/people");

Anroid系統(tǒng)根據(jù)Uri來定位注冊到系統(tǒng)的ContentProvider中,找到ContentProvider之后會通過ContentResolver來操作。

  • UriMatcher類
    因為Uri代表了要操作的數(shù)據(jù),所以我們經(jīng)常需要解析Uri,并從Uri中獲取數(shù)據(jù)。Android系統(tǒng)提供了兩個用于操作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所返回的數(shù)據(jù)類型定義、數(shù)據(jù)集合
    public static final String  CONTENT_TYPE = "vnd.android.cursor.dir/vnd." +AUTHORIY;
    //單項數(shù)據(jù)
    public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd." + AUTHORIY;
    //數(shù)據(jù)集合操作時的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;
    }
}

忽略數(shù)據(jù)庫操作類UserInfoDbHelper代碼
創(chuàng)建一個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();
    }
}
```
***




最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容