Android Content Providers

Download as pdf or txt
Download as pdf or txt
You are on page 1of 31

Android Content

Providers
Using Media Data

Media Music
Manager Player
playlists, songs, artists…

2
Using Media Data

Media Music
Manager Player

Content Inter-process communication
 Content


Provider (IPC) channel Resolver

3
Client-side: content resolver

• Implemented
Media by Android:
 Music
getContentResolver()
Manager Player

• API: “CRUD” — similar to database


• create (insert)
• retrive (query)
• update Inter-process communication

Content Content
Provider
• delete (IPC) channel Resolver

http://developer.android.com/reference/android/content/
ContentResolver.html
4
Service-side: content provider
a few functions query

framework
Android’s
implemented by the
content provider’s insert
owner (Media) update

Media delete Music


Manager Player
common code:
Use any handling IPC
requests, data
storage. Don’t
serialization/
have to use a
Content Inter-process communication
deserialization
database
Content
Provider (IPC) channel Resolver

5
Built-in content providers
• Contacts

• Media

• Calendar

• User Dictionary

• …

6
Simple example:

user dictionary (built-in)
• Stores the spellings of non-standard words that the
user wants to keepI

• Backed by a database table

word app id frequency locale _ID


mapreduce user1 100 en_US 1
precompiler user14 200 fr_FR 2
applet user2 225 fr_CA 3
const user1 255 pt_BR 4
int user5 100 en_UK 5

7
Query from another app
get the
ContentResolver
object

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

URI: an identifier
to locate the user
dictionary

8
Locating resources using
Content URIs


scheme - always "content"
authority - name of entire provider
} used by Android to

identify a content provider

}
• path (optional) used by the content

• data type path provider to identify

• instance identifier internal objects

Path

}
content://user_dictionary/words/5
}
}

scheme authority
must be “content” *For non-built-in apps: com.example.<appname>.provider
9
Uri class

• Convert String to Uri via Uri.parse()

• Example:

Uri.parse("content://contacts/people");

10
Creating a content provider
• Why?

• You want to offer complex data or files to other


applications.

• You want to allow users to copy complex data


from your app into other apps.

• You want to provide custom search suggestions


using the search framework.

11
Creating a content provider

• Design URI-to-data mapping

• Manifest declaration

• Implementation

• Permissions

http://developer.android.com/guide/topics/providers/content-provider-creating.html

12
Design URI-to-data
mapping
• authority: user_dictionary
• path:
• /words: all words
• /words/<id>: a specific word
• Use UriMatcher

sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);


sUriMatcher.addURI(AUTHORITY, "words", WORDS);
sUriMatcher.addURI(AUTHORITY, "words/#", WORD_ID);

http://androidxref.com/4.4.3_r1.1/xref/packages/providers/UserDictionaryProvider/src/com/android/providers/
userdictionary/UserDictionaryProvider.java

13
Declare in manifest
A content provider is an app component
http://developer.android.com/guide/topics/manifest/provider-element.html
</application>

<!-- The Content Provider is declared -->
<provider android:name="UserDictionaryProvider"

android:authorities=“user_dictionary"

android:syncable="false"

android:multiprocess="false"

android:exported="true"

android:readPermission="android.permission.READ_USER_DICTIONARY"
android:writePermission="android.permission.WRITE_USER_DICTIONARY" />
</application>

http://androidxref.com/4.4.3_r1.1/xref/packages/providers/UserDictionaryProvider/
AndroidManifest.xml

14
Implementation

Implement a class that extends ContentProvider

public class UserDictionaryProvider extends ContentProvider


{
insert(…);
query(…);
update(…);
delete(…);

}

15
Implementing query

Implement this function:

public Cursor query(



Uri uri, String[] projection,

String selection, String[] selectionArgs,

String sortOrder);

16
Match Uri
content://user_dictionary/words/1
switch (sUriMatcher.match(uri)) {
case WORDS:
path segments: [“words”,
qb.setTables(USERDICT_TABLE_NAME);
“1”]
qb.setProjectionMap(sDictProjectionMap);
break;
case WORD_ID:
qb.setTables(USERDICT_TABLE_NAME);
qb.setProjectionMap(sDictProjectionMap);
qb.appendWhere(

"_id" + "=" + uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException(

"Unknown URI " + uri);
}

17
Query DB, then return cursor
// If no sort order aisContentObserver
Register specified use the default
String orderBy;
if (TextUtils.isEmpty(sortOrder)) {
orderBy = Words.DEFAULT_SORT_ORDER;
Allow Android’s “CursorLoader”
} else {
mechanism to automatically re-fetch data
orderBy = sortOrder;
}

// Get the database and run the query


SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection,

selectionArgs, null, null, orderBy);

// Tell the cursor what uri to watch, so it knows when its


source data changes
c.setNotificationUri(

getContext().getContentResolver(), uri);

return c;

18
Implementing insert
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
// Validate the requested uri
if (sUriMatcher.match(uri) != WORDS) {
throw new IllegalArgumentException("Unknown URI " + uri);
} return the inserted URI
ContentValues values;
… // sanitize initialValues and store to values

SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long rowId = db.insert(

USERDICT_TABLE_NAME, Words.WORD, values);
if (rowId > 0) {
Uri wordUri = ContentUris.withAppendedId(

UserDictionary.Words.CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(

wordUri, null);
mBackupManager.dataChanged();
return wordUri;
} notify content observers
throw new SQLException("Failed to insert row into " + uri);
}

19
Permissions in manifest

http://developer.android.com/guide/topics/manifest/provider-element.html
exported: enable to share with
</application>

other apps
<!-- The Content Provider is declared -->
<provider android:name="UserDictionaryProvider"

android:authorities=“user_dictionary"

android:syncable="false"

android:multiprocess="false"

android:exported="true"

android:readPermission="android.permission.READ_USER_DICTIONARY"
android:writePermission="android.permission.WRITE_USER_DICTIONARY" />
</application>

http://androidxref.com/4.4.3_r1.1/xref/packages/providers/UserDictionaryProvider/
AndroidManifest.xml

20
Permissions in manifest

http://developer.android.com/guide/topics/manifest/provider-element.html
</application>
… read/write permissions
<!-- The Content Provider is declared -->
<provider android:name="UserDictionaryProvider"

android:authorities=“user_dictionary"

android:syncable="false"

android:multiprocess="false"

android:exported="true"

android:readPermission="android.permission.READ_USER_DICTIONARY"
android:writePermission="android.permission.WRITE_USER_DICTIONARY" />
</application>

http://androidxref.com/4.4.3_r1.1/xref/packages/providers/UserDictionaryProvider/
AndroidManifest.xml

21
Permissions on whole
content provider
• Single read-write provider-level permission

• One permission that controls both read and write


access to the entire provider, specified with the
android:permission attribute of the <provider> element.

• Separate read and write provider-level permission

• You specify them with the android:readPermission and


android:writePermission attributes of the <provider>
element. They take precedence over the permission
required by android:permission.

22
Path-level permissions

You specify each URI with a <path-permission> child


element of the <provider> element. For each content
URI you specify, you can specify a read/write
permission, a read permission, or a write permission,
or all three.

Path-level permission takes precedence over


provider-level permissions.

23
Temporary permissions

• Temporarily grant an app access


• In the context of an invocation using an intent.

— revoked when this invocation ends.
• To a specific URI specified in the intent.

24
Example: email attachments

a l ly:

m
Nor ccess
an’t a
c

attachments

25
Example: email attachments

user clicks

a r i l y 

m p o r
a n t e
c c e s s
ac
attachments
i ng i n t e nt
s
invoke u

a content-provider backed by files


26
Temporary permissions
• Manifest: assert android:grantUriPermissions
attribute in the <provider> element.
• The scope of these permissions can be further
limited by the <grant-uri-permission>.
• Intent (runtime): using the
FLAG_GRANT_READ_URI_PERMISSION and
FLAG_GRANT_WRITE_URI_PERMISSION flags in
the Intent object that activates the component.

27
Example: email attachments
Invoke using intent

28
Example: email attachments

Enable in manifest
Example: email attachments

Implement file-related function in ContentProvider

public ParcelFileDescriptor openFile(



Uri uri, String mode)

throws FileNotFoundException

http://androidxref.com/4.4.3_r1.1/xref/packages/apps/Email/src/com/android/email/provider/AttachmentProvider.java

30
Android’s built-in file-backed
content provider class
• FileProvider: a subclass of ContentProvider

• Implemented by Android

• Supports simple filename-to-URI mapping

https://developer.android.com/reference/android/support/v4/content/FileProvider.html

31

You might also like