編寫完整的Content provider樣本

來源:互聯網
上載者:User
文章目錄
  • 日誌引用

在在Content provider實現中使用SQLiteOpenHelper中實現的是特別簡單的content provider,方法實現不全。下面給出一個實現比較全面的Content provider,當然也是很簡單的。

使用UriMatcher

UriMatcher可以協助開發人員識別Uri。比如:

content://com.easymorse.cp.mycp/emperors

表示擷取朝代列表集合。而:

content://com.easymorse.cp.mycp/emperors/1

表示其中的_ID值為1的一個特定的記錄。

如果自己寫分析Uri的代碼,比較繁瑣和重複。android提供了方便的工具類UriMatcher。

 

首先定義兩個常量,針對集合與特定的單條記錄:

private static final int ITEMS = 1;

private static final int ITEM = 2;

另外要建立UriMatcher執行個體:

private static UriMatcher uriMatcher;

static {
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(PROVIDER_NAME, TABLE_EMPERORS, ITEMS);
    uriMatcher.addURI(PROVIDER_NAME, TABLE_EMPERORS + "/#", ITEM);
}

靜態即可。然後在靜態初始化塊中把ITEMS和ITEM加進去。這裡指定了ITEMS的URI模式是:

content://com.easymorse.cp.mycp/emperors

而ITEM是:

content://com.easymorse.cp.mycp/emperors/#

#號表示一個id值。

UriMatcher如何使用呢?

uriMatcher.match(uri)

如果一個content://com.easymorse.cp.mycp/emperors Uri,該方法將返回1,也就是常量ITEMS的值,以此類推。

編寫一個getType方法:

@Override
public String getType(Uri uri) {
    switch (uriMatcher.match(uri)) {
    case ITEMS:
        return "vnd.android.cursor.dir/vnd.easymorse.mycp";
    case ITEM:
        return "vnd.android.cursor.item/vnd.easymorse.mycp";
    default:
        throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
}

這個方法在本例中並未起到作用,如果作為intent並使用data(Mimetype)就會用到這個方法。可見總結一下Intent概念的data測試部分。

編寫查詢方法

查詢方法的代碼:

@Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        switch (uriMatcher.match(uri)) {
        case ITEMS:
            return database.query(TABLE_EMPERORS, projection, selection,
                    selectionArgs, null, null, sortOrder);
        case ITEM:
            return database.query(TABLE_EMPERORS, projection, _ID + "="
                    + uri.getPathSegments().get(1), selectionArgs, null, null,
                    null);
        default:
            throw new IllegalArgumentException("unknown uri: " + uri);
        }
    }

 

這裡有兩種可能,通過條件查詢,或者通過id查詢,前者走ITEMS,後者走ITEM,都是通過Uri判斷的,藉助UriMatcher。這裡:

uri.getPathSegments().get(1),

將取到id號。如果get(0),將取到path的第一個值emperors

使用該Content provider的代碼:

private String getContentProviderValues() {
    StringBuilder builder = new StringBuilder();

    // 查名稱和朝代,朝代=明,而且按照登基時間倒排序
    Cursor cursor = managedQuery(MyContentProvider.CONTENT_URI,
            new String[] { MyContentProvider.NAME,
                    MyContentProvider.DYNASTY }, MyContentProvider.DYNASTY
                    + "=?", new String[] { "明" }, " start_year desc");

    // 查全部記錄
    // Cursor cursor = managedQuery(MyContentProvider.CONTENT_URI, null,
    // null,
    // null, null);

    // 根據id定位記錄(0..1)
    // Cursor cursor = managedQuery(ContentUris.withAppendedId(
    // MyContentProvider.CONTENT_URI, 1),
    // new String[] { MyContentProvider.NAME }, null, null, null);

    while (cursor.moveToNext()) {
        builder
                .append(
                        cursor.getString(cursor
                                .getColumnIndex(MyContentProvider.NAME)))
                .append(" | ")
                // .append(
                // cursor
                // .getString(cursor
                // .getColumnIndex(MyContentProvider.START_YEAR)))
                // .append(" | ")
                .append(
                        cursor.getString(cursor
                                .getColumnIndex(MyContentProvider.DYNASTY)))
                .append("/n");
    }

 

可以有多種使用方式,本例中屏蔽部分,是其他使用方式。

編寫編輯方法

insert()、update()和delete()都屬於編輯記錄的功能。拿update舉例,因為比較複雜一點:

@Override
public int update(Uri uri, ContentValues contentValues, String selection,
        String[] selectionArgs) {
    switch (uriMatcher.match(uri)) {
    case ITEM:
        return database.update(TABLE_EMPERORS, contentValues,
                _ID + "=" + uri.getPathSegments().get(1) + " and ("
                        + selection + ")", selectionArgs);
    case ITEMS:
        return database.update(TABLE_EMPERORS, contentValues, selection,
                selectionArgs);
    default:
        throw new IllegalArgumentException("unknown uri: " + uri);
    }
}

這裡複雜的地方是如果根據id做修改,比如還有其他附加條件,需要拼接where子句字串。後面的and要帶括弧,否則邏輯可能不同。

使用這個Content provider的做update的樣本:

ContentValues values = new ContentValues();
values.put(MyContentProvider.NAME, "朱重八");
getContentResolver().update(MyContentProvider.CONTENT_URI, values,
        MyContentProvider.NAME + "=?", new String[] { "朱元璋" });

修改表中是朱元璋的,改為他的小名,朱重八。

如果是delete和insert操作,情況是類似的。

完整樣本見:

http://easymorse.googlecode.com/svn/tags/content.provider-0.3.0/

日誌引用
  • 總結Content Provider的使用
  • 在content provider中使用位元據

 

 

相關日誌
  • 編寫最簡單的Content Provider (0)
  • 總結Content Provider的使用 (0)
  • 在其他應用中使用自訂的Content Provider (0)
  • 在Content provider實現中使用SQLiteOpenHelper (0)
  • 在content provider中使用大型二進位檔案 (0)

轉:http://marshal.easymorse.com/archives/2991

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.