Files
notes/docs/lectures/mdp/12_content_providers.md
T

5.2 KiB
Raw Blame History

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

image-20220107180058110

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

image-20220107180837589

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
  • 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
  • Enables Content Providers to be used across multiple applications
  • Can observe a content provider to be informed of real-time modifications
    • e.g. contentResolver monitors the path and can notify if a new email pops up ✉

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 CursorWindow size is 2 Mb
Example of Querying Contacts
  • To access / modify requires a permission
    • android.permission.READ_CONTACTS
    • android.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
    • Contacts
      • Aggregated raw contacts
        • Single view of a person
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)