You start by sub-classing
ContentProvider. Since
ContentProvider
is an abstract class you have to implement the five abstract methods.
These methods are explained in detail later on, for now simply use the
stubs created by Eclipse (or whatever tool you use).
Implementing a content provider involves always the following steps:
- Create a class that extends
ContentProvider
- Define the authority
- Define the URI or URIs
- Create constants to ease client-development
- Implement the
getType()
method
- Implement the CRUD-methods
- Add the content provider to your
AndroidManifest.xml
The abstract methods you have to implement
Method |
Usage |
getType(Uri) |
Returns the MIME type for this URI |
delete(Uri uri, String selection, String[] selectionArgs) |
Deletes records |
insert(Uri uri, ContentValues values) |
Adds records |
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) |
Return records based on selection criteria |
update(Uri uri, ContentValues values, String selection, String[] selectionArgs) |
Modifies data |
Notifying listeners of dataset changes
Clients often want to be notified about changes in the underlying
datastore of your content provider. So inserting data, as well as
deleting or updating data should trigger this notification.
That’s why I used the following line in the code sample above:
| getContext().getContentResolver().notifyChange(uri, null ); | | |
Configuring your content provider
As with any component in Android you also have to register your content provider within the
AndroidManifest.xml
file. The next code sample shows a typical example configuration for a content provider.
<provider
android:name="pritom.kumar.content.provider.LentItemsProvider"
android:authorities="pritom.kumar.content.provider"
android:grantUriPermissions="true"/>
Your own content provider class should look like this:
package pritom.kumar.content.provider;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.net.Uri;
public class LentItemsProvider extends ContentProvider {
private SQLiteDatabase db;
private DataHandler dataHandler;
// public constants for client development
public static final String AUTHORITY = "pritom.kumar.content.provider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + LentItems.CONTENT_PATH);
// helper constants for use with the UriMatcher
private static final int LENTITEM_LIST = 1;
private static final int LENTITEM_ID = 2;
private static final UriMatcher URI_MATCHER;
public static interface LentItems extends BaseColumns {
public static final String DATABASE_NAME = "reminders.db";
public static final String DATABASE_TABLE_NAME = "reminders";
public static final int DATABASE_VERSION = 1;
public static final Uri CONTENT_URI = LentItemsProvider.CONTENT_URI;
public static final String NAME = "name";
public static final String CATEGORY = "category";
public static final String BORROWER = "borrower";
public static final String CONTENT_PATH = "items";
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/LentItemsProvider";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/LentItemsProvider";
public static final String[] PROJECTION_ALL = {_ID, NAME, CATEGORY, BORROWER};
public static final String SORT_ORDER_DEFAULT = NAME + " ASC";
}
// prepare the UriMatcher
static {
URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
URI_MATCHER.addURI(AUTHORITY, LentItems.CONTENT_PATH, LENTITEM_LIST);
URI_MATCHER.addURI(AUTHORITY, LentItems.CONTENT_PATH + "/#", LENTITEM_ID);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int delCount = 0;
switch (URI_MATCHER.match(uri)) {
case LENTITEM_LIST:
delCount = db.delete(DataHandler.TBL_ITEMS, selection, selectionArgs);
break;
case LENTITEM_ID:
String idStr = uri.getLastPathSegment();
String where = LentItems._ID + " = " + idStr;
if (!TextUtils.isEmpty(selection)) {
where += " AND " + selection;
}
delCount = db.delete(DataHandler.TBL_ITEMS, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
// notify all listeners of changes:
if (delCount > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return delCount;
}
@Override
public String getType(Uri uri) {
switch (URI_MATCHER.match(uri)) {
case LENTITEM_LIST:
return LentItems.CONTENT_TYPE;
case LENTITEM_ID:
return LentItems.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (URI_MATCHER.match(uri) != LENTITEM_LIST) {
throw new IllegalArgumentException("Unsupported URI for insertion: " + uri);
}
if(db == null) {
System.out.println(" DB NULL ");
}
System.out.println(values.size());
long id = db.insert(DataHandler.TBL_ITEMS, null, values);
if (id > 0) {
// notify all listeners of changes and return itemUri:
Uri itemUri = ContentUris.withAppendedId(uri, id);
getContext().getContentResolver().notifyChange(itemUri, null);
return itemUri;
}
// s.th. went wrong:
throw new SQLException("Problem while inserting into " + DataHandler.TBL_ITEMS + ", uri: " + uri); // use another exception here!!!
}
@Override
public boolean onCreate() {
dataHandler = new DataHandler(getContext());
db = dataHandler.getWritableDatabase();
System.out.println("LentItemsProivider onCreate done. Data base is "+(db==null?"null":"not null")+".");
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(DataHandler.TBL_ITEMS);
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = LentItems.SORT_ORDER_DEFAULT;
}
System.out.println("HERE IN query matcher: "+URI_MATCHER.match(uri));
switch (URI_MATCHER.match(uri)) {
case LENTITEM_LIST:
// all nice and well
break;
case LENTITEM_ID:
// limit query to one row at most:
builder.appendWhere(LentItems._ID + " = " + uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
Cursor cursor = builder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
// if we want to be notified of any changes:
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int updateCount = 0;
switch (URI_MATCHER.match(uri)) {
case LENTITEM_LIST:
updateCount = db.update(DataHandler.TBL_ITEMS, values, selection, selectionArgs);
break;
case LENTITEM_ID:
String idStr = uri.getLastPathSegment();
String where = LentItems._ID + " = " + idStr;
if (!TextUtils.isEmpty(selection)) {
where += " AND " + selection;
}
updateCount = db.update(DataHandler.TBL_ITEMS, values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
// notify all listeners of changes:
if (updateCount > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return updateCount;
}
}
Your DataHandler class should look like this:
package pritom.kumar.content.provider;
import pritom.kumar.content.provider.LentItemsProvider.LentItems;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DataHandler extends SQLiteOpenHelper {
private String DATABASE_CREATE_SCHEMA = "create table "
+ LentItems.DATABASE_TABLE_NAME + " (" + LentItems._ID
+ " integer primary key autoincrement, " + LentItems.NAME
+ " text not null, " + LentItems.CATEGORY + " text not null, " + LentItems.BORROWER+" text not null );";
public DataHandler(Context context) {
super(context, LentItems.DATABASE_NAME, null, LentItems.DATABASE_VERSION);
}
public static final String DEFAULT_TBL_ITEMS_SORT_ORDER = "ASC";
private SQLiteDatabase db;
public static final String TBL_ITEMS = LentItems.DATABASE_TABLE_NAME;
@Override
public void onCreate(SQLiteDatabase arg0) {
if(arg0 == null) {
System.out.println("Database is null on create.");
} else {
System.out.println("Database is not null on create.");
}
db = arg0;
db.execSQL(DATABASE_CREATE_SCHEMA);
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
}
}
Use your own custom provider by this code follow:
<?php
Bind your content provider on create, update and delete mode.
Follow the link for details.
getContentResolver().registerContentObserver(LentItems.CONTENT_URI, true, new MyObserver(null));
/* Get your ContentResolver class */
ContentResolver resolver = getContentResolver();
/* Create content values to insert */
ContentValues values = new ContentValues();
values.put(LentItems.NAME, "Software Engineer Basic");
values.put(LentItems.BORROWER, "Pritom Kumar");
values.put(LentItems.CATEGORY, "Computer Science And Engineering");
System.out.println("Row insert id: "+resolver.insert(LentItems.CONTENT_URI, values));
/* Get All data from content provider */
String[] PROJECTION=new String[] {
LentItems.BORROWER,
LentItems.NAME,
LentItems.CATEGORY,
LentItems._ID
};
Cursor c = resolver.query(LentItemsProvider.CONTENT_URI, PROJECTION, null, null, null);
if (c == null){
System.out.println("NULL");
}
else{
while (c.moveToNext())
{
String s1 = c.getString(c.getColumnIndex(LentItems._ID));
String s2 = c.getString(c.getColumnIndex(LentItems.NAME));
String s3 = c.getString(c.getColumnIndex(LentItems.CATEGORY));
String s4 = c.getString(c.getColumnIndex(LentItems.BORROWER));
System.out.println(s1+", "+s2+", "+s3+", "+s4);
}
}
?>