1. Define a Database Contract.
It contains the following information about a Database.
(1) Authority
(2) Table names
(3) column names of each Table
(4) content Uri
import android.net.Uri;
import android.provider.BaseColumns;
import static com.example.viki_hung.imageforumviewer.Constant.PACKAGE_NAME;
/**
* The contract holds database setting for forum content provider.
*/
public final class ForumDBContract {
/**
* the authority of Content Provider
*/
static final String AUTHORITY = PACKAGE_NAME;
/**
* To prevent someone from accidentally instantiating the contract class,
* give it an empty constructor.
*/
private ForumDBContract() {
}
/**
* Inner class that defines the Forum table contents
*/
public static final class ForumEntry implements BaseColumns {
public static final String FORUM_TABLE_NAME = "ForumList";
public static final String FORUM_ID = "fid";
public static final String FORUM_TITLE = "title";
}
/**
* Inner class that defines the Topic table contents
*/
public static final class TopicEntry implements BaseColumns {
public static final String TOPIC_TABLE_NAME = "TopicList";
public static final String TOPIC_ID = "tid";
public static final String TOPIC_FORUM_ID = "fid";
public static final String TOPIC_TITLE = "title";
public static final String TOPIC_IMAGE = "image";
public static final String TOPIC_IMAGE_LIST = "imagelist";
}
/**
* Uri of Forum list content
*/
static final Uri CONTENT_URI_FORUM_LIST =
Uri.parse("content://" + AUTHORITY + "/" + ForumEntry.FORUM_TABLE_NAME);
/**
* Uri of Topic list content
*/
static final Uri CONTENT_URI_TOPIC_LIST =
Uri.parse("content://" + AUTHORITY + "/" + TopicEntry.TOPIC_TABLE_NAME);
}
2. Create a class extends SQLiteOpenHelper
It contains the following information.
(1) Database name
(2) Database version
(3) SQL command to create a database
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import static android.provider.BaseColumns._ID;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.ForumEntry.FORUM_ID;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.ForumEntry.FORUM_TABLE_NAME;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.ForumEntry.FORUM_TITLE;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.TopicEntry.TOPIC_FORUM_ID;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.TopicEntry.TOPIC_ID;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.TopicEntry.TOPIC_IMAGE;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.TopicEntry.TOPIC_IMAGE_LIST;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.TopicEntry.TOPIC_TABLE_NAME;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.TopicEntry.TOPIC_TITLE;
/**
* Database create Helper of forum database
*/
class ForumDBHelper extends SQLiteOpenHelper {
private static final String DEBUG_TAG = ForumDBHelper.class.getSimpleName();
private static final String DATABASE_NAME = "ForumList";
private static final int VERSION_INITIAL = 1;
private static final String DATABASE_CREATE_FORUM_LIST =
"CREATE TABLE if not exists " + FORUM_TABLE_NAME + " ("
+ _ID + " integer PRIMARY KEY autoincrement,"
+ FORUM_ID + " TEXT, "
+ FORUM_TITLE + " TEXT );";
private static final String DATABASE_CREATE_TOPIC_LIST =
"CREATE TABLE if not exists " + TOPIC_TABLE_NAME + " ("
+ _ID + " integer PRIMARY KEY autoincrement,"
+ TOPIC_ID + " TEXT, "
+ TOPIC_FORUM_ID + " TEXT, "
+ TOPIC_TITLE + " TEXT, "
+ TOPIC_IMAGE + " TEXT, "
+ TOPIC_IMAGE_LIST + " TEXT );";
ForumDBHelper(Context context) {
super(context, DATABASE_NAME, null, VERSION_INITIAL);
}
@Override public void onCreate(SQLiteDatabase db) {
Log.d(DEBUG_TAG, "DB onCreate");
db.execSQL(DATABASE_CREATE_FORUM_LIST);
db.execSQL(DATABASE_CREATE_TOPIC_LIST);
}
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
3. Create a ContentProvider which uses SQLiteOpenHelper and UriMatcher
package com.example.viki_hung.imageforumviewer;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.AUTHORITY;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.CONTENT_URI_FORUM_LIST;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.CONTENT_URI_TOPIC_LIST;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.ForumEntry.FORUM_TABLE_NAME;
import static com.example.viki_hung.imageforumviewer.ForumDBContract.TopicEntry.TOPIC_TABLE_NAME;
/**
* The Content Provider of the image forum
*/
public class ForumContentProvider extends ContentProvider {
private static final String DEBUG_TAG = ForumContentProvider.class.getSimpleName();
/**
* UriMatcher to match URI to a code
*/
private static final UriMatcher sUriMatcher;
private static final int URI_MATCH_FORUM_LIST = 1;
private static final int URI_MATCH_TOPIC_LIST = 2;
/**
* match URI to a code using UriMatcher
*/
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(AUTHORITY, FORUM_TABLE_NAME, URI_MATCH_FORUM_LIST);
sUriMatcher.addURI(AUTHORITY, TOPIC_TABLE_NAME, URI_MATCH_TOPIC_LIST);
}
private ForumDBHelper mDbHelper;
@Override public boolean onCreate() {
Log.d(DEBUG_TAG, "CP onCreate");
mDbHelper = new ForumDBHelper(getContext());
return true;
}
@Override public String getType(Uri uri) {
switch (sUriMatcher.match(uri)) {
case URI_MATCH_FORUM_LIST: {
return "vnd.android.cursor.dir/vnd." + AUTHORITY + "." + FORUM_TABLE_NAME;
}
case URI_MATCH_TOPIC_LIST: {
return "vnd.android.cursor.dir/vnd." + AUTHORITY + "." + TOPIC_TABLE_NAME;
}
default: {
return null;
}
}
}
@Override public Uri insert(Uri uri, ContentValues values) {
Uri returnUri = null;
if (values == null || values.size() == 0) {
return null;
}
try {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
if (db == null) {
return null;
}
long id;
switch (sUriMatcher.match(uri)) {
case URI_MATCH_FORUM_LIST: {
// insert value to forum list
id = db.insert(FORUM_TABLE_NAME, null, values);
returnUri = Uri.withAppendedPath(CONTENT_URI_FORUM_LIST, String.valueOf(id));
Log.d(DEBUG_TAG, "CP insert, uri=" + returnUri);
break;
}
case URI_MATCH_TOPIC_LIST: {
// insert value to topic list
id = db.insert(TOPIC_TABLE_NAME, null, values);
returnUri = Uri.withAppendedPath(CONTENT_URI_TOPIC_LIST, String.valueOf(id));
Log.d(DEBUG_TAG, "CP insert, uri=" + returnUri);
break;
}
default: {
return null;
}
}
getContext().getContentResolver().notifyChange(returnUri, null);
} catch (Exception ignored) {
Log.e(DEBUG_TAG, ignored.getMessage(), ignored);
}
return returnUri;
}
@Override public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Cursor cursor = null;
try {
SQLiteDatabase db = mDbHelper.getReadableDatabase();
if (db == null) {
return null;
}
switch (sUriMatcher.match(uri)) {
case URI_MATCH_FORUM_LIST: {
Log.d(DEBUG_TAG, "CP query forum list.");
cursor = db.query(FORUM_TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
}
case URI_MATCH_TOPIC_LIST: {
Log.d(DEBUG_TAG, "CP query topic list.");
cursor = db.query(TOPIC_TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
}
default: {
return null;
}
}
Log.d(DEBUG_TAG, "CP query result cursor_count=" + cursor.getCount());
} catch (Exception ignored) {
Log.e(DEBUG_TAG, ignored.getMessage(), ignored);
}
return cursor;
}
@Override public int delete(Uri uri, String selection, String[] selectionArgs) {
int deleteCount = -1;
SQLiteDatabase db = mDbHelper.getWritableDatabase();
if (db == null) {
return -1;
}
try {
switch (sUriMatcher.match(uri)) {
case URI_MATCH_FORUM_LIST: {
Log.d(DEBUG_TAG, "CP delete forum list.");
deleteCount = db.delete(FORUM_TABLE_NAME, selection, selectionArgs);
break;
}
case URI_MATCH_TOPIC_LIST: {
Log.d(DEBUG_TAG, "CP delete topic list.");
deleteCount = db.delete(TOPIC_TABLE_NAME, selection, selectionArgs);
break;
}
default: {
return -1;
}
}
getContext().getContentResolver().notifyChange(uri, null);
} catch (Exception ignored) {
Log.e(DEBUG_TAG, ignored.getMessage(), ignored);
}
return deleteCount;
}
@Override public int update(Uri uri, ContentValues values, String selection, String[]
selectionArgs) {
int updateCount = -1;
try {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
if (db == null) {
return -1;
}
switch (sUriMatcher.match(uri)) {
case URI_MATCH_FORUM_LIST: {
Log.d(DEBUG_TAG, "CP update forum list.");
updateCount = db.update(FORUM_TABLE_NAME, values, selection, selectionArgs);
break;
}
case URI_MATCH_TOPIC_LIST: {
Log.d(DEBUG_TAG, "CP update topic list.");
updateCount = db.update(TOPIC_TABLE_NAME, values, selection, selectionArgs);
break;
}
default: {
return -1;
}
}
getContext().getContentResolver().notifyChange(uri, null);
} catch (Exception ignored) {
Log.e(DEBUG_TAG, ignored.getMessage(), ignored);
}
return updateCount;
}
}
4. Usage of the ContentProvider
Insert:
// new item ContentValues values = new ContentValues(); values.put(FORUM_ID, forumId); values.put(FORUM_TITLE, forumTitle); // insert a record to DB Uri uri = getContentResolver().insert(CONTENT_URI_FORUM_LIST, values);
delete:
// if parse json OK, clear topic list in DB
int dCount = getContentResolver().delete(
CONTENT_URI_TOPIC_LIST,
TOPIC_FORUM_ID + " = ?",
new String[]{fid});