Content Providers
Objectives What are content providers? How to use a content provider in Android How to create your own content provider
Motivation Different ways to persist data, e.g., shared preferences, files, and SQLite but, accessible only by the package that created it Various persistent data from Android, e.g. Browser: browser bookmarks, borwser history, etc. CallLog: missed calls, call details, etc. Contacts: contact details MediaStore: audio, video, and images Setting: device's settings and preferences Q: How to share these data across packages and applications in a uniform way?
Content Provider: Sharing Data In Android Provides a consistent, uniform programming interface for sharing data Can be thought of as a data store, e.g., query, edit, add, and delete But unlike database, can be stored in many different ways Built-in vs user-defined
What API Or Facility? Naming a data store (URI) Querying a data store (query, Cursor) Table view of data store Inserting a new record (insert) Deleting an existing record (delete) Updating an existing record (update)
Querying Content Providers Use a query string in the form of URI content://<authority>/<data_path>/<id> <authority>: name of content provider, e.g., contacts for built-in Contacts content provider edu.utep.cs.cs4390.grade for user-defined <data_path>: specifies the kind of data requested, e.g., content://contacts/people <id>: specifies the specific record requested, e.g., content://contacts/people/2 <-- second record
Examples content://media/internal/images content://media/external/images content://call_log/calls content://browser/bookmarks
Querying Use the query method of ContentResolver Cursor query(URI uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) uri: content to retrieve projection: list of columns to return; null for all columns selection: filter declaring which rows to return, formatted as an SQL WHERE clause; null for all rows Use SQL operators: =, <>, >, <, >=, <=, between, like, in selectionArgs: args for "?s" in selection sortOrder: order of rows, formatted as an SQL ORDER BY clause e.g., “name asc” and “name desc”
Example Uri allContacts = Uri.parse("content://contacts/people"); Cursor c = getContentsResolver().query(allContacts, null, null, null, null); if (c.moveToFirst()) { do { String id = c.getString(c.getColumnIndex( ContactsContract.Contacts._ID)); String name = c.getString(c.getColumnIndex( ContactsContract.Contacts.DISPLAY_NAME)); ...use id and name .... } while (c.moveToNext()); } *Note that ContentsResolver.query is a synchronous call. *Can use a CursorAdapter class such as SimpleCursorAdapter to display results in an AdapterView such as ListView.
Cursor Class Interface providing random read-write access to the result set returned by a database query int getColumnCount(): total number of columns int getColumnIndex(String): zero-based index for the column name String getColumnName(int): column name for given index String[] getColumnNames() int getCount(): number of rows ... getBlob(int), getDouble(int), getInt(int), ... int getType(int) boolean isFirst(), isLast() boolean moveToFirst(), moveToLast(), moveToNext(), moveToPrevious(), moveToPosition(int) void registerContentObserver(ContentObserver) ...
CursorLoader: Querying Asynchronously in a new thread Uri allContacts = Uri.parse("content://contacts/people"); CursorLoader cursorLoader = new CursorLoader(this, allContacts, null, null, null, null); Cursor c = cursorLoader.loadInBackground(); if (c.moveToFirst()) { do { String id = c.getString(c.getColumnIndex( ContactsContract.Contacts._ID)); String name = c.getString(c.getColumnIndex( ContactsContract.Contacts.DISPLAY_NAME)); ...use id and name .... } while (c.moveToNext()); }
Predefined Query String Constants Uri allContacts = Uri.parse("content://contacts/people"); Uri allContacts = ContactsContract.CONTENT_URI Browser.BOOKMARKS_URI Browser.SEARCHES_URI CallLog.CONTENT_URI MediaStore.Images.Media.INTERNAL_CONTENT_URI MediaStore.Images.Media.EXTERNAL_CONTENT_URI Settings.CONTENT_URI Use withAppendedId method to retrieve a particular row, e.g., ContentUris.withAppendedId(ContactContract.Contacts.CONTENT_URI,1);
Inserting, Updating and Deleting Use the insert, update, and delete methods of ContentResolver Uri insert (Uri uri, ContentValues values) int update (Uri uri, ContentValues values, String where, String[] selArgs) int delete (Uri url, String where, String[] selectionArgs) *Refer to API documents of ContentValues and ContentResolver
Creating User-Defined Content Providers Extend the ContentProvider class and overwrite: getType(): returns MIME type of the data onCreate(): called when the provider is started query(): query and return a Cursor object insert(): insert a new record delete(): delete an existing record update(): update an existing record Need to register the content provider in the manifest file, e.g., <provider android:name="BooksProvider“ android:authority="edu.utep.cs.cs4390.provider.Books" />
In-Class (Pair) Write an app to find contacts matching a given (partial) name Display the name and phone number of matching contacts Name: Jason_______ Found: … Find