用SQLite编写自定义ContentProvider

在android中自定义一个ContentProvider大致需要四步:1,定义数据的MetaData;2,定义一个类继承ContentProvider;3,覆写自定义类中的getType(),onCreate(),insert(),delete(),update(),query()六个方法;4,在AndroidManifest.xml文件中配置我们自定义的ContentProvider

第一步:定义数据的MetaData

1.1:用SQLite实现自定义contentProvider的metadata需要做以下四步:1,定义authority;2,定义外部访问的Uri;3,定义访问时的MIME;4,定义数据库表相关的信息

package com.yihua;

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

public interface MemberProviderMetaData {
	//1,定义authority,google官方建议由packageName + className
	//For example, if your Android package name is com.example.<appname>, you should give your provider the authority com.example.<appname>.provider.
	public static final String AUTHORITY = "com.yihua.memberprovider";
	
	public static final String DB_NAME = "cp.db";
	
	public interface MemberMetaData extends BaseColumns {
		public static final String TABLE_NAME = "member";
		//2,定义Uri,google官方建议由authority +  / + tableName
		//Content URIs include the symbolic name of the entire provider (its authority) and a name that points to a table or file (a path)
		public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
		//3,定义访问的MIME类型,google官方建议authority + tableName
		public static final String MEMBER_LIST = "vnd.android.cursor.dir/vnd.com.yihua.memberprovider.member";
		public static final String MEMBER_ITEM = "vnd.android.cursor.item/vnd.com.yihua.memberprovider.member";
		//4,定义数据库表相关的信息
		public static final String NAME = "name";
		public static final String AGE = "age";
		public static final String SORT_ORDER = "name desc";
	}
}
1.2定义SQLiteOpenHelper的实现类MySQLiteOpenHelper

package com.yihua;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

	public MySQLiteOpenHelper(Context context) {
		super(context, MemberProviderMetaData.DB_NAME, null, 1);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		String sql = " create table   " + MemberProviderMetaData.MemberMetaData.TABLE_NAME 
				 + " (  " + MemberProviderMetaData.MemberMetaData._ID + "   INTEGER PRIMARY KEY,  "
				 + MemberProviderMetaData.MemberMetaData.NAME + "   VARCHAR NOT NULL,   "
				 + MemberProviderMetaData.MemberMetaData.AGE + "    INTEGER NOT NULL  "
				 + ")";
		db.execSQL(sql);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		String sql = "  DROP TABLE IF EXISTS   " + MemberProviderMetaData.MemberMetaData.TABLE_NAME;
		db.execSQL(sql);
		onCreate(db);
	}

}

第二,三步,继承contentProvider类并覆写6个方法

package com.yihua;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;

public class MemberProvider extends ContentProvider {
	private static UriMatcher uriMatcher = null;
	private static final int GET_MEMBER_LIST = 1;
	private static final int GET_MEMBER_ITEM = 2;

	private MySQLiteOpenHelper db;
	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(MemberProviderMetaData.AUTHORITY,
				MemberProviderMetaData.MemberMetaData.TABLE_NAME,
				GET_MEMBER_LIST);
		uriMatcher.addURI(MemberProviderMetaData.AUTHORITY,
				MemberProviderMetaData.MemberMetaData.TABLE_NAME + "/#",
				GET_MEMBER_ITEM);
	}

	@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {
		case GET_MEMBER_LIST:
			return MemberProviderMetaData.MemberMetaData.MEMBER_LIST;
		case GET_MEMBER_ITEM:
			return MemberProviderMetaData.MemberMetaData.MEMBER_ITEM;
		default:
			throw new IllegalArgumentException("uri can not match!  " + uri);
		}
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		switch (uriMatcher.match(uri)) {
		case GET_MEMBER_LIST:
			return this.db.getWritableDatabase().delete(MemberProviderMetaData.MemberMetaData.TABLE_NAME, selection, selectionArgs);
		case GET_MEMBER_ITEM:
			return this.db.getWritableDatabase().delete(MemberProviderMetaData.MemberMetaData.TABLE_NAME, selection, selectionArgs);
		default:
			throw new IllegalArgumentException("uri can not match!  " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		switch (uriMatcher.match(uri)) {
		case GET_MEMBER_LIST:
			long id = this.db.getWritableDatabase().insert(
					MemberProviderMetaData.MemberMetaData.TABLE_NAME, null,
					values);
			if (id > 0) {
				Uri insertUri = ContentUris.withAppendedId(uri, id);
				getContext().getContentResolver().notifyChange(insertUri, null);
				return insertUri;
			}
		case GET_MEMBER_ITEM:
			return null;
		default:
			throw new IllegalArgumentException("uri can not match!  " + uri);
		}
	}

	@Override
	public boolean onCreate() {
		this.db = new MySQLiteOpenHelper(super.getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		switch (uriMatcher.match(uri)) {
		case GET_MEMBER_LIST:
			return this.db.getReadableDatabase().query(MemberProviderMetaData.MemberMetaData.TABLE_NAME, null, selection, selectionArgs, null, null, null);
		case GET_MEMBER_ITEM:
			return this.db.getReadableDatabase().query(MemberProviderMetaData.MemberMetaData.TABLE_NAME, null, selection, selectionArgs, null, null, null);
		default:
			throw new IllegalArgumentException("uri can not match!  " + uri);
		}
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		switch (uriMatcher.match(uri)) {
		case GET_MEMBER_LIST:
			return this.db.getWritableDatabase().update(MemberProviderMetaData.MemberMetaData.TABLE_NAME, values, selection, selectionArgs);
		case GET_MEMBER_ITEM:
			return this.db.getWritableDatabase().update(MemberProviderMetaData.MemberMetaData.TABLE_NAME, values, selection, selectionArgs);
		default:
			throw new IllegalArgumentException("uri can not match!  " + uri);
		}
	}

}
第四步:在AndroidManifest.xml中配置我们自定义的contentProvider

        <provider android:name=".MemberProvider" android:authorities="com.yihua.memberprovider"/>

OK,大功告成,可以在Activity中使用我们自定义的contentProvider了。

package com.yihua;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MainActivity extends Activity {
	private Button insert = null;
	private Button delete = null;
	private Button update = null;
	private Button query = null;
	private ListView listView = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		insert = (Button) findViewById(R.id.insert);
		insert.setOnClickListener(new InsertOnClickListener());
		delete = (Button) findViewById(R.id.delete);
		update = (Button) findViewById(R.id.update);
		query = (Button) findViewById(R.id.query);
		delete.setOnClickListener(new DeleteOnClickListener());
		update.setOnClickListener(new UpdateOnClickListener());
		query.setOnClickListener(new QueryOnClickListener());
		listView = (ListView) findViewById(R.id.listView);
	}

	private class DeleteOnClickListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			String id = "2";
			// TextUtils.isEmpty()当字符串是空或者长度为0时返回true
			int deleteNum = 0;
			if (TextUtils.isEmpty(id)) {
				deleteNum = getContentResolver().delete(
						MemberProviderMetaData.MemberMetaData.CONTENT_URI,
						null, null);
			} else {
				deleteNum = getContentResolver()
						.delete(ContentUris.withAppendedId(
								MemberProviderMetaData.MemberMetaData.CONTENT_URI,
								Long.parseLong(id)), "_id=?",
								new String[] { id });
			}
			Toast.makeText(MainActivity.this, deleteNum + "", Toast.LENGTH_LONG)
					.show();
		}
	}

	private class UpdateOnClickListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			String id = "3";
			ContentValues values = new ContentValues();
			values.put(MemberProviderMetaData.MemberMetaData.NAME, "wangwu");
			values.put(MemberProviderMetaData.MemberMetaData.AGE, 20);
			String where = "_id=?";
			String[] selectionArgs = new String[] { id };
			if (TextUtils.isEmpty(id)) {
				getContentResolver().update(
						MemberProviderMetaData.MemberMetaData.CONTENT_URI,
						values, null, null);
			} else {
				getContentResolver()
						.update(ContentUris.withAppendedId(
								MemberProviderMetaData.MemberMetaData.CONTENT_URI,
								Long.parseLong(id)), values, where,
								selectionArgs);
			}
		}
	}

	private class QueryOnClickListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			String id = "";
			String[] projection = new String[] {
					MemberProviderMetaData.MemberMetaData._ID,
					MemberProviderMetaData.MemberMetaData.NAME,
					MemberProviderMetaData.MemberMetaData.AGE };
			String selection = "_id=?";
			String[] selectionArgs = new String[] { id };
			Cursor cursor = null;
			if (TextUtils.isEmpty(id)) {
				cursor = getContentResolver().query(
						MemberProviderMetaData.MemberMetaData.CONTENT_URI,
						projection, null, null,
						MemberProviderMetaData.MemberMetaData.SORT_ORDER);
			} else {
				cursor = getContentResolver()
						.query(ContentUris.withAppendedId(
								MemberProviderMetaData.MemberMetaData.CONTENT_URI,
								Long.parseLong(id)), projection, selection,
								selectionArgs, null);
			}
			MainActivity.this.startManagingCursor(cursor);
			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor
					.moveToNext()) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put(MemberProviderMetaData.MemberMetaData._ID,
						cursor.getInt(cursor
								.getColumnIndex(MemberProviderMetaData.MemberMetaData._ID)));
				map.put(MemberProviderMetaData.MemberMetaData.NAME,
						cursor.getString(cursor
								.getColumnIndex(MemberProviderMetaData.MemberMetaData.NAME)));
				map.put(MemberProviderMetaData.MemberMetaData.AGE,
						cursor.getInt(cursor
								.getColumnIndex(MemberProviderMetaData.MemberMetaData.AGE)));
				list.add(map);
			}
			SimpleAdapter sa = new SimpleAdapter(MainActivity.this, list, R.layout.member, new String[]{"_id", "name", "age"}, new int[]{R.id._id, R.id.name, R.id.age});
			listView.setAdapter(sa);
		}
	}

	private class InsertOnClickListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			ContentValues values = new ContentValues();
			values.put(MemberProviderMetaData.MemberMetaData.NAME, "lisi");
			values.put(MemberProviderMetaData.MemberMetaData.AGE, 22);
			Uri uri = getContentResolver().insert(
					MemberProviderMetaData.MemberMetaData.CONTENT_URI, values);
			Toast.makeText(MainActivity.this, uri.toString(), Toast.LENGTH_LONG)
					.show();
		}

	}
}

呵呵,布局文件我就不贴上来了。比较简单。现在已经够长的了。源代码从我的上传资源文件中可以下载到。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值