2010. 8. 15. 04:48

ContentProvider Example

Pro Android 2 책에 나오는 BookProvider 테스트 샘플을 이클립스로 만들어 보았습니다. 

MainActivity 는 BookProvider 를 간단하게 테스트하는 것으로, 중요한 건 Provider 를 만들고 등록하는 방법과 그를 어떻게 이용하는 것입니다. 첨부는 이클립스 프로젝트.


BookProvider.java

package com.sskk.example.bookprovidertest.provider;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.sskk.example.bookprovidertest.provider.BookProviderMetaData.BookTableMetaData;

public class BookProvider extends ContentProvider
{
	private final static String TAG="tag";

	//Create a Projection Map for Columns
	//Projection maps are similar to "as" construct in an sql
	//statement whereby you can rename the
	//columns.
	private static HashMap sBooksProjectionMap;
	static
	{
		sBooksProjectionMap = new HashMap();
		sBooksProjectionMap.put(BookTableMetaData._ID, BookTableMetaData._ID);
		//name, isbn, author
		sBooksProjectionMap.put(BookTableMetaData.BOOK_NAME
				, BookTableMetaData.BOOK_NAME);
		sBooksProjectionMap.put(BookTableMetaData.BOOK_ISBN
				, BookTableMetaData.BOOK_ISBN);
		sBooksProjectionMap.put(BookTableMetaData.BOOK_AUTHOR
				, BookTableMetaData.BOOK_AUTHOR);
		//created date, modified date
		sBooksProjectionMap.put(BookTableMetaData.CREATED_DATE
				, BookTableMetaData.CREATED_DATE);
		sBooksProjectionMap.put(BookTableMetaData.MODIFIED_DATE
				, BookTableMetaData.MODIFIED_DATE);
	}
	//Provide a mechanism to identify all the incoming uri patterns.
	private static final UriMatcher sUriMatcher;
	private static final int INCOMING_BOOK_COLLECTION_URI_INDICATOR = 1;

	private static final int INCOMING_SINGLE_BOOK_URI_INDICATOR = 2;
	static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(BookProviderMetaData.AUTHORITY
				, "books"
				, INCOMING_BOOK_COLLECTION_URI_INDICATOR);
		sUriMatcher.addURI(BookProviderMetaData.AUTHORITY
				, "books/#",
				INCOMING_SINGLE_BOOK_URI_INDICATOR);
	}
	// Deal with OnCreate call back
	private DatabaseHelper mOpenHelper;

	@Override
	public boolean onCreate() {
		mOpenHelper = new DatabaseHelper(getContext());
		return true;
	}

	private static class DatabaseHelper extends SQLiteOpenHelper 
	{
		DatabaseHelper(Context context) 
		{
			super(context, BookProviderMetaData.DATABASE_NAME, null
					, BookProviderMetaData.DATABASE_VERSION);
		}

		//Create the database
		@Override
		public void onCreate(SQLiteDatabase db) 
		{
			db.execSQL("CREATE TABLE " + BookTableMetaData.TABLE_NAME + " ("
					+ BookProviderMetaData.BookTableMetaData._ID
					+ " INTEGER PRIMARY KEY,"
					+ BookTableMetaData.BOOK_NAME + " TEXT,"
					+ BookTableMetaData.BOOK_ISBN + " TEXT,"
					+ BookTableMetaData.BOOK_AUTHOR + " TEXT,"
					+ BookTableMetaData.CREATED_DATE + " INTEGER,"
					+ BookTableMetaData.MODIFIED_DATE + " INTEGER"
					+ ");");
		}
		//Deal with version changes
		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
		{
			Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
					+ newVersion + ", which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS " + BookTableMetaData.TABLE_NAME);
			onCreate(db);
		}
	}

	@Override
	public String getType(Uri uri) 
	{
		switch (sUriMatcher.match(uri)) 
		{
			case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
				return BookTableMetaData.CONTENT_TYPE;

			case INCOMING_SINGLE_BOOK_URI_INDICATOR:
				return BookTableMetaData.CONTENT_ITEM_TYPE;

			default:
				throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection
			, String[] selectionArgs, String sortOrder)
	{
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		switch (sUriMatcher.match(uri))
		{
			case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
				qb.setTables(BookTableMetaData.TABLE_NAME);
				qb.setProjectionMap(sBooksProjectionMap);
				break;

			case INCOMING_SINGLE_BOOK_URI_INDICATOR:
				qb.setTables(BookTableMetaData.TABLE_NAME);
				qb.setProjectionMap(sBooksProjectionMap);
				qb.appendWhere(BookTableMetaData._ID + "="
						+ uri.getPathSegments().get(1));
				break;

			default:
				throw new IllegalArgumentException("Unknown URI " + uri);
		}

		// If no sort order is specified use the default
		String orderBy;
		if (TextUtils.isEmpty(sortOrder)) {
			orderBy = BookTableMetaData.DEFAULT_SORT_ORDER;
		} else {
			orderBy = sortOrder;
		}

		// Get the database and run the query
		SQLiteDatabase db =
			mOpenHelper.getReadableDatabase();

		Cursor c = qb.query(db, projection, selection,
				selectionArgs, null, null, orderBy);

		int i = c.getCount();
		// Tell the cursor what uri to watch,
		// so it knows when its source data changes
		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) 
	{
		// Validate the requested uri
		if (sUriMatcher.match(uri) != INCOMING_BOOK_COLLECTION_URI_INDICATOR) {
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		Long now = Long.valueOf(System.currentTimeMillis());

		//validate input fields
		// Make sure that the fields are all set
		if (values.containsKey(BookTableMetaData.CREATED_DATE) == false) {
			values.put(BookTableMetaData.CREATED_DATE, now);
		}

		if (values.containsKey(BookTableMetaData.MODIFIED_DATE) == false) {
			values.put(BookTableMetaData.MODIFIED_DATE, now);
		}
		if (values.containsKey(BookTableMetaData.BOOK_NAME) == false) {
			throw new SQLException(
					"Failed to insert row because Book Name is needed " + uri);
		}

		if (values.containsKey(BookTableMetaData.BOOK_ISBN) == false) {
			values.put(BookTableMetaData.BOOK_ISBN, "Unknown ISBN");
		}
		if (values.containsKey(BookTableMetaData.BOOK_AUTHOR) == false) {
			values.put(BookTableMetaData.BOOK_ISBN, "Unknown Author");
		}

		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		long rowId = db.insert(BookTableMetaData.TABLE_NAME
				, BookTableMetaData.BOOK_NAME, values);

		if (rowId > 0) {
			Uri insertedBookUri = ContentUris.withAppendedId(
					BookTableMetaData.CONTENT_URI, rowId);
			getContext().getContentResolver().notifyChange(insertedBookUri, null);
			return insertedBookUri;
		}
		throw new SQLException("Failed to insert row into " + uri);
	}

	@Override
	public int update(Uri uri, ContentValues values, String where, String[] whereArgs)
	{
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		int count;
		switch (sUriMatcher.match(uri)) 
		{
			case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
				count = db.update(BookTableMetaData.TABLE_NAME,
						values, where, whereArgs);
				break;
			case INCOMING_SINGLE_BOOK_URI_INDICATOR:
				String rowId = uri.getPathSegments().get(1);
				count = db.update(BookTableMetaData.TABLE_NAME
						, values
						, BookTableMetaData._ID + "=" + rowId
						+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : "")
						, whereArgs);
				break;
			default:
				throw new IllegalArgumentException("Unknown URI " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public int delete(Uri uri, String where, String[] whereArgs) 
	{
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		int count;
		switch (sUriMatcher.match(uri)) 
		{
			case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
				count = db.delete(BookTableMetaData.TABLE_NAME, where, whereArgs);
				break;
			case INCOMING_SINGLE_BOOK_URI_INDICATOR:
				String rowId = uri.getPathSegments().get(1);
				count = db.delete(BookTableMetaData.TABLE_NAME
						, BookTableMetaData._ID + "=" + rowId
						+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : "")
						, whereArgs);
				break;
			default:
				throw new IllegalArgumentException("Unknown URI " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}
}

BookProviderMetaData.java

package com.sskk.example.bookprovidertest.provider;

import android.net.Uri;
import android.provider.BaseColumns;

public class BookProviderMetaData
{
	public static final String AUTHORITY = "com.sskk.example.bookprovidertest.provider.BookProvider";
	public static final String DATABASE_NAME = "book.db";
	public static final int DATABASE_VERSION = 1;
	public static final String BOOKS_TABLE_NAME = "books";

	private BookProviderMetaData() {}

	//inner class describing BookTable
	public static final class BookTableMetaData implements BaseColumns
	{
		private BookTableMetaData() {}
		public static final String TABLE_NAME = "books";

		//uri and MIME type definitions
		public static final Uri CONTENT_URI =
			Uri.parse("content://" + AUTHORITY + "/books");

		public static final String CONTENT_TYPE =
			"vnd.android.cursor.dir/vnd.androidbook.book";

		public static final String CONTENT_ITEM_TYPE =
			"vnd.android.cursor.item/vnd.androidbook.book";

		public static final String DEFAULT_SORT_ORDER = "modified DESC";

		//Additional Columns start here.
		//string type
		public static final String BOOK_NAME = "name";

		//string type
		public static final String BOOK_ISBN = "isbn";

		//string type
		public static final String BOOK_AUTHOR = "author";

		//Integer from System.currentTimeMillis()
		public static final String CREATED_DATE = "created";

		//Integer from System.currentTimeMillis()
		public static final String MODIFIED_DATE = "modified";
	}
}

MainActivity.java

package com.sskk.example.bookprovidertest;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

import com.sskk.example.bookprovidertest.provider.BookProviderMetaData;

public class MainActivity extends Activity {
	private static final String TAG = "MainActivity"; 	

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		deleteTest();

		insertTest();

		readTest();
	}

	private void readTest() {
		ContentResolver contentResolver = getContentResolver(); 
		Cursor cursor = contentResolver.query(BookProviderMetaData.BookTableMetaData.CONTENT_URI, null, null, null, null);
		
		// 행 갯수 출력
		Log.d(TAG, "Cursor Count: " + cursor.getCount());

		// 커서 내용 읽기
		if(cursor.moveToFirst() == true) {        	        	
			do {
				int nameColumn = cursor.getColumnIndex(BookProviderMetaData.BookTableMetaData.BOOK_NAME);
				int authorColumn = cursor.getColumnIndex(BookProviderMetaData.BookTableMetaData.BOOK_AUTHOR);
				int isbnColumn = cursor.getColumnIndex(BookProviderMetaData.BookTableMetaData.BOOK_ISBN);

				String name = cursor.getString(nameColumn);
				String author = cursor.getString(authorColumn);
				String isbn = cursor.getString(isbnColumn);

				Log.d(TAG, name + " " + author + " " + isbn);
			} while(cursor.moveToNext());
		}
	}

	private void deleteTest() {
		ContentResolver contentResolver = getContentResolver(); 		
		
		contentResolver.delete(BookProviderMetaData.BookTableMetaData.CONTENT_URI, null, null);
		
		Cursor cursor = contentResolver.query(BookProviderMetaData.BookTableMetaData.CONTENT_URI, null, null, null, null);
		// 행 갯수 출력
		Log.d(TAG, "Cusor Count: " + cursor.getCount());
	}

	private void insertTest() {
		ContentResolver contentResolver = getContentResolver(); 
		Cursor cursor = contentResolver.query(BookProviderMetaData.BookTableMetaData.CONTENT_URI, null, null, null, null);

		if(cursor.getCount() != 0) return;
		// 행 추가
		ContentValues values = new ContentValues();
		values.put(BookProviderMetaData.BookTableMetaData.BOOK_NAME, "Sonagi");
		values.put(BookProviderMetaData.BookTableMetaData.BOOK_AUTHOR, "HwangSunWon");
		values.put(BookProviderMetaData.BookTableMetaData.BOOK_ISBN, "isbn-0033");

		Uri uri = contentResolver.insert(BookProviderMetaData.BookTableMetaData.CONTENT_URI, values);

		values = new ContentValues();
		values.put(BookProviderMetaData.BookTableMetaData.BOOK_NAME, "HaakHaak");
		values.put(BookProviderMetaData.BookTableMetaData.BOOK_AUTHOR, "LeeOiSu");
		values.put(BookProviderMetaData.BookTableMetaData.BOOK_ISBN, "isbn-0034");
		uri = contentResolver.insert(BookProviderMetaData.BookTableMetaData.CONTENT_URI, values);
	}
}
참고: 안드로이드2 마스터북 Pro Android 2 교재