
前言:现在这段时间没这么忙了,要抓紧时间把要总结的知识沉淀下来,今年重新分了项目组,在新项目中应该不会那么忙了,看来有时间来学一些自己的东西了。现在而言,我需要的是时间。只要不断的努力,总有一天,你会与从不同。加油。 1、《ContentProvider数
前言:现在这段时间没这么忙了,要抓紧时间把要总结的知识沉淀下来,今年重新分了项目组,在新项目中应该不会那么忙了,看来有时间来学一些自己的东西了。现在而言,我需要的是时间。只要不断的努力,总有一天,你会与从不同。加油。
1、《ContentProvider数据库共享之——概述》
2、《ContentProvider数据库共享之——实例讲解》
3、《ContentProvider数据库共享之——MIME类型与getType()》
4、《ContentProvider数据库共享之——读写权限与数据监听》
在上篇文章中,已经给大家初步讲解了有关ContentProvder的整体流程及设计方式,在这篇文章中将通过实例来讲述ContentProvider的操作过程;
在上篇中,我们提到过,两个应用间是通过Content URI来媒介传递消息的,我们的应用在收到URI以后,通过匹配完成对应的数据库操作功能。听的有点迷糊?没关系,下面会细讲,我这里要说的是,匹配成功后要完成的数据库操作!!!那好,我们的第一步:建数据库,数据表
在这里,我们在一个数据库(“harvic.db”)中创建两个数据表”first”与”second”;每个表都有多出一个字段“table_name”,来保存当前数据表的名称
代码如下:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "harvic.db";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_FIRST_NAME = "first";
public static final String TABLE_SECOND_NAME = "second";
public static final String SQL_CREATE_TABLE_FIRST = "CREATE TABLE " +TABLE_FIRST_NAME +"("
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "table_name" +" VARCHAR(50) default 'first',"
+ "name" + " VARCHAR(50),"
+ "detail" + " TEXT"
+ ");" ;
public static final String SQL_CREATE_TABLE_SECOND = "CREATE TABLE "+TABLE_SECOND_NAME+" ("
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "table_name" +" VARCHAR(50) default 'second',"
+ "name" + " VARCHAR(50),"
+ "detail" + " TEXT"
+ ");" ;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.e("harvic", "create table: " + SQL_CREATE_TABLE_FIRST);
db.execSQL(SQL_CREATE_TABLE_FIRST);
db.execSQL(SQL_CREATE_TABLE_SECOND);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS first");
db.execSQL("DROP TABLE IF EXISTS second");
onCreate(db);
}
}public class PeopleContentProvider extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
}public class PeopleContentProvider extends ContentProvider {
private static final UriMatcher sUriMatcher;
private static final int MATCH_FIRST = 1;
private static final int MATCH_SECOND = 2;
public static final String AUTHORITY = "com.harvic.provider.PeopleContentProvider";
public static final Uri CONTENT_URI_FIRST = Uri.parse("content://" + AUTHORITY + "/frist");
public static final Uri CONTENT_URI_SECOND = Uri.parse("content://" + AUTHORITY + "/second");
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(AUTHORITY, "first", MATCH_FIRST);
sUriMatcher.addURI(AUTHORITY, "second", MATCH_SECOND);
}
private DatabaseHelper mDbHelper;
@Override
public boolean onCreate() {
mDbHelper = new DatabaseHelper(getContext());
return false;
}
…………
}sUriMatcher.addURI(AUTHORITY, "first", MATCH_FIRST);
public void addURI (String authority, String path, int code)
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
下面先看看insert方法,主要功能为:当URI匹配content://com.harvic.provider.PeopleContentProvider/frist时,将数据插入first数据库
当URI匹配content://com.harvic.provider.PeopleContentProvider/second时,将数据插入second数据库
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
switch (sUriMatcher.match(uri)){
case MATCH_FIRST:{
long rowID = db.insert(DatabaseHelper.TABLE_FIRST_NAME, null, values);
if(rowID > 0) {
Uri retUri = ContentUris.withAppendedId(CONTENT_URI_FIRST, rowID);
return retUri;
}
}
break;
case MATCH_SECOND:{
long rowID = db.insert(DatabaseHelper.TABLE_SECOND_NAME, null, values);
if(rowID > 0) {
Uri retUri = ContentUris.withAppendedId(CONTENT_URI_SECOND, rowID);
return retUri;
}
}
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
return null;
}long rowID = db.insert(DatabaseHelper.TABLE_FIRST_NAME, null, values);
Uri retUri = ContentUris.withAppendedId(CONTENT_URI_FIRST, rowID);
在看了insert方法之后,update方法难度也不大,也是根据UriMatcher.match(uri)的返回值来判断当前与哪个URI匹配,根据匹配的URI来操作对应的数据库,代码如下:
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int count = 0;
switch(sUriMatcher.match(uri)) {
case MATCH_FIRST:
count = db.update(DatabaseHelper.TABLE_FIRST_NAME, values, selection, selectionArgs);
break;
case MATCH_SECOND:
count = db.update(DatabaseHelper.TABLE_SECOND_NAME, values, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknow URI : " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}至于query()方法就不再细讲了,跟上面的一样,根据不同的URI来操作不同的查询操作而已,代码如下:
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
switch (sUriMatcher.match(uri)) {
case MATCH_FIRST:
// 设置查询的表
queryBuilder.setTables(DatabaseHelper.TABLE_FIRST_NAME);
break;
case MATCH_SECOND:
queryBuilder.setTables(DatabaseHelper.TABLE_SECOND_NAME);
break;
default:
throw new IllegalArgumentException("Unknow URI: " + uri);
}
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, null);
return cursor;
}public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int count = 0;
switch(sUriMatcher.match(uri)) {
case MATCH_FIRST:
count = db.delete(DatabaseHelper.TABLE_FIRST_NAME, selection, selectionArgs);
break;
case MATCH_SECOND:
count = db.delete(DatabaseHelper.TABLE_SECOND_NAME, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknow URI :" + uri);
}
return count;
} public String getType(Uri uri) {
return null;
}在第三方应用中,我们要如何利用URI来执行共享数据数的操作呢,这是利用ContentResolver这个类来完成的。
获取ContentResolver实例的方法为:
ContentResolver cr = this.getContentResolver();
public final Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) public final Uri insert (Uri url, ContentValues values) public final int update (Uri uri, ContentValues values, String where, String[] selectionArgs) public final int delete (Uri url, String where, String[] selectionArgs)
新建一个工程,命名为“UseProvider”,界面长这个样子:
最上头有两个按钮,用来切换当前使用哪个URI来增、删、改、查操作;由于不同的URI会操作不同的数据表,所以我们使用不同的URI,会在不同的数据表中操作;
先列出来那两个要匹配的URI,以及全局当前要使用的URI(mCurrentURI ),mCurrentURI 默认是/first对应的URI,如果要切换,使用界面上最上头的那两个按钮来切换当前所使用的URI。
public static final String AUTHORITY = "com.harvic.provider.PeopleContentProvider";
public static final Uri CONTENT_URI_FIRST = Uri.parse("content://" + AUTHORITY + "/first");
public static final Uri CONTENT_URI_SECOND = Uri.parse("content://" + AUTHORITY + "/second");
public static Uri mCurrentURI = CONTENT_URI_FIRST;private void query() {
Cursor cursor = this.getContentResolver().query(mCurrentURI, null, null, null, null);
Log.e("test ", "count=" + cursor.getCount());
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String table = cursor.getString(cursor.getColumnIndex("table_name"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String detail = cursor.getString(cursor.getColumnIndex("detail"));
Log.e("test", "table_name:" + table);
Log.e("test ", "name: " + name);
Log.e("test ", "detail: " + detail);
cursor.moveToNext();
}
cursor.close();
}Cursor cursor = this.getContentResolver().query(mCurrentURI, null, null, null, null);
public final Uri insert (Uri url, ContentValues values)
private void insert() {
ContentValues values = new ContentValues();
values.put("name", "hello");
values.put("detail", "my name is harvic");
Uri uri = this.getContentResolver().insert(mCurrentURI, values);
Log.e("test ", uri.toString());
}public final int update (Uri uri, ContentValues values, String where, String[] selectionArgs)
private void update() {
ContentValues values = new ContentValues();
values.put("detail", "my name is harvic !!!!!!!!!!!!!!!!!!!!!!!!!!");
int count = this.getContentResolver().update(mCurrentURI, values, "_id = 1", null);
Log.e("test ", "count=" + count);
query();
}public final int delete (Uri url, String where, String[] selectionArgs)
private void delete() {
int count = this.getContentResolver().delete(mCurrentURI, "_id = 1", null);
Log.e("test ", "count=" + count);
query();
}1、我们先运行ContentProvider对应的APP:ContentProviderBlog,然后再运行UseProvider;
2、然后先用content://com.harvic.provider.PeopleContentProvider/frist 来操作ContentProviderBlog的数据库:
3、点两个insert操作,看返回的URI,在每个URI后都添加上了当前新插入记录的行号
4、然后做下查询操作——query()
由于我们的URI是针对first记录的,所以在这里的table_name,可以看到是“first”,即我们操作的是first表,如果我们把URI改成second对应的URI,那操作的就会变成second表
5、更新操作——update()
执行Update()操作,会将_id = 1的记录的detail字段更新为“my name is harvic !!!!!!!!!!!!!!!!!!!!!!!!!!”;其它记录的值不变,结果如下:
6、删除操作——delete()
同样,删除操作也会只删除_id = 1的记录,所以操作之后的query()结果如下:
总结:在这篇文章中,我们写了两个应用ContentProviderBlog和UseProvider,其中ContentProviderBlog派生自ContentProvider,提供第三方操作它数据库的接口;而UseProvider就是所谓第三方应用,在UseProvider中通过URI来操作ContentProviderBlog的数据库;
好了,到这里,整个文章就结束了,大家在看完这篇文章以后再回过头来看第一篇,应该对应用间数据库共享的整体流程已经有清晰的了解了。
源码来了,源码包含两部分内容:
1、《ContentProviderBlog》:这个是提供共享数据库接口的APP;
2、《UseProvider》:第三方通过URI来操作数据库的APP;
如果本文有帮到你,记得关注哦
源码下载地址:http://download.csdn.net/detail/harvic880925/8528507
http://blog.csdn.net/harvic880925/article/details/44591631 谢谢!
