ContentProvider总是需要与ContentResolver结合使用,它们之间的关系是:
Context提供了getContentResolver()方法,这个表示Activity、Service等组件都可通过getContentResolver()方法获取ContentResolver对象。
获取了ContentResolver对象之后,接下来就可以调用ContentResolver的query()、insert()、update()和delete()方法
——实际上指定Uri对应的ContentProvider的query()、insert()、update()和delete()
从mars视频学习的例程,主要是在数据库中增加和查询数据
CPActivity.java
public class CPActivity extends Activity {
public Button queryButton = null;
public Button insertButton = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
queryButton = (Button)findViewById(R.id.query);
insertButton = (Button)findViewById(R.id.insert);
queryButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Cursor c = getContentResolver().query(
FirstProviderMetaData.UserTableMetaData.CONTENT_URI, null,
null, null, null);
while(c.moveToNext()){
System.out.println(c.getString(c.getColumnIndex(UserTableMetaData.USER_NAME)));
}
}
});
insertButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME, "zhangsan");
Uri uri = getContentResolver().insert(FirstProviderMetaData.UserTableMetaData.CONTENT_URI, values);
System.out.println("uri-->"+uri.toString());
}
});
System.out.println(getContentResolver().getType(FirstProviderMetaData.UserTableMetaData.CONTENT_URI));
}
}
FirstContentProvider.java 重写ContentProvider类的query()、insert()方法
public class FirstContentProvider extends ContentProvider {
public static final UriMatcher uriMatcher;//对URI的参数进行判断,是否符合标准,确定该ContentProvider实际能处理的URI
public static final int INCOMING_USER_COLLECTION = 1;
public static final int INCOMING_USER_SINGLE = 2;
private DatabaseHelper dh;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(FirstProviderMetaData.AUTHORITY,"/users",INCOMING_USER_COLLECTION);
uriMatcher.addURI(FirstProviderMetaData.AUTHORITY, "/users/#", INCOMING_USER_SINGLE);
}
public static HashMap<String,String> userProjectionMap;
static{
userProjectionMap = new HashMap<String,String>();
userProjectionMap.put(UserTableMetaData._ID, UserTableMetaData._ID);
userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
}
//是一个回调函数,在contentProvider创建的时候执行
@Override
public boolean onCreate() {
//打开数据库
dh = new DatabaseHelper(getContext(), FirstProviderMetaData.DATABASE_NAME);
System.out.println("onCreate");
return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
//根据传入的URI,返回该URI所表示的数据类型
@Override
public String getType(Uri uri) {
System.out.println("getType");
switch(uriMatcher.match(uri)){
case INCOMING_USER_COLLECTION:
return UserTableMetaData.CONTENT_TYPE;
case INCOMING_USER_SINGLE:
return UserTableMetaData.CONTENT_TYPE_ITEM;
default:
throw new IllegalArgumentException("Unknown URI" + uri);
}
}
/**
* 该函数的返回值是一个uri,这个uri表示的是刚刚使用这个函数所插入的数据
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
System.out.println("insert");
SQLiteDatabase db = dh.getWritableDatabase();
long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
if(rowId > 0){
Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
//通知监听器,数据已经改变
getContext().getContentResolver().notifyChange(insertedUserUri, null);
return insertedUserUri;
}
throw new SQLException("Failed to insert row into" + uri);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch(uriMatcher.match(uri)){
case INCOMING_USER_COLLECTION:
qb.setTables(UserTableMetaData.TABLE_NAME);
qb.setProjectionMap(userProjectionMap);
break;
case INCOMING_USER_SINGLE:
qb.setTables(UserTableMetaData.TABLE_NAME);
qb.setProjectionMap(userProjectionMap);
qb.appendWhere(UserTableMetaData._ID+"=" + uri.getPathSegments().get(1));
break;
}
String orderBy;
if(TextUtils.isEmpty(sortOrder)){
orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;
}else{
orderBy = sortOrder;
}
SQLiteDatabase db = dh.getWritableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
c.setNotificationUri(getContext().getContentResolver(), uri);
System.out.println("query");
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
}
public class FirstProviderMetaData {
public static final String AUTHORITY = "com.mars.testcp.FirstContentProvider";
public static final String DATABASE_NAME = "FirstProvider.db";
public static final int DATABASE_VERSION = 1;
public static final String USERS_TABLE_NAME = "users";
//定义一个静态内部类 定义该ContentProvider所包含的数据列的列名
public static final class UserTableMetaData implements BaseColumns{
//表名
public static final String TABLE_NAME = "users";
//访问该ContentProvider的URI
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/users");
//该ContentProvider所返回的数据类型的定义,参考帮助文档
//整张表的数据
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/nvd.firstprovider.user";
//表中的一条数据
public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/nvd.firstprovider.user";
//列名
public static final String USER_NAME = "name";
//默认的排序方法
public static final String DEFAULT_SORT_ORDER = "_id desc";
}
}
DatabaseHelper.java 创建数据库文件
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int VERSION = 1;
//在SQLiteOepnHelper的子类当中,必须有该构造函数
public DatabaseHelper(Context context, String name, CursorFactory factory,
int version) {
//必须通过super调用父类当中的构造函数
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
public DatabaseHelper(Context context, String name) {
this(context, name, VERSION);
// TODO Auto-generated constructor stub
}
public DatabaseHelper(Context context,String name,int version){
this(context,name,null,version);
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
System.out.println("create a Database");
//execSQL函数用于执行SQL语句,创建一个表名为user,有两列数据id、name
db.execSQL("create table "+ FirstProviderMetaData.USERS_TABLE_NAME
+ "(" + FirstProviderMetaData.UserTableMetaData._ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ FirstProviderMetaData.UserTableMetaData.USER_NAME
+ " varchar(20));");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
System.out.println("update a Database");
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mars.testcp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.mars.testcp.CPActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name = "com.mars.testcp.FirstContentProvider"
android:authorities="com.mars.testcp.FirstContentProvider" />
</application>
</manifest>