5.2 KiB
Content Providers - Storage
Access to data is restricted to the app that owns it
- Database is usually located in internal app-specific storage
- If we want other apps to access our data, or we want to access other apps’ data, or we want to be notified when data has changed, we must use a content provider
Content providers expose data / content to other applications in a structured manner
- Fundamentally IPC via Binder and ashmem (Android shared memory) with a well-defined (database-like) interface
System Content Providers
Content providers manage data for:
Browser: bookmarks, history
Call Log: Telephone usage
Contacts: Contact data, contacts for other apps, e.g. WhatsApp
Media: Media metadata database
User Dictionary: database for predictive spelling
Storage Access Framework
Is an abstraction of documents
- Restricted access to external storage
- Enumerated by the system content object picker
A content provider is mostly used for making content available outside your application, as using it to get data is now done by the repository.
How to use it?
- Create our own by sub-classing
ContentProvider- Must add it in the manifest
- Or add/query data via an existing content provider
Data Model
Very similar to a relational database table
- A collection of records
- Support for read/write
- Support for typical database operations
- CRUD - Create Read Update Delete
Records are stored in rows, with each column providing different data fields
- Each record has a numeric id (in the field ID) that uniquely identifies it
- Tables exposed via URI
- This is a further abstraction
Applications query the content provider, which maps the requests to the underlying database. This can be SQLite or Room (doesn’t really matter to the application)
Querying a Content Provider
Content Providers identify data sets through URIs
content://authority/path/id- content: Data managed by a content provider
- authority: ID for the Content provider
- A fully qualified class name, e.g.
com.example.project
- A fully qualified class name, e.g.
- path: 0 or more segments indicating the subset of data to be requested
- e.g. table name
- A RESTful resource philosophy
- id: specific record (row) being accessed
/email/2021/Nov/17 -> would retrieve all emails received on Nov 17th 📅
Content Resolver
- Manages and supports content provider access
- How to service a request for content
- Similar to
ServiceManager
- Similar to
- Enables Content Providers to be used across multiple applications
- Can observe a content provider to be informed of real-time modifications
- e.g.
contentResolvermonitors the path and can notify if a new email pops up ✉
- e.g.
Full URI: ContactsContract.Contact.CONTENT_URI = "content://com.android.contacts/contacts/"
ContentResolver.query(...)
- Returns a cursor instance for accessing results
- Cursor is a pointer to a
cursorWindow- A read-only reference to shared memory
- Allocated by ashmem
- Retrieved via Binder
- Max
CursorWindowsize is 2 Mb
Example of Querying Contacts
- To access / modify requires a permission
android.permission.READ_CONTACTSandroid.permission.WRITE_CONTACTS
- Contacts has 3 components
- Data
- Rows (mime-typed) that can hold personal info
- Raw Contacts
- A contact for a given person from a given system
- Gmail contact, Facebook contact, etc.
- Associated with data entries
- A contact for a given person from a given system
- Contacts
- Aggregated raw contacts
- Single view of a person
- Aggregated raw contacts
- Data
Modifying a Content Provider
Uri insert (Uri uri, ContentValues values)
Returns the URI of the newly inserted item
int update(Uri uri, ContentValues values, String where, String[] selectionArgs)
Parameters
uri: the table we want to modify
content values: values for the new row or key/value pairs where the key is the column name
Creating a content Provider
- Implement a storage system for the data
- Structured data, can be SQLite or Room
- Media & blobs
- Implement a content provider
- query, add, update, insert, etc.
- onCreate
- When content provider is instantiated, needs to instantiate the internal storage (create the table)
- getType
- single items, multiple items, mime type
- Tell Android we are a provider
- Declare in the manifest
Contract
- Defines metadata pertaining to the provider
- Constant definitions that are exposed to developers via a compiled .jar file
- Authority
- URI
- Meta-data
- Column names
URI Matching
All of these methods take a URI as the first parameter
- The object will need to parse it to know what to return
android.content.UriMatcher
- Provides mapping between abstraction of contract class to concrete db implementation
- Does the calling app want all the data from the table or just a row?
content://authority/tablename/- whole table
content://authority/tablename/1- row
- Or a virtual table (joins across various underlying resources)

