ContentProvider为存储和获取数据提供了统一的接口。ContentProvide对数据进行封装,不用关心数据存储的细节,虽然使用其他方法也可以对外共享数据,但数据访问方式
使用ContentProvider可以在不同的应用程序之间共享数据。Android为常见的一些数据提供了默认的ContentProvider(包括音频、视频、图片和通讯录等)。ContentProvider所提供的函数:query(),insert(),update(),delete(),getType(),onCreate()等。
For example, to get a list of the words and their locales from the User Dictionary Provider, you callContentResolver.query()
. Thequery()
method calls the ContentProvider.query()
method defined by the User Dictionary Provider. The following lines of code show a ContentResolver.query()
call:
// Queries the user dictionary and returns results
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder); // The sort order for the returned rows
Table 2 shows how the arguments to query(Uri,projection,selection,selectionArgs,sortOrder)
match an SQL SELECT statement:
在Content Provider中使用的查询字符串有别于标准的SQL查询。
Table 2: Query() compared to SQL query.
URI:
A content URI is a URI that identifies data in a provider. Content URIs include the symbolic name of the entire provider (itsauthority) and a name that points to a table (apath). When you call a client method to access a table in a provider, the content URI for the table is one of the arguments.
In the preceding lines of code, the constant CONTENT_URI
contains the content URI of the user dictionary's "words" table. TheContentResolver
object parses out the URI's authority, and uses it to "resolve" the provider by comparing the authority to a system table of known providers. The ContentResolver
can then dispatch the query arguments to the correct provider.
The ContentProvider
uses the path part of the content URI to choose the table to access. A provider usually has apath for each table it exposes.
In the previous lines of code, the full URI for the "words" table is:
content://user_dictionary/words
where the user_dictionary
string is the provider's authority, and words
string is the table's path. The string content://
(thescheme) is always present, and identifies this as a content URI.
Many providers allow you to access a single row in a table by appending an ID value to the end of the URI. For example, to retrieve a row whose_ID
is 4
from user dictionary, you can use this content URI:
Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
Inserting, Updating, and Deleting Data
Inserting data
To insert data into a provider, you call the ContentResolver.insert()
method. This method inserts a new row into the provider and returns a content URI for that row. This snippet shows how to insert a new word into the User Dictionary Provider:
// Defines a new Uri object that receives the result of the insertion
Uri mNewUri;
...
// Defines an object to contain the new values to insert
ContentValues mNewValues = new ContentValues();
/* * Sets the values of each column and inserts the word. The arguments to the "put"
* method are "column name" and "value"
*/
mNewValues.put(UserDictionary.Words.APP_ID, "example.user");
mNewValues.put(UserDictionary.Words.LOCALE, "en_US");
mNewValues.put(UserDictionary.Words.WORD, "insert");
mNewValues.put(UserDictionary.Words.FREQUENCY, "100");
mNewUri = getContentResolver().insert(
UserDictionary.Word.CONTENT_URI, // the user dictionary content URI
mNewValues // the values to insert
);
Updating data
To update a row, you use a ContentValues
object with the updated values just as you do with an insertion, and selection criteria just as you do with a query. The client method you use is ContentResolver.update()
. You only need to add values to the ContentValues
object for columns you're updating. If you want to clear the contents of a column, set the value tonull
.
The following snippet changes all the rows whose locale has the language "en" to a have a locale ofnull
. The return value is the number of rows that were updated:
// Defines an object to contain the updated values
ContentValues mUpdateValues = new ContentValues();
// Defines selection criteria for the rows you want to update
String mSelectionClause = UserDictionary.Words.LOCALE + "LIKE ?";
String[] mSelectionArgs = {"en_%"};
// Defines a variable to contain the number of updated rows
int mRowsUpdated = 0;
...
/* * Sets the updated value and updates the selected words. */
mUpdateValues.putNull(UserDictionary.Words.LOCALE);
mRowsUpdated = getContentResolver().update(
UserDictionary.Words.CONTENT_URI, // the user dictionary content URI
mUpdateValues // the columns to update
mSelectionClause // the column to select on
mSelectionArgs // the value to compare to
);
The data for the new row goes into a single ContentValues
object, which is similar in form to a one-row cursor. The columns in this object don't need to have the same data type, and if you don't want to specify a value at all, you can set a column tonull
usingContentValues.putNull()
.
The snippet doesn't add the _ID
column, because this column is maintained automatically. The provider assigns a unique value of_ID
to every row that is added. Providers usually use this value as the table's primary key.
The content URI returned in newUri
identifies the newly-added row, with the following format:
content://user_dictionary/words/<id_value>
The <id_value>
is the contents of _ID
for the new row. Most providers can detect this form of content URI automatically and then perform the requested operation on that particular row.
To get the value of _ID
from the returned Uri
, call ContentUris.parseId()
.
Deleting data
Deleting rows is similar to retrieving row data: you specify selection criteria for the rows you want to delete and the client method returns the number of deleted rows. The following snippet deletes rows whose appid matches "user". The method returns the number of deleted rows.
// Defines selection criteria for the rows you want to delete
String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
String[] mSelectionArgs = {"user"};
// Defines a variable to contain the number of rows deleted
int mRowsDeleted = 0;
...
// Deletes the words that match the selection criteria
mRowsDeleted = getContentResolver().delete(
UserDictionary.Words.CONTENT_URI, // the user dictionary content URI
mSelectionClause // the column to select on
mSelectionArgs // the value to compare to
);