在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();
}
}
}
呵呵,布局文件我就不贴上来了。比较简单。现在已经够长的了。源代码从我的上传资源文件中可以下载到。