Content Providers是Android平臺中重要的元件之一,它提供了一套標準的介面用來實現資料的增刪改查,可以使各個應用程式之間實現資料共享。一方面,我們可以獲得系統內部的如音訊、視訊、影像和聯絡人等Content Providers,還可以定義自己開發應用程式的CP,提供其他應用程式訪問自身資料的介面。

1. 對Content Providers的操作

Content Providers把它的資料作為資料庫模型上的單一資料表提供出來,在資料表中,每一行是一條記錄,每一列代表某一特定型別的值。下表是聯絡人資訊的資料模型。

 
_ID NUMBER NUMBER_KEY LABEL NAME TYPE
13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK
44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME
45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE
53 201.555.4433 201 555 4433 Love Nest Rex Cars TYPE_HOME

    每一個Content Providers都會會對外提供一個URI作為其唯一標識,在與其他程式互動的過程中都會使用到這個常量。URI有三部分組成:

    “content://”

    資料的路徑

    ID(可選) 一個ID代表一條記錄,ID為空代表表中的全部資料。

    在進行對Content Providers的操作中,使用到一個唯一的ContentResolver介面來使用某個具體的Content Provisers物件。其初始化程式碼如下:

ContentResolver cr=getContentResolver();

    ContentResolver中定義了對Content Providers中資料操作的方法。主要包括如下幾個:

    a. 查詢資料

    方法一:使用的ContentResolver.query()方法。在SDK文件中,有如下說明: 

public final Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

Since: API Level 1

 

Query the given URI, returning a Cursor over the result set.

For best performance, the caller should follow these guidelines:

  • Provide an explicit projection, to prevent reading data from storage that aren`t going to be used.

  • Use question mark parameter markers such as `phone=?` instead of explicit values in the selection parameter, so that queries that differ only by those values will be recognized as the same for caching purposes.

 Parameters

uri

The URI, using the content:// scheme, for the content to retrieve.

projection

A list of which columns to return. Passing null will return all columns, which is inefficient.

selection

A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given URI.

selectionArgs

You may include ?s in selection, which will be replaced by the values from selectionArgs, in the order that they appear in the selection. The values will be bound as Strings.

sortOrder

How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.

Returns

  • A Cursor object, which is positioned before the first entry, or null

    方法二:使用Activity.managedQuery()方法。需要注意的是它包含了Activity的生命週期,當Activity被暫停後,如果需要重新使用方法返回的Cursor物件,就需要通過Activity.startManagingCursor()方法重新啟動。在SDK文件中的說明如下:

public final Cursor managedQuery (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

Since: API Level 1

Wrapper around query(android.net.Uri, String[], String, String[], String) that gives the resulting Cursor to call startManagingCursor(Cursor) so that the activity will manage its lifecycle for you.

Parameters

uri

The URI of the content provider to query.

projection

List of columns to return.

selection

SQL WHERE clause.

selectionArgs

The arguments to selection, if any ?s are pesent

sortOrder

SQL ORDER BY clause.

Returns

  • The Cursor that was returned by query(). 

    b. 新增和修改資料

    ContentResolver中定義了增加和修改資料的方法,使用起來非常方便,與資料庫的操作類似。程式碼如下:

 
 

  1. //1. 增加資料  
  2. //獲得ContentValues物件,並構造其中的資料  
  3. ContentValues values = new ContentValues();  
  4. values.put(NotePad.Notes.TITLE, "title1");  
  5. values.put(NotePad.Notes.NOTE, "NOTENOTE1");  
  6. //將資料新增到URI為NotePad.Notes.CONTENT_URI的資料模型中  
  7. getContentResolver().insert(NotePad.Notes.CONTENT_URI, values);  
  8.  
  9. //2. 修改資料  
  10. //獲得ContentValues物件,並構造其中的資料  
  11. ContentValues values = new ContentValues();  
  12. values.put(NotePad.Notes.TITLE, "title1");  
  13. values.put(NotePad.Notes.NOTE, "NOTENOTE1");
  14. //定義加入了需要被修改記錄ID的URI 
  15. URI uri=contentUris.withAppendedID(NotePad.Notes.CONTENT_URI,id);  
  16. //修改URI為NotePad.Notes.CONTENT_URI的資料模型中ID為id的記錄,將其值修改為ContentValue中的值  
  17. getContentResolver().insert(uri, values);  
  18.      

2. 自定義Content Provisers

    可以通過定義一個繼承於ContentProvider的類自定義自己開發應用程式的CP。通過重寫基類中的方法,可以提供給外部操作的介面。至於在方法內部如何組織和儲存資料,則由開發者自定。例如,既可以使用資料庫儲存,也可使用XML。不管採用哪種機制,外部使用者關注的僅僅是可操作的介面。

    在實際的開發中,大多數情況使用的是系統內的CP。由於很少情況自定義CP,而且模式相對較為固定,所以我們在使用時可以參照現有資料或API DEMO即可。