Download presentation
Presentation is loading. Please wait.
1
Making content providers
David Sutton/Ian Bayley
2
OUTLINE OF LECTURE Essential methods of a content provider
Example provider Helper classes Implementation of the example
3
CONTENT PROVIDERS To make a content provider we must extend the abstract class ContentProvider. We must override (at least) the following methods: onCreate Method called when the content provider is created. query Performs a query over the content provider insert Inserts a new row into the provider delete Deletes row(s) from the provider update Updates the values of particular column(s) in particular row(s). getType Returns the MIME type of data at a particular URI.
4
AN EXAMPLE CONTENT PROVIDER
We will illustrate the creation of content providers by implementing a simple provider that we can use to find the capital cities of various countries. The provider will expose a table that looks like this Id Country Capital 1 France Paris 2 Germany Berlin 3 Italy Rome 4 Spain Madrid
5
URIS OF TABLES AND ROWS The capitals table itself will be identified by the URI uk.ac.brookes.bayley.capitals/capitals Individual rows within the table are identified by adding a trailing row number to the URI for the table. For instance the row for Germany would be identified by uk.ac.brookes.bayley.capitals/capitals/2 Id Country Capital 1 France Paris 2 Germany Berlin 3 Italy Rome 4 Spain Madrid
6
CLASSES THAT WILL HELP US
We will store our data in an SQLite database. We will make use of the following classes to help us implement the provider: SQLiteDatabase – Exposes methods to manage an SQLite database SQLiteOpenHelper - Helper class to manage database creation and version management SQLiteQueryBuilder – Utility class for building SQL queries. UriMatcher – Utility class that determines whether a given Uri matches a given pattern. ContentValues – a set of key-value pairs where the key is a column name and the value is a value to insert into that column We shall not be able to give complete descriptions of these classes, but there definitions can be found in the android developer reference.
7
BASIC STRUCTURE OF THE CONTENT PROVIDER
SQLiteOpenHelper ContentProvider createWriteableDatabase onCreate onUpgrade Called when the database is created performs an SQL create statement CapitalsProvider CapitalsDatabaseHelper SQLLiteDatabase capitalsDb UriMatcher uriMatcher onCreate onUpgrade Called when the database needs to be upgraded. Our implementation simply drops the table then calls onCreate onCreate query insert delete update getType
8
Capitalsprovider Constants and nested class
public class CapitalsProvider extends ContentProvider { public static final String AUTHORITY = "uk.ac.brookes.bayley.capitals"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/capitals"); private SQLiteDatabase capitalsDB; private static final String CAPITALS_TABLE = "capitals"; public static final String KEY_ID = "_id"; public static final String KEY_COUNTRY = "country"; public static final String KEY_CAPITAL = "capital"; ... private static class CapitalsDatabaseHelper extends SQLiteOpenHelper { This is a static nested class
9
CapitalsDatabaseHelper
static nested classes CapitalsProvider A static nested class is defined within another class. Objects of the nested class can access static fields and methods of the enclosing class static KEY_COUNTRY=“country” static KEY_CAPITAL = “capital” CapitalsDatabaseHelper createWriteableDatabase() onCreate() onUpgrade() public class CapitalsProvider extends ContentProvider { ... private static class CapitalsDatabaseHelper extends SQLiteOpenHelper { } ....
10
DAtabase helper private static class CapitalsDatabaseHelper extends SQLiteOpenHelper { public CapitalsDatabaseHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + CAPITALS_TABLE + " (" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_COUNTRY + " TEXT," + KEY_CAPITAL + " TEXT);"); public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + CAPITALS_TABLE); onCreate(db);
11
Creating the database db.execSQL("CREATE TABLE " + CAPITALS_TABLE + " (" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_COUNTRY + " TEXT," + KEY_CAPITAL + " TEXT);"); CREATE TABLE capitals( id INTEGER PRIMARY KEY AUTOINCREMENT, country TEXT capital TEXT) Id Country Capital This column contains integer values. The database will automatically add increasing values so that each row has a unique value. These two column contains text values.
12
uri matcher The code that creates our URIMatcher looks like this…
public static final String AUTHORITY = "uk.ac.brookes.bayley.capitals"; private static final int CAPITALS = 1; private static final int COUNTRY_ID = 2; uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "capitals", CAPITALS); uriMatcher.addURI(AUTHORITY, "capitals/#", COUNTRY_ID); The calls to addURI add patterns that the can be matched, and integer codes that will be returned if they do match. The # matches any number. We test for matches using a method ‘match’. So “uk.ac.brookes.bayley.capitals/capitals” matches the first pattern, and CAPITALS is returned. “uk.ac.brookes.bayley.capitals/capitals/3” matches the second pattern and COUNTRY_ID is returned.
13
IMPLEMENTING CAPITALS PROVIDER: ONCREATE
OnCreate should attempt to create the database, and return true or false depending on whether it was successful in doing this. public boolean onCreate() { CapitalsDatabaseHelper helper = new CapitalsDatabaseHelper( this.getContext(), DATABASE_NAME, null, DATABASE_VERSION); this.capitalsDB = helper.getWritableDatabase(); return (capitalsDB != null); }
14
IMPLEMENTING CAPITALS PROVIDER: QUERY
The query method has the following signature public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) { The parameters are as follows: uri – URI of the table or row to be queried projection, selection, selectioArgs – define a potential projection and/or selection over the content provider. Can be null if we want to return all rows and/or all columns. sort – defines the order in which rows are to be returned. Can be null if we do not care what order we get the rows in. The return value is a Cursor over the rows in the query.
15
IMPLEMENTING CAPITALS PROVIDER: QUERY
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(CAPITALS_TABLE); if (uriMatcher.match(uri) == COUNTRY_ID) { qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1)); } Cursor c = qb.query(capitalsDB, projection, selection, selectionArgs, null, null, sort); c.setNotificationUri(getContext().getContentResolver(), uri); return c;
16
IMPLEMENTING CAPITALS PROVIDER: INSERT
The insert method has the following signature public Uri insert(Uri uri, ContentValues values) Parameters: uri- URI of the table into which we insert a value values – a set of key value pairs. The keys are columns and the values are values that those columns should have in an inserted row. For example we might specify that the COUNTRY_COLUMN column should have the value “Italy” and that the CAPITAL_COLUMN column should have the value “Rome” Returns: A URI for the inserted row. For example if the row got inserted at index 2 we would return uk.ac.brookes.bayley.capitals/capitals/2
17
IMPLEMENTING CAPITALS PROVIDER: INSERT
public Uri insert(Uri uri, ContentValues values) { long rowID = capitalsDB.insert(CAPITALS_TABLE, KEY_COUNTRY, values); if (rowID > 0) { Uri newuri = ContentUris.withAppendedId(CONTENT_URI, rowID); getContext().getContentResolver().notifyChange(newuri, null); return uri; } else throw new SQLException("Failed to insert row into " + uri); }
18
IMPLEMENTING CAPITALS PROVIDER: UPDATE
The update method has the following signature: public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { Parameters: uri – the URI of the table or row to update values – a set of key-value pair expressing values to be inserted into particular columns. where, whereArgs – express an SQL where clause defining the rows to be updated Returns: The number of rows inserted.
19
IMPLEMENTING CAPITALS PROVIDER: UPDATE
makeNewWhere is a private method defined on the next slide @Override public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { int matchResult = uriMatcher.match(uri); String newWhere = makeNewWhere(where, uri, matchResult); if (matchResult == COUNTRY_ID || matchResult == CAPITALS) { int count = capitalsDB.update(CAPITALS_TABLE, values, newWhere, whereArgs); getContext().getContentResolver().notifyChange(uri, null); return count; } else throw new IllegalArgumentException("Unknown URI " + uri); }
20
IMPLEMENTING CAPITALS PROVIDER: MAKENEWWHERE
private String makeNewWhere(String where, Uri uri, int matchResult) { if (matchResult != COUNTRY_ID) { return where; } else { String newWhereSoFar = KEY_ID + "=" + uri.getPathSegments().get(1); if (TextUtils.isEmpty(where)) return newWhereSoFar; else return newWhereSoFar + " AND (" + where + ')'; }
21
IMPLEMENTING CAPITALS PROVIDER: DELETE
The delete method has the following signature: public int delete(Uri uri, String where, String[] whereArgs) Parameters: uri – the URI of the table or row from which we are deleting. where, whereArgs – represent an SQL where clause that defines which rows should be deleted. Returns: The number of rows deleted.
22
IMPLEMENTING CAPITALS PROVIDER: DELETE
public int delete(Uri uri, String where, String[] whereArgs) { int matchResult = uriMatcher.match(uri); String newWhere = makeNewWhere(where, uri, matchResult); if (matchResult == COUNTRY_ID || matchResult == CAPITALS) { int count = capitalsDB.delete(CAPITALS_TABLE, newWhere, whereArgs); getContext().getContentResolver().notifyChange(uri, null); return count; } else throw new IllegalArgumentException("Unknown URI " + uri); }
23
IMPLEMENTING CAPITALS PROVIDER: GETTYPE
The getType method has the following signature public String getType(Uri uri) Parameter: uri – URI of a table or row Returns: A String describing the MIME type of the data at the given URI. This should start with “vnd.android.cursor.item” for a single record, or “vnd.android.cursor.dir/” for multiple items.
24
IMPLEMENTING CAPITALS PROVIDER: GETTYPE
public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case CAPITALS: return "vnd.android.cursor.dir/vnd.brookes.country"; case COUNTRY_ID: return "vnd.android.cursor.item/vnd.brookes.country"; default: throw new IllegalArgumentException("Unsupported URI: " + uri); }
25
SUMMARY We implement a content provider by extending the abstract class ContentProvider and implementing its abstract methods: onCreate query insert delete update getType Various auxiliary classes: SQLiteDatabase, SQLiteOpenHelper, SQLiteQueryBuilder, UriMatcher, ContentValues.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.