Content Provider
Content Provider的几个抽象方法:
Query(Uri,String[],String,String[],String)查询
Insert(Uri,ContentValues)插入
Update(Uri,ContentValues,String,String[])更新
Delete(Uri,String,String[]);
getType(Uri);获得MIME数据类型
ContentResolver
ContentResolver中提供和ContentProvider中对应的方法,我们是间接的通过操作ContentResolver来操作ContentProvider,一般情况下,ContentProvider是单实例的,而ContentResolver可以有多个
URI
ContentProvider是通过URI来共享其数据。一个URI必须以“content://”开头接下来是URI授权的部分,这部分内容与AndroidManifest.xml配置文件中声明的授权内容一致,后面还可能有数据类型和记录ID。
查询系统ContentProvider内容
步骤:
1. 通过对应getContentResolver()方法,获取ContentResolver对象。
2. 获取ContentProvider的URI标示
3. 列出想要查询的URI标示
4. 调用ContentResolver的query方法来执行查询。
添加系统ContentProvider内容
步骤:
5. 通过对应getContentResolver()方法,获取ContentResolver对象。
6. 获取ContentProvider的URI标示
7. 把添加的信息封装到ContentValues对象中
8. 调用ContentResolver的insert方法来执行添加
9.
。
自定义ContentProvider
创建ContentProvider的步骤:
1. 创建保存数据的文件或数据库
2. 定义一个类继承ContentProvider,实现其抽象方法
3. 将定义好的ContentProvider在AndroidMainfest.xml配置文件中声明,以便使用。
下面开始代码实例:
1package com.king.android.controls;
3 import android.net.Uri;
4 import android.provider.BaseColumns;
5
6 /**
7
8 * 描述:实体类。
9 * 作者:Andy.Liu
10 * 时间: 2012-7-20 上午08:19:51
11 **/
12 public class Employees {
13 // 授权常量
14 public static final String AUTHORITY = "com.king.provider.Employees";
15 private Employees() {}
16 // 内部类
17 public static final class Employee implements BaseColumns {
18 // 构造方法
19 private Employee() {}
20 // 访问Uri
21 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/employee");
22 // 内容类型
23 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.king.employees";
24 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.king.employees";
25
26 // 默认排序常量
27 public static final String DEFAULT_SORT_ORDER = "name DESC";// 按姓名排序
28 // 表字段常量
29 public static final String NAME = "name"; // 姓名
30 public static final String GENDER= "gender"; // 性别
31 public static final String AGE = "age"; // 年龄
32 }
33
34 }
数据库创建:
1 package com.king.android.controls;
3 import android.content.Context;
4 import android.database.sqlite.SQLiteDatabase;
5 import android.database.sqlite.SQLiteOpenHelper;
6
7 import com.king.android.controls.Employees.Employee;
8
9 /**
10
11 * 描述:数据库操作工具类
12 * 作者:Andy.Liu
13 * 时间: 2012-7-20 上午08:22:54
14 **/
15 public class DBHelper extends SQLiteOpenHelper {
16 private static final String DATEBASE_NAME = "Employee.db";
17 private static final int DATAVASE_VERSION = 1;
18 public static final String EMPLOYEE_TABLE_NAME = "employee";
19 private static final String EMPLOYEE_TABLE_CREATE = "CREATE TABLE "
20 + EMPLOYEE_TABLE_NAME + " (" + Employee._ID
21 + " INTEGER PRIMARY KEY," + Employee.NAME + " TEXT,"
22 + Employee.GENDER + " TEXT," + Employee.AGE + " INTEGER" + ")";
23
24 //创建数据库
25 public DBHelper(Context context) {
26 super(context, DATEBASE_NAME, null, DATAVASE_VERSION);
27
28 }
29
30 @Override//创建时调用
31 public void onCreate(SQLiteDatabase db) {
32 db.execSQL(EMPLOYEE_TABLE_CREATE);
33 }
34
35 @Override//版本更新时调用
36 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
37 db.execSQL("DROP TABLE IF EXISTS "+ EMPLOYEE_TABLE_NAME);
38 onCreate(db);
39 }
40
41 }
创建EmployeeProvider ,待续。。。。 package com.king.android.controls;
import java.util.HashMap;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import com.king.android.controls.Employees.Employee;
/**
* 描述:ContentProvider具体使用
* 作者:Andy.Liu
* 时间: 2012-7-20 上午08:39:26
**/
public class EmployeeProvider extends ContentProvider {
private DBHelper mDBHelper;
//Uri工具类
private static UriMatcher sUriMather = null;
//查询更新条件
private static final int EMPLOYEE = 1;
private static final int EMPLOYEE_ID = 2;
//查询列集合
private static HashMap<String,String> empProjectionMap;
static{
sUriMather = new UriMatcher(UriMatcher.NO_MATCH);
sUriMather.addURI(Employees.AUTHORITY, "employee", EMPLOYEE);
sUriMather.addURI(Employees.AUTHORITY, "employee/#", EMPLOYEE_ID);
//实例化查询列集合
empProjectionMap= new HashMap<String, String>();
//添加查询列
empProjectionMap.put(Employee._ID, Employee._ID);
empProjectionMap.put(Employee.NAME, Employee.NAME);
empProjectionMap.put(Employee.GENDER, Employee.GENDER);
empProjectionMap.put(Employee.AGE, Employee.AGE);
}
@Override
public boolean onCreate() {
mDBHelper = new DBHelper(getContext());
return true;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
//添加数据库实例
SQLiteDatabase db = mDBHelper.getWritableDatabase();
//插入数据,返回行ID
long rowId = db.insert(DBHelper.EMPLOYEE_TABLE_NAME, Employee.NAME, values);
//如果插入成功后返回Uri
if(rowId>0){
Uri empUri = ContentUris.withAppendedId(Employee.CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(empUri, null);
return empUri;
}
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
//添加数据库实例
SQLiteDatabase db = mDBHelper.getWritableDatabase();
int count;
switch(sUriMather.match(uri)){
case EMPLOYEE:
count = db.delete(DBHelper.EMPLOYEE_TABLE_NAME, selection, selectionArgs);
break;
case EMPLOYEE_ID:
String noteId = uri.getPathSegments().get(1);
count = db.delete(DBHelper.EMPLOYEE_TABLE_NAME, Employee._ID + "="+noteId+(!TextUtils.isEmpty(selection)?" AND ("+selection+')':""), selectionArgs);
break;
default:
throw new IllegalArgumentException("错误的Uri "+uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch(sUriMather.match(uri)){
//查询所有
case EMPLOYEE:
qb.setTables(DBHelper.EMPLOYEE_TABLE_NAME);
qb.setProjectionMap(empProjectionMap);
break;
//根据ID查询
case EMPLOYEE_ID:
qb.setTables(DBHelper.EMPLOYEE_TABLE_NAME);
qb.setProjectionMap(empProjectionMap);
qb.appendWhere(Employee._ID+"="+uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException("错误的Uri "+uri);
}
//使用默认排序
String orderBy;
if(TextUtils.isEmpty(sortOrder)){
orderBy = Employee.DEFAULT_SORT_ORDER;
}else{
orderBy = sortOrder;
}
//获得数据库实例
SQLiteDatabase db = mDBHelper.getReadableDatabase();
//返回游标集合
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
//更新方法
@Override
public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
//添加数据库实例
SQLiteDatabase db = mDBHelper.getWritableDatabase();
int count;
switch(sUriMather.match(uri)){
case EMPLOYEE:
count = db.update(DBHelper.EMPLOYEE_TABLE_NAME,values, selection, selectionArgs);
break;
case EMPLOYEE_ID:
String noteId = uri.getPathSegments().get(1);
count = db.update(DBHelper.EMPLOYEE_TABLE_NAME,values, Employee._ID + "="+noteId+(!TextUtils.isEmpty(selection)?" AND ("+selection+')':""), selectionArgs);
break;
default:
throw new IllegalArgumentException("错误的Uri "+uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
测试部分:package com.king.android.controls;
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.util.Log;
import android.widget.Toast;
import com.king.android.R;
import com.king.android.controls.Employees.Employee;
/**
* 描述:测试Content Provider
* 作者:Andy.Liu
* 时间: 2012-7-22 下午04:46:19
**/
public class ProviderActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
insert();
query();
update();
query();
delete();
query();
}
private void delete(){
//删除ID为1的记录
Uri uri = ContentUris.withAppendedId(Employee.CONTENT_URI, 1);
//获得ContentResolver,并删除
getContentResolver().delete(uri, null, null);
}
private void update(){
//更新ID为1的记录
Uri uri = ContentUris.withAppendedId(Employee.CONTENT_URI, 1);
ContentValues cv = new ContentValues();
cv.put(Employee.NAME, "king.liu");
cv.put(Employee.GENDER, "male");
cv.put(Employee.AGE, 50);
getContentResolver().update(uri, cv, null, null);
}
private void query(){
//查询列数据
String[] projeciton = new String[]{
Employee._ID,
Employee.NAME,
Employee.GENDER,
Employee.AGE,
};
//查询所有备忘录信息
Cursor c =managedQuery(Employee.CONTENT_URI, projeciton, null, null, Employee.DEFAULT_SORT_ORDER);
//判断是否为空
if(c.moveToFirst()){
//遍历游标
for(int i = 0;i<c.getCount();i++){
c.moveToPosition(i);
//获得姓名
String name = c.getString(1);
String gender = c.getString(2);
int age = c.getInt(3);
Log.i("provider", name+":"+gender+":"+age);
Toast.makeText(ProviderActivity.this, "输出:name:=="+name+"gender=="+gender+"age=="+age, Toast.LENGTH_LONG).show();
}
}
}
private void insert(){
//更新ID为1的记录
Uri uri = Employee.CONTENT_URI;
ContentValues cv = new ContentValues();
cv.put(Employee.NAME, "king.liu");
cv.put(Employee.GENDER, "male");
cv.put(Employee.AGE, 20);
getContentResolver().insert(uri, cv);
}
}
注意:注册使用provider一定要在AndroidManifest.xml注册:
<!--end Content Provider -->
运行效果如下: