ContentProvider和ContentResolver的使用


ContentProvider

ContentProvider 在android中的作用是對外共享數據,也就是說你可以通過ContentProvider把應用中的數據共享給其他應用訪問,其他應用可以通過ContentProvider 對你應用中的數據進行添刪改查。
ContentProvider的就是自定義增刪改查接口並暴露出去,讓別的應用訪問自己的數據。ContentResolver就是按照一定規則訪問內容提供者的數據。

ContentProvider對外共享數據步驟:

步驟

1. 定義一個類 繼承 ContentProvider
2. 定義匹配規則 uri
3. 通過靜態代碼塊添加匹配規則 
4.在manifest.xml中配置contentProvider.  

 

Uri介紹

uri代表了要操作的數據

上面我們提到了Android提供內容的叫Provider,那么在Android中怎么區分各個Provider?

Uri作為唯一的標識來標識這個Provider。

ContentProvider的scheme為:content://
Authority 用於唯一標識這個ContentProvider,外部調用者可以根據這個標識來找到它。
路徑(path)可以用來表示我們要操作的數據,路徑的構建應根據業務而定,如下:
要操作file表中id為10的記錄,可以構建這樣的路徑:/file/10
要操作file表中id為10的記錄的name字段, file/10/name
要操作file表中的所有記錄,可以構建這樣的路徑:/file

當然要操作的數據可以是數據庫,也可以是文件、xml或網絡等其他存儲方式。

代碼示例

public class FileProvider  extends ContentProvider {

    private Context mContext;
    private static final int QUEYSUCESS = 0;
    private static final int INSERTSUCESS = 1;
    //UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼
    private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    private SQLiteDatabase mDb;
    private String mTableName = DbOpenHelper.STUDENT_TABLE_NAME;
    static{
        //注冊所有要匹配的uri
        mUriMatcher.addURI("com.itcast.contentp.FileProvider", "query", QUEYSUCESS);
        mUriMatcher.addURI("com.itcast.contentp.FileProvider", "insert", INSERTSUCESS);
    }

    //該方法在其它應用第一次訪問它時才會被創建
    @Override
    public boolean onCreate() {        
        mContext = getContext();
        mDb = new DbOpenHelper(mContext).getWritableDatabase();
        return false;
    }

    /**
    *public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, String sortOrder)
    *projection : 這個參數告訴查詢要返回的列(Column)即需要的字段,比如Contacts Provider提供了聯系人的ID和聯系人的NAME等內容.
    *selection :查詢where字句
    *selectionArgs : 查詢條件屬性值
    *sortOrder :結果排序
    */
    @Override
    public Cursor query(Uri uri, String[] arg1, String arg2, String[] arg3,String arg4) {
        if (mUriMatcher.match(uri)== QUEYSUCESS ) {//uri匹配后進行下面的操作
            Cursor cursor = mDb.query(tableName, arg1, arg2, arg3, null, null, null);
            getContext().getContentResolver().notifyChange(uri, null);
            return cursor;
        }else{
            throw new IllegalArgumentException("match fail");
        }
}
這里只給出部分代碼。。。。。。


ContentResolver

使用ContentResolver調用ContentProvider提供的接口,對ContentProvider中的數據進行添加、刪除、修改和查詢操作時。

可以使用Activity提供的getContentResolver()方法來獲取ContentResolver對象。 ContentResolver 類提供了與ContentProvider類相同簽名的四個方法:

  • public Uri insert(Uri uri, ContentValues values)
  • public int delete(Uri uri, String selection, String[] selectionArgs)。
  • public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
  • public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)


1.對ContentProvider中的數據進行增刪改查

直接看代碼:

//uriQuery必須與要查詢的ContentProvider中的要操作數據的uri保持一致(btw 這里只給了查詢好插入的例子)

ContentValues values = new ContentValues();
Cursor cursor = getContentResolver().query(uriQuery, null, null, null, null);
int count = cursor.getCount(); //獲取到一共有多少行
int contact_id = count + 1;

ContentValues nameValues = new ContentValues();
nameValues.put("name", name);
nameValues.put("mime_type", "vnd.android.cursor.item/name");
nameValues.put("contact_id", contact_id);
getContentResolver().insert(uriInsert, nameValues);

 

2.監聽ContentProvider中數據的變化

在ContentProvider 發生數據變化時調用getContentResolver().notifyChange(uri, null)來通知注冊在此URI上的訪問者。

當數據放生變化時會調用ContentObserver的onChange()來進行一系列的后續操作~~~

如下: 

 

public class MainActivity extends Activity {

    private Uri uri;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        //注冊
        uri = Uri.parse("content://com.example.contentp.AccountProvider"); 
        getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler())) 
}
}

//監聽到變化后調用onChange()來執行一系列操作

private class MyObserver extends ContentObserver {
    Uri uri = Uri.parse("content://com.example.contentp.AccountProvider"); 

public MyObserver(Handler handler) {

super(handler);
}
@Override
public void onChange(boolean selfChange) {
Cursor cursor = getContentResolver().query(uri, new String[]{"file","mime_type","date"}, null, null, null);
while(cursor.moveToNext()){
//執行一些操作
}
}
}

 

ContentProviderClient 

與ContentResolver一樣都是用來對ContentProvider中的數據進行添加、刪除、修改和查詢操作的

通過調用 getContentResolver().acquireContentProviderClient(authority) 方法獲取 ContentProviderClient對象。

用法跟ContentResolver相似,不同點是ContentProviderClient 對象必須在結束使用后,調用ContentProviderClient.release()來釋放。這會是系統釋放對應的ContentProvider對象。

對於相同ContentProvider 的多次調用,推薦使用ContentProviderClient。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM