通过之前的讲解,对ContentProvider有了比较全面的理解。那么如何创建ContentProvider呢?一般情况下,程序开发人员在创建自己的ContentProvider的过程可以分为以下三步。
(1)首先,继承ContentProvider类,并覆盖ContentProvider的抽6个抽象方法。新建立的类继承ContentProvider后,需覆盖的6个方法如下。
□ public boolean onCreate(),当ContentProvider 生成时调用此方法,主要实现初始化底层数据集和建立数据链接等工作。
□ public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) ,此方法返回一个Cursor 对象作为查询结果集。
□ public Uri insert(Uri uri, ContentValues initialValues),此方法负责往数据集当中插入一列,并返回这一列的Uri。
□ public int delete(Uri uri, String where, String[] whereArgs),此方法负责删除指定Uri 的数据。
□ public int update(Uri uri, ContentValues values, String where,String[] whereArgs) ,此方法负责更新指定Uri 的数据。
□ public String getType(Uri uri) ,返回所给Uri 的MIME 类型,如果Uri是单条数据,则返回的MIME数据类型应以vnd.android.cursor.item开头;如果Uri是多条数据,则返回的MIME数据类型应以vnd.android.cursor.dir/开头。
新建立的类继承ContentProvider后,Eclipse会提示程序开发人员需要覆盖部分代码,并自动生成需要覆盖的代码框架。代码清单7-48所示的代码是Eclipse自动生成的代码框架。
代码清单7-48 继承ContentProvider后的代码框架
import android.content.*;
import android.database.Cursor;
import android.net.Uri;
public class PeopleProvider extends ContentProvider{
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public oolean onCreate() {
// TODO Auto-generated method stub
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
}
(2)声明CONTENT_URI,实现UriMatcher。
在上一步中,知道在返回所给Uri 的MIME 类型即实现getType(Uri uri)时,需通过Uri是单条数据还是多条数据来确认其返回的MIME数据类型。在新构造的ContentProvider类中,通过构造一个UriMatcher,判断Uri是单条数据还是多条数据。为了便于判断和使用Uri,一般将Uri的授权者名称和数据路径等内容声明为静态常量,并声明CONTENT_Uri。
声明CONTENT_Uri和构造UriMatcher的代码如代码清单7-49所示。
代码清单7-49 声明CONTENT_URI和构造UriMatcher
//声明了Uri的授权者名称
public static final String AUTHORITY = "cn.com.farsight.peopleprovider";
//声明了单条数据的数据路径
public static final String PATH_SINGLE = "people/#";
//声明了多条数据的数据路径
public static final String PATH_MULTIPLE = "people";
//声明了CONTENT_URI的字符串形式
public static final String CONTENT_URI_STRING = "content://" +
AUTHORITY + "/" + PATH_MULTIPLE;
//声明了CONTENT_URI
public static final Uri CONTENT_URI = Uri.parse
(CONTENT_URI_STRING);
//声明了多条数据的返回代码
private static final int MULTIPLE_PEOPLE = 1;
//声明了单条数据的返回代码
private static final int SINGLE_PEOPLE = 2;
//声明了UriMatcher
private static final UriMatcher uriMatcher;
//静态构造方法,声明了UriMatcher的匹配方式和返回代码
static {
// UriMatcher.NO_MATCH表示Uri无匹配时的返回代码
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//addURI()方法用来添加新的匹配项
uriMatcher.addURI(AUTHORITY, PATH_SINGLE, MULTIPLE_PEOPLE);
uriMatcher.addURI(AUTHORITY, PATH_MULTIPLE, SINGLE_PEOPLE);
}
其中,addURI()方法用来添加新的匹配项,语法如代码清单7-50所示。
代码清单7-50 addURI()方法语法
public void addURI (String authority, String path, int code)
其中,authority表示匹配的授权者名称;path表示数据路径,#可以代表任何数字;code表示返回代码。
使用UriMatcher时,则可以直接调用match()方法,对指定的Uri进行判断,示例代码如代码清单7-51所示。
代码清单7-51 调用match()方法,对指定的URI进行判断
switch(uriMatcher.match(uri)){
case MULTIPLE_PEOPLE:
//多条数据的处理过程
break;
case SINGLE_PEOPLE:
//单条数据的处理过程
break;
default:
throw new IllegalArgumentException("不支持的URI:" + uri);
}
(3)注册ContentProvider。
在完成ContentProvider类的代码实现后,需要在AndroidManifest.xml文件中进行注册。注册ContentProvider使用<provider>标签,例如,注册了一个授权者名称为cn.com.farsight.peopleprovider的ContentProvider,其实现类是PeopleProvider的示例代码如代码清单7-52所示。
代码清单7-52 注册ContentProvider
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<provider android:name =".PeopleProvider"
android:authorities ="cn.com.farsight.peopleprovider"/>
</application>