1. 程式人生 > >對ContentProvider的一點認識

對ContentProvider的一點認識

1、ContentProvider

  是android的四大元件之一,作用是對外共享資料,就是把自已應用程式裡的資料分享給其他應用程式,其他應用可以通過ContentProvider對你應用中的資料進行添刪改查。使用ContentProvider對外共享資料的好處是統一了資料的訪問方式。

  ContentProvider(內容提供者)用於提供資料的統一訪問格式,封裝底層的具體實現。對於資料的使用者來說,無需知曉資料的來源是資料庫、檔案,或者網路,只需簡單地使用ContentProvider提供的資料操作介面,也就是增(insert)、刪(delete)、改(update)、查(query)四個過程。

  contentprovider是一個抽象類,想要擁有自己的provider就必須繼承自這個類並重寫想要實現的方法,並且在manifest檔案裡進行註冊。如:
//這裡只想實現插入和查詢
 @Override
    public boolean onCreate() {
        smsDbHelper = SmsDbHelper.getInstance(getContext());
        return true;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        int
match = mUriMater.match(uri); switch (match) { case CODE_URI_SMS_ALL: break; case CODE_URI_SMS_ONE: long id = ContentUris.parseId(uri); selection = "_id = ?"; selectionArgs = new String[]{String.valueOf(id)}; break
; } db = smsDbHelper.getReadableDatabase(); Cursor cr = db.query(SendMsg.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); cr.setNotificationUri(getContext().getContentResolver(),URI_SMS_ALL); return cr; } @Nullable @Override public String getType(Uri uri) { return null; } @Nullable @Override public Uri insert(Uri uri, ContentValues values) { //如果匹配就會返回匹配碼 int match = mUriMater.match(uri); if (match != CODE_URI_SMS_ALL) throw new IllegalArgumentException("Wrong Uri" + uri); db = smsDbHelper.getWritableDatabase(); long rowId = db.insert(SendMsg.TABLE_NAME, null, values); if (rowId > 0) { //說明插入成功 notifyDataSetChange(); return ContentUris.withAppendedId(uri, rowId); } db.close(); return null; } private void notifyDataSetChange() { getContext().getContentResolver().notifyChange(URI_SMS_ALL, null); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } //在manifest檔案裡進行註冊 <provider android:authorities="com.example.lyw.sms.provider" android:name=".db.SmsProvider"/>

2.ContentReciver

 當外部應用需要對ContentProvider中的資料進行新增、刪除、修改和查詢操作時,可以使用ContentResolver 類來完成,要獲取ContentResolver 物件,可以使用Activity提供的getContentResolver()方法。 ContentResolver 類提供了與ContentProvider類相同簽名的四個方法:

public int delete(Uri uri, String selection, String[]

selectionArgs):該方法用於從ContentProvider刪除資料。

public int update(Uri uri, ContentValues values, String

selection, String[] selectionArgs):該方法用於更新ContentProvider中的資料。

public Cursor query(Uri uri, String[] projection, String selection,

String[] selectionArgs, String sortOrder):該方法用於從

ContentProvider中獲取資料。

3、Uri介紹
Uri代表了要操作的資料,Uri主要包含了兩部分資訊:1>需要操作的ContentProvider ,2>對ContentProvider中的什麼資料進行操作,會在程式中定義一下幾個欄位:

  public static final String AUTHORITY ="com.example.lyw.sms.provider";
    //對外查詢通過這個常量獲取
    public static final Uri URI_SMS_ALL = Uri.parse("content://" + AUTHORITY
            + "/sms");
            + 
private static final int CODE_URI_SMS_ALL = 0;
private static final int CODE_URI_SMS_ONE = 1;            

4、UriMatcher類使用介紹
因為Uri代表了要操作的資料,所以我們經常需要解析Uri,並從Uri中獲取資料。Android系統提供了兩個用於操作Uri的工具類,分別為UriMatcher和ContentUris 。UriMatcher類用於匹配Uri。

static {
        mUriMater = new UriMatcher(UriMatcher.NO_MATCH);
        //註冊路徑
        mUriMater.addURI(AUTHORITY, "sms", CODE_URI_SMS_ONE);
        mUriMater.addURI(AUTHORITY, "sms/#", CODE_URI_SMS_ALL);
    }
//匹配操作,如果匹配就會返回匹配碼
int match = mUriMater.match(uri);
        switch (match) {
            case CODE_URI_SMS_ALL:
                break;
            case CODE_URI_SMS_ONE:
                long id = ContentUris.parseId(uri);
                selection = "_id = ?";
                selectionArgs = new String[]{String.valueOf(id)};
                break;
        }

5.ContentUris類使用介紹

ContentUris類用於操作Uri路徑後面的ID部分( CODE_URI_SMS_ALL)。
withAppendedId(uri, id)用於為路徑加上ID部分: 
Uri uri =ContentUris.withAppendedId(uri, rowId);
//生成的URI為:com.example.lyw.sms.provider/sms/rowId;
parseId(uri)方法用於從路徑中獲取ID部分:
Uri uri = Uri.parse("content://com.example.lyw.sms.provider/sms/10")
long personid = ContentUris.parseId(uri);//personid為10

PS:當修改過provider裡的資料需要呼叫,
getContext().getContentResolver().notifyChange(URI_SMS_ALL, null)

具體應用等我整理號程式碼再上傳。