Đầu tiên các bạn tạo 1 Project như sau: Project name: TestProvider Build Target: Android 2.3.3 Application name: TestProvider Package name: com.ai.android.book.provider Create Activity:
Trang 1TEST PROVIDER Sau đây mình sẽ làm 1 ứng dụng hơi lớn 1 tý để test việc phối hợp giữa các Provider, Interface và SQLite.
Đầu tiên các bạn tạo 1 Project như sau:
Project name: TestProvider
Build Target: Android 2.3.3
Application name: TestProvider
Package name: com.ai.android.book.provider
Create Activity: MonitoredActivity
Trong phần resource của Project các bạn chỉnh lại như sau:
+ Phần layout: tạo thêm 1 file debug_activity_layout.xml (để debug ứng dụng) :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Debut Text Appears here"
/>
</LinearLayout>
File main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Test Provider"
Trang 2/>
</LinearLayout>
+ Phần Menu: Các bạn tạo thêm 1 folder menu trong res/ và tạo tiếp 1 file main_menu.xml :
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/menuGroup_Main">
<item android:id="@+id/menu_display_table"
android:title="Show" />
<item android:id="@+id/menu_add"
android:title="Add Book" />
<item android:id="@+id/menu_delete"
android:title="Remove Book" />
<item android:id="@id/menu_da_clear"
android:title="clear" />
</group>
</menu>
+ Trong file strings.xml :
<resources>
<item type="id" name="menu_da_clear"/>
</resources>
+ Và trong AndroidMenufest.xml ta chỉnh sữa lại như sau:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ai.android.book.provider"
android:versionCode="1"
android:versionName="1.0.0">
<application android:name=".MyApplication"
android:icon="@drawable/icon"
android:label="Test Provider">
<activity android:name=".HelloWorld"
android:label="Test Provider">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
</activity>
<provider android:name=".BookProvider"
android:authorities="com.androidbook.provider.BookProvider"/>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
Trang 3Kế tiếp là phần xữ lý Phần này hơi dài và nhiều file java khác nhau Nên ngoài file Activity chính thì các bạn tạo thêm các file java tương ứng với đoạn code như sau trong package:
+ BaseTester.java:
package com.ai.android.book.provider;
import android.content.Context;
public class BaseTester
{
protected IReportBack mReportTo;
protected Context mContext;
public BaseTester(Context ctx, IReportBack target)
{
mReportTo = target;
mContext = ctx;
} }
+ BookProvider.java:
package com.ai.android.book.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.ai.android.book.provider.BookProviderMetaData.BookTableMetaData;
public class BookProvider extends ContentProvider
{ private static final String TAG = "BookProvider";
Trang 4private static HashMap<String, String> sBooksProjectionMap;
static { sBooksProjectionMap = new HashMap<String, String>();
sBooksProjectionMap.put(BookTableMetaData._ID,
sBooksProjectionMap.put(BookTableMetaData.BOOK_NAME,
sBooksProjectionMap.put(BookTableMetaData.BOOK_ISBN,
sBooksProjectionMap.put(BookTableMetaData.BOOK_AUTHOR,
sBooksProjectionMap.put(BookTableMetaData.CREATED_DATE,
sBooksProjectionMap.put(BookTableMetaData.MODIFIED_DATE,
} 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",
sUriMatcher.addURI(BookProviderMetaData.AUTHORITY, "books/#",
} /**
* This class helps open, create, and upgrade the database file */
private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) {
super(context, BookProviderMetaData.DATABASE_NAME, null,
BookProviderMetaData.DATABASE_VERSION);
} @Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG,"inner oncreate called");
db.execSQL("CREATE TABLE " + BookTableMetaData.TABLE_NAME +
" ("
Trang 5+ 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" + ");");
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{ Log.d(TAG,"inner onupgrade called");
Log.w(TAG, "Upgrading database from version "
+ oldVersion + " to "
+ newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS " +
onCreate(db);
} } private DatabaseHelper mOpenHelper;
@Override
public boolean onCreate() {
Log.d(TAG,"main onCreate called");
mOpenHelper = new DatabaseHelper(getContext());
return true;
} @Override
public Cursor query(Uri uri, String[] projection, String selection,
{ 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 + "="
break;
Trang 6default:
throw new IllegalArgumentException("Unknown URI " + uri); }
String orderBy;
if (TextUtils.isEmpty(sortOrder)) { orderBy = BookTableMetaData.DEFAULT_SORT_ORDER;
} else { orderBy = sortOrder;
} SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection,
int i = c.getCount();
c.setNotificationUri(getContext().getContentResolver(), uri); return c;
} @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 Uri insert(Uri uri, ContentValues initialValues) {
if (sUriMatcher.match(uri)
{ throw new IllegalArgumentException("Unknown URI " + uri); }
ContentValues values;
if (initialValues != null) { values = new ContentValues(initialValues);
} else { values = new ContentValues();
}
Long now = Long.valueOf(System.currentTimeMillis());
if (values.containsKey(BookTableMetaData.CREATED_DATE) == false)
Trang 7{ 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,
if (rowId > 0) { Uri insertedBookUri =
ContentUris.withAppendedId(
getContext() getContentResolver() .notifyChange(insertedBookUri, null);
return insertedBookUri;
} throw new SQLException("Failed to insert row into " + uri); }
@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,
break;
Trang 8case 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;
} @Override
public int update(Uri uri, ContentValues values,
{ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)) { case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.update(BookTableMetaData.TABLE_NAME,
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;
} } + BookProviderMetaData.java:
package com.ai.android.book.provider;
Trang 9import android.net.Uri;
import android.provider.BaseColumns;
public class BookProviderMetaData
{
public static final String AUTHORITY = "com.androidbook.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() {}
public static final class BookTableMetaData implements BaseColumns
{
private BookTableMetaData() {}
public static final String TABLE_NAME = "books";
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";
public static final String BOOK_NAME = "name";
public static final String BOOK_ISBN = "isbn";
public static final String BOOK_AUTHOR = "author";
public static final String CREATED_DATE = "created";
public static final String MODIFIED_DATE = "modified";
}
}
+ HelloWorld.java:
package com.ai.android.book.provider;
import android.util.Log;
import android.view.MenuItem;
public class HelloWorld extends MonitoredDebugActivity
implements IReportBack
{
public static final String tag="HelloWorld";
private ProviderTester providerTester = null;
public HelloWorld()
{
super(R.menu.main_menu,tag);
this.retainState();
Trang 10providerTester = new ProviderTester(this,this);
}
protected boolean onMenuItemSelected(MenuItem item)
{
Log.d(tag,item.getTitle().toString());
if (item.getItemId() == R.id.menu_add)
return true;
if (item.getItemId() == R.id.menu_display_table)
return true;
if (item.getItemId() == R.id.menu_delete)
return true;
return true;
}
}
+ IreportBack.java (Interface)
package com.ai.android.book.provider;
public interface IReportBack
{
public void reportBack(String tag, String message);
}
+ MonitoredDebugActivity.java:
package com.ai.android.book.provider;
import com.ai.android.book.provider.R;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
public abstract class MonitoredDebugActivity extends MonitoredActivity implements IReportBack
Trang 11protected abstract boolean onMenuItemSelected(MenuItem item);
private static String tag=null;
private int menuId = 0;
private boolean m_retainState = false;
public MonitoredDebugActivity(int inMenuId, String inTag)
{
super(inTag);
tag = inTag;
menuId = inMenuId;
}
public void retainState()
{
m_retainState = true;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.debug_activity_layout);
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
appendMenuItemText(item);
if (item.getItemId() == R.id.menu_da_clear){
this.emptyText();
return true;
return onMenuItemSelected(item);
}
private TextView getTextView(){
return (TextView)this.findViewById(R.id.text1);
}
protected void appendMenuItemText(MenuItem menuItem){
String title = menuItem.getTitle().toString();
TextView tv = getTextView();
tv.setText(tv.getText() + "\n" + title);
}
protected void emptyText(){
TextView tv = getTextView();
tv.setText("");
}