自己實現第一個ContentProvider

一、概念及說明

ContentProvider定義:

內容提供者是一個android應用的基礎模塊,提供內容給這個應用,它們封裝數據和提供它給應用通過這個ContentResolver接口,使用ContentProvider可以在不同的應用程序之間共享數據,android爲常見的一些數據提供了ContentProvider(視頻、音頻),ContentProvider使用表的形式來組織數據。

 URI定義:

每一個ContentProvider都擁有一個公共的URI,這個URI用於表示這個ContentProvider所提供的數據。android所提供ContentProvider都存放在android.provider。


二、實現ContentProvider的過程

1。定義ContentProvider所需要的常量(最主要的是定義CONTENT_URI,CONTENT_URI是Uri類型,事實是通過字符串解析得到)

//定義ContentProvider所需要的常量
public class FirstProviderMetaData {

	// AUTHORIY等於自己的創建ContentProvider類的完全路徑
	public static final String AUTHORIY = "com.example.firstconent.FirstContentProvider";

	// 數據庫的名稱
	public static final String DATABASE_NAME = "FirstProvider.db";

	// BaseColumns有兩個字段_id和_count
	public static final class UserTableMetaData implements BaseColumns {
		// 表名
		public static final String TABLE_NAME = "t_user";
		// 訪問該ContentProvider的URI
		public static final Uri CONTENT_URI = Uri
				.parse("content://" + AUTHORIY);

		// 表的數據類型
		public static final String CONTENT_TYPE = "vnd.android.cursor.dir/users";
		// 一列的數據類型
		public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/users";

		// 一個字段
		public static final String USER_NAME = "name";

		// 默認排序
		public static final String DEFAULT_SORT_ORDER = "_id desc";
	}
}

2。定義一個類,繼承ContentProvider

3。實現query,insert,update,delete,getType和onCreate方法


(1).定義UriMatcher

// 匹配Uri,檢查Uri的合法性
	public static final UriMatcher uriMatcher;
	public static final int INCOMING_USER_COLLECTION = 1;
	public static final int INCOMING_USER_SIGNLE = 2;
	static {
		// 創建一個uri樹的根結點
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		// 添加uri匹配對,如果這個匹配成功,則code值則會返回。
		uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/t_user",
				INCOMING_USER_COLLECTION);
		uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/t_user/#",
				INCOMING_USER_SIGNLE);

	}

(2).重寫getType方法

// 根據傳入uri,所回該uri所表示的數據類型
	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		switch (uriMatcher.match(uri)) {
		case INCOMING_USER_COLLECTION:
			return UserTableMetaData.CONTENT_TYPE;
		case INCOMING_USER_SIGNLE:
			return UserTableMetaData.CONTENT_ITEM_TYPE;
		default:
			throw new IllegalArgumentException("Unknown URI" + uri);
		}

	}
(3).創建userProjectMap哈希Map靜態對象

public static HashMap<String, String> userProjectMap;
	static {
		userProjectMap = new HashMap<String, String>();
		userProjectMap.put(UserTableMetaData._ID, UserTableMetaData._ID);
		userProjectMap.put(UserTableMetaData.USER_NAME,
				UserTableMetaData.USER_NAME);
	}

(4).重寫insert方法

// 該方法返回值是一個uri,這個uri表示的剛剛使用這個方法所插入的數據
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		// rowId是新插入數據的id
		long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
		// 正常插入,-1爲出常錯誤
		if (rowId != -1) {
			// 添加一個id到這個路徑的結尾
			Uri insertUserUri = ContentUris.withAppendedId(
					UserTableMetaData.CONTENT_URI, rowId);
			// 得到一個ContentResolver實例.
			ContentResolver cr = this.getContext().getContentResolver();
			// 通辭呈數據改變
			cr.notifyChange(insertUserUri, null);

			return insertUserUri;
		} else {
			throw new SQLException("Failed to insert row into" + uri);
		}
	}
(5).重寫query方法

@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		SQLiteQueryBuilder sqb = new SQLiteQueryBuilder();
		switch (uriMatcher.match(uri)) {
		case INCOMING_USER_COLLECTION:
			sqb.setTables(UserTableMetaData.TABLE_NAME);
			sqb.setProjectionMap(userProjectMap);
			break;
		case INCOMING_USER_SIGNLE:
			sqb.setTables(UserTableMetaData.TABLE_NAME);
			sqb.setProjectionMap(userProjectMap);

			String idKey = UserTableMetaData._ID;
			// 1得到path集合
			// 2取它的集合的第2個元素
			// 例如:CONTENT_URI等於content://com.example.firstconent.FirstContentProvider/t_user/id,
			// content://爲協議
			// com.example.firstconent.FirstContentProvider爲authoriy
			// /t_user/id爲path
			String idValue = uri.getPathSegments().get(1);

			sqb.appendWhere(idKey + "=" + idValue);
			break;
		}
		String orderBy = null;
		if (TextUtils.isEmpty(sortOrder)) {
			orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;
		} else {
			orderBy = sortOrder;
		}
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		Cursor cursor = sqb.query(db, projection, selection, selectionArgs,
				null, null, orderBy);
		ContentResolver cr = this.getContext().getContentResolver();
		// 通適數據變動
		cursor.setNotificationUri(cr, uri);
		return cursor;
	}

4。在AndroidManifest.xml中聲明

<provider
            android:name="com.example.firstcontent.FirstContentProvider"
            android:authorities="com.example.first.firstcontent.FirstContentProvider" >
        </provider>



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章