Download - Content providers in Android
Content Providers in Android
● Overall structure
● Interaction with Content Provider● Constructing query● Retreiving cursor asyncronuously● Provider permissions● Creating Content Provider● Questions
● Overall structure
● Interaction with Content Provider● Constructing query● Retreiving cursor asyncronuously● Provider permissions● Creating Content Provider● Questions
Overall structure
Content Provider
Application #1
Activity #1
Activity #2
Activity #3
Database Files XML Remoteconnection …
Activity #1
Application #2
Activity #1
Application #3
Activity #2
Content Provider is a source
Content Provider
Application #1
Activity #1
Activity #2
Activity #3
Database Files XML Remoteconnection …
Activity #1
Application #2
Activity #1
Application #3
Activity #2
For some consumers
Content Provider
Application #1
Activity #1
Activity #2
Activity #3
Database Files XML Remoteconnection …
Activity #1
Application #2
Activity #1
Application #3
Activity #2
Gives access to variety types of data
Content Provider
Application #1
Activity #1
Activity #2
Activity #3
Database Files XML Remoteconnection …
Activity #1
Application #2
Activity #1
Application #3
Activity #2
Overall structure
Content Provider
Application #1
Activity #1
Activity #2
Activity #3
Database Files XML Remoteconnection …
Activity #1
Application #2
Activity #1
Application #3
Activity #2
● Overall structure
● Interaction with Content Provider● Constructing query● Retreiving cursor asyncronuously● Provider permissions● Creating Content Provider● Questions
Interaction with Content Provider
Content Provider
Application #1
Activity #1
Activity #2
Activity #3
Database Files XML Remoteconnection …
Activity #1
Application #2
Activity #1
Application #3
Activity #2
Activity to Content Provider access
Content Provider
Activity
ContentResolverCursor
CursorAdapter ListView
Activity
Content Provider
Activity
ContentResolverCursor
CursorAdapter ListView
Performing request
ContentResolver
Query
Delete
Update
Insert
Content Provider
URI
URI
content://com.example.provider/articles
Scheme Authority Path
● Overall structure
● Interaction with Content Provider● Constructing query● Retreiving cursor asyncronuously● Provider permissions● Creating Content Provider● Questions
Constructing query
SELECT _id, title, content, date FROM articles WHERE date >= 1352470000 ORDER BY date ASC
Constructing queryString[] mProjection = { "_id", "title", "content", "date", };String mSelection = "date >= ?";
String[] mSelectionArgs = {"1352470000"};
String mSortOrder = "date ASC";Cursor cursor = getContentResolver().query( MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder);
Constructing queryString[] mProjection = { "_id", "title", "content", "date", };String mSelection = "date >= ?";
String[] mSelectionArgs = {"1352470000"};
String mSortOrder = "date ASC";Cursor cursor = getContentResolver().query( MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder);
Constructing queryString[] mProjection = { "_id", "title", "content", "date", };String mSelection = "date >= ?";
String[] mSelectionArgs = {"1352470000"};
String mSortOrder = "date ASC";Cursor cursor = getContentResolver().query( MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder);
Constructing queryString[] mProjection = { "_id", "title", "content", "date", };String mSelection = "date >= ?";
String[] mSelectionArgs = {"1352470000"};
String mSortOrder = "date ASC";Cursor cursor = getContentResolver().query( MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder);
Constructing queryString[] mProjection = { "_id", "title", "content", "date", };String mSelection = "date >= ?";
String[] mSelectionArgs = {"1352470000"};
String mSortOrder = "date ASC";Cursor cursor = getContentResolver().query( MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder);
Constructing queryString[] mProjection = { "_id", "title", "content", "date", };String mSelection = "date >= ?";
String[] mSelectionArgs = {"1352470000"};
String mSortOrder = "date ASC";Cursor cursor = getContentResolver().query( MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder);
Cursor_id title content date
1 First article Lorem ipsum... 1352475013
2 Second article Dolor sit amet... 1352471413
... ... ... ...
if (mCursor != null) { while (mCursor.moveToNext()) { String title = mCursor.getString(Columns.TITLE); }}
● Overall structure
● Interaction with Content Provider● Constructing query● Retreiving cursor asyncronuously● Provider permissions● Creating Content Provider● Questions
Activity & blocking queries
Content Provider
Activity
ContentResolverCursor
CursorAdapter ListView
Activity & non blocking queries
Content Provider
Activity
ContentResolverCursor
CursorAdapter ListView
CursorLoader
AsyncQueryHandler
Activity & Loader
Content Provider
Activity
ContentResolverCursor
CursorAdapter ListView
CursorLoader
AsyncQueryHandler
Activity & Loader
getSupportLoaderManager().initLoader(0, null, this);...
public class ArticlesActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {...
public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader( this, // context MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder); }
public void onLoadFinished( Loader<Cursor> loader, Cursor cursor) { mAdapter.swapCursor(cursor); }
Activity & Loader
getSupportLoaderManager().initLoader(0, null, this);...
public class ArticlesActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {...
public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader( this, // context MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder); }
public void onLoadFinished( Loader<Cursor> loader, Cursor cursor) { mAdapter.swapCursor(cursor); }
Activity & Loader
getSupportLoaderManager().initLoader(0, null, this);...
public class ArticlesActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {...
public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader( this, // context MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder); }
public void onLoadFinished( Loader<Cursor> loader, Cursor cursor) { mAdapter.swapCursor(cursor); }
Activity & Loader
getSupportLoaderManager().initLoader(0, null, this);...
public class ArticlesActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {...
public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader( this, // context MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder); }
public void onLoadFinished( Loader<Cursor> loader, Cursor cursor) { mAdapter.swapCursor(cursor); }
Activity & Loader
getSupportLoaderManager().initLoader(0, null, this);...
public class ArticlesActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {...
public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader( this, // context MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder); }
public void onLoadFinished( Loader<Cursor> loader, Cursor cursor) { mAdapter.swapCursor(cursor); }
Activity & AsyncQueryHandler
Content Provider
Activity
ContentResolverCursor
CursorAdapter ListView
CursorLoader
AsyncQueryHandler
Activity & AsyncQueryHandler
private AsyncQueryHandler mHandler;
...
mHandler = new MyAsyncQueryHandler(getContentResolver());mHandler.startQuery( 0, // token null, // cookie MyContentProvider.ARTICLES_CONTENT_URI, mProjection, mSelection, mSelectionArgs, mSortOrder);
Activity & AsyncQueryHandler
class MyAsyncQueryHandler extends AsyncQueryHandler { public MyAsyncQueryHandler(ContentResolver cr) { super(cr); } @Override protected void onQueryComplete( int token, Object cookie, Cursor cursor) { mAdapter.swapCursor(cursor); } }
● Overall structure
● Interaction with Content Provider● Constructing query● Retreiving cursor asyncronuously● Provider permissions● Creating Content Provider● Questions
Permissions
<permission android:name="com.example.provider.permission.READ_ARTICLES" android:protectionLevel="normal" />
<provider android:name=".MyContentProvider" android:exported="false" android:authorities="com.example.provider" android:permission="com.example.provider.permission.READ_ARTICLES"/>
<uses-permission android:name="com.example.provider.permission.READ_ARTICLES" />
Permissions
<permission android:name="com.example.provider.permission.READ_ARTICLES" android:protectionLevel="normal" />
<provider android:name=".MyContentProvider" android:exported="false" android:authorities="com.example.provider" android:permission="com.example.provider.permission.READ_ARTICLES"/>
<uses-permission android:name="com.example.provider.permission.READ_ARTICLES" />
Permissions
<permission android:name="com.example.provider.permission.READ_ARTICLES" android:protectionLevel="normal" />
<provider android:name=".MyContentProvider" android:exported="false" android:authorities="com.example.provider" android:permission="com.example.provider.permission.READ_ARTICLES"/>
<uses-permission android:name="com.example.provider.permission.READ_ARTICLES" />
● Overall structure
● Interaction with Content Provider● Constructing query● Retreiving cursor asyncronuously● Provider permissions● Creating Content Provider● Questions
Creating content provider
public class MyContentProvider extends ContentProvider {...
onCreate()
query()
insert()
update()
delete()
getType()
URI matching
content://com.example.provider/articles
content://com.example.provider/articles/*
content://com.example.provider/articles/#
URI matching
content://com.example.provider/articles
content://com.example.provider/articles/*
content://com.example.provider/articles/#
URI matching
content://com.example.provider/articles
content://com.example.provider/articles/*
content://com.example.provider/articles/#
URI matching
sUriMatcher.addURI("com.example.provider", "articles/#", 0);
sUriMatcher.addURI("com.example.provider", "articles/today", 1);
sUriMatcher.addURI("com.example.provider", "articles/history/*", 2);
...
public String getType(Uri uri) { switch (sUriMatcher.match(uri)) {...
URI matching
sUriMatcher.addURI("com.example.provider", "articles/#", 0);
sUriMatcher.addURI("com.example.provider", "articles/today", 1);
sUriMatcher.addURI("com.example.provider", "articles/history/*", 2);
...
public String getType(Uri uri) { switch (sUriMatcher.match(uri)) {...
MIME types
vnd.android.cursor.dir/vnd.com.example.provider.article
vnd.android.cursor.item/vnd.com.example.provider.article
getType()
getStreamTypes()
{ "image/jpeg", "image/png", "image/gif" }
MIME types
vnd.android.cursor.dir/vnd.com.example.provider.article
vnd.android.cursor.item/vnd.com.example.provider.article
getType()
getStreamTypes()
{ "image/jpeg", "image/png", "image/gif" }
Questions
Thank you!
Useful links
http://developer.android.com/guide/topics/providers/content-provider-basics.html
http://developer.android.com/guide/topics/providers/content-provider-creating.html
http://developer.android.com/guide/topics/security/permissions.html
http://gdg.org.ua
http://dnipro.gdg.org.ua
About speaker
Alexey Ustenko — Android developerCoordniator of GDG Dnipropetrovs'k
@ustav