ContentProvider小结
ContentProvider,android四大组件之一,用于对外提供数据操作的接口,通常情况下,我们是结合android的SQLite数据库来对应提供数据接口的,当然,数据不一定非要来自于数据库,也可以是文件。在编写ContentProvider的时候,通常需要用到的实例对象有:Uri,UriMatcher,ContentUris,ContentResolver。
1.Uri
Uri类用于定义ContentProvider的访问路径,类似于网站的网址,Uri由三部分组成,即:content:// + authority + path,如:content://com.jackie.providers.personprovider/person,创建Uri实例的语句如下:
Uri uri = Uri.parse("content://com.jackie.providers.personprovider/person");
2.UriMatcher
UriMatcher是用匹配Uri是否符合我们定义的格式,如下:
private UriMatcher matcher;
static {
matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(PersonUtil.AUTHORITY, "person", 1);
matcher.addURI(PersonUtil.AUTHORITY, "person/#", 2);
}
3.ContentUris
ContentUris用于操作uri,它有两个方法:withAppendedId(uri,id),parseId(uri),从方法的定义上,我们知道withAppendedId(uri,id)用往uri添加id,而parseId这是解析uri中的id。
4.ContentResolver
ContentResolver用于客户端,它用来操作ContentProvider,同样,ContentResolver提供了与ContentProvider一致的方法。
下面是一个简单的实例:
1、person实体类
public class Person {
public int id;
public String name;
public int age;
public Person() {
}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
}
2、person对应的数据库操作
package com.jackie.util;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.jackie.domain.Person;
public class PersonDBUtil extends SQLiteOpenHelper{
public static final String TABLE_NAME = "person";
public static final int VERSION = 1;
public PersonDBUtil(Context context) {
super(context, TABLE_NAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
StringBuffer person_sql = new StringBuffer();
person_sql.append("create table person ( _id integer primary key autoincrement,");
person_sql.append("name varchar(30), age integer)");
db.execSQL(person_sql.toString());
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
/**
* 插入person记录
* @param person
*/
public void insertPerson(Person person){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", person.name);
values.put("age", person.age);
db.insert(TABLE_NAME, null, values);
}
/**
* 获取person列表
* @return
*/
public List<Person> getPersons() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, null, null, null, null, null, null);
List<Person> list = new ArrayList<Person>();
while(cursor.moveToNext()) {
Person person = new Person();
person.id = cursor.getInt(cursor.getColumnIndex("_id"));
person.name = cursor.getString(cursor.getColumnIndex("name"));
person.age = cursor.getInt(cursor.getColumnIndex("age"));
list.add(person);
}
return list;
}
/**
* 获取person
* @param id
* @return
*/
public Person getPersonById(int id){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, null, "_id=?", new String[]{id + ""}, null, null, null);
Person person = new Person();
while(cursor.moveToNext()) {
person.id = cursor.getInt(cursor.getColumnIndex("_id"));
person.name = cursor.getString(cursor.getColumnIndex("name"));
person.age = cursor.getInt(cursor.getColumnIndex("age"));
break;
}
return person;
}
/**
* 更新person
* @param person
*/
public void updatePerson(Person person){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", person.name);
values.put("age", person.age);
db.update(TABLE_NAME, values, "_id=?", new String[]{person.id + ""});
}
/**
* 删除person
* @param id
*/
public void deletePersonById(int id) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, "_id=?", new String[]{id + ""});
}
}
3、person工具类
package com.jackie.util;
import android.net.Uri;
public class PersonUtil {
public static final String AUTHORITY = "com.jackie.providers.personprovider";
public static final int PERSONS = 1;
public static final int PERSON = 2;
public static final String PERSON_TYPE = "vnd.android.cursor.dir/com.jackie.providers.personprovider";
public static final String PERSON_ITEM_TYPE = "vnd.android.cursor.item/com.jackie.providers.personprovider";
public static final Uri PERSON_URI = Uri.parse("content://" + AUTHORITY + "/person");
}
4、person的ContentProvider类
package com.jackie.providers;
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.net.Uri;
import android.text.TextUtils;
import com.jackie.util.PersonDBUtil;
import com.jackie.util.PersonUtil;
public class PersonProvider extends ContentProvider{
private static UriMatcher matcher;
private static ContentUris contentUris;
private PersonDBUtil util;
private SQLiteDatabase db;
private String tableName ;
static {
matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(PersonUtil.AUTHORITY, "person", PersonUtil.PERSONS);
matcher.addURI(PersonUtil.AUTHORITY, "person/#", PersonUtil.PERSON);
}
@Override
public boolean onCreate() {
contentUris = new ContentUris();
util = new PersonDBUtil(this.getContext());
db = util.getWritableDatabase();
tableName = util.TABLE_NAME;
return false;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
switch (matcher.match(uri)) {
case PersonUtil.PERSONS:
count = db.delete(tableName, selection, selectionArgs);
break;
case PersonUtil.PERSON:
long id = contentUris.parseId(uri);
String whereClause = "_id = " + id + (!TextUtils.isEmpty(selection)? " AND " + selection : "");
count = db.delete(tableName, whereClause, selectionArgs);
break;
default:
new IllegalArgumentException("Unknown Uri : " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch(matcher.match(uri)){
case PersonUtil.PERSONS:
return PersonUtil.PERSON_TYPE;
case PersonUtil.PERSON:
return PersonUtil.PERSON_ITEM_TYPE;
default:
new IllegalArgumentException("Unknown Uri : " + uri);
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowId;
Uri contentUri = null;
switch(matcher.match(uri)){
case PersonUtil.PERSONS:
rowId =db.insert(tableName, null, values);
if(rowId > 0) {
contentUri = ContentUris.withAppendedId(uri, rowId);
getContext().getContentResolver().notifyChange(contentUri, null);
}
break;
default:
new IllegalArgumentException("Unknown uri:" + uri);
}
return contentUri;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Cursor cursor = null ;
switch(matcher.match(uri)) {
case PersonUtil.PERSONS:
cursor = db.query(tableName, projection, selection, selectionArgs, null, null, null);
break;
case PersonUtil.PERSON:
long id = contentUris.parseId(uri);
String whereClause = "_id=" + id + ( !TextUtils.isEmpty(selection) ? " AND " + selection : "");
cursor = db.query(tableName, projection, whereClause, selectionArgs, null, null, null);
default:
new IllegalArgumentException("Unknown uri:" + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int rowId = 0;
switch(matcher.match(uri)){
case PersonUtil.PERSONS:
rowId = db.update(tableName, values, selection, selectionArgs);
break;
case PersonUtil.PERSON:
long id = ContentUris.parseId(uri);
String whereClause = "_id=" + id + ( !TextUtils.isEmpty(selection)?" AND " + selection : "");
rowId = db.update(tableName, values, whereClause, selectionArgs);
break;
default:
new IllegalArgumentException("Unknown uri : " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowId;
}
}
5、ContentResolver
package com.jackie.contentprovider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.test.AndroidTestCase;
import com.jackie.util.PersonUtil;
public class ContentResolverTest extends AndroidTestCase {
public void insert(){
ContentResolver resolver = getContext().getContentResolver();
ContentValues values = new ContentValues();
values.put("name", "aaa");
values.put("age", 12);
resolver.insert(PersonUtil.PERSON_URI, values);
}
public void query(){
ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = resolver.query(PersonUtil.PERSON_URI, null, null, null, null);
while(cursor.moveToNext()) {
System.out.println("id:" + cursor.getInt(cursor.getColumnIndex("_id")) +
"\t name : " + cursor.getString(cursor.getColumnIndex("name")) +
"\t age : " + cursor.getInt(cursor.getColumnIndex("age")));
}
}
}
6、AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jackie.contentprovider"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:name="com.jackie.providers.PersonProvider" android:authorities="com.jackie.providers.personprovider"/>
<uses-library android:name="android.test.runner"/>
</application>
<instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.jackie.contentprovider" ></instrumentation>
</manifest>