为什么要有ContentProvider
功能需求:一个应用需要访问另一个应用的数据库表数据
实际情况:一个应用的数据库文件是私有的,其它应用不能直接访问
功能需求:一个应用需要访问另一个应用的数据库表数据
实际情况:一个应用的数据库文件是私有的,其它应用不能直接访问
ContentProvider
当前应用使用Content将数据库数据操作暴露给其它应用访问
其它应用使用ContentResolver来调用ContentProvider
当前应用使用Content将数据库数据操作暴露给其它应用访问
其它应用使用ContentResolver来调用ContentProvider
需要两个应用,一个用于提供数据源,另一个可以访问提供者的数据
在提供的应用里面,需要调用一个新的类,它继承ContentProvider,这是针对表的操作类,
我们知道在对表的操作的时候需要定义一个类用于对数据库进行连接,这个类是dbHelp继承SQLiteOpenHelper
我们知道在对表的操作的时候需要定义一个类用于对数据库进行连接,这个类是dbHelp继承SQLiteOpenHelper
注意:在定义ContentProvider的子类时需要注册
//提供者
//提供者
<strong><provider android:name="全类名"
android:authorities="全类名"
android:exported="true">
<!-- 是否可以让其它应用访问 -->
</provider></strong>
定义一个变量
//用来存放所有合法的Uri的容器
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//保存一些合法的uri
//content://com.example.provider.PersonProvider/表名
//content://com.example.provider.PersonProvider/表名/id
static {
//不根据id查询
matcher.addURI("com.example.provider.PersonProvider", "/表名", 1);
//根据id查询
matcher.addURI("com.example.provider.PersonProvider", "/表名/#", 2);//#匹配任意字符
}
对数据库的操作需要一个数据库对象,在onCreate的方法里面对dbHelp进行创建对象
然后分别是增删改查
1.查询query
<strong>int code = matcher.match(uri);//匹配码
SQLiteDatabase database = dbHelp.getReadableDatabase();
if (code==1) {//不根据id查询
Cursor cursor = database.query("person", projection, selection, selectionArgs, null, null, null);
return cursor;
} else if (code==2) {//根据id查询
//得到id值
long id = ContentUris.parseId(uri);
//查询
Cursor cursor = database.query("person", projection, "_id=?", new String[]{id+""}, null, null, null);
return cursor;
}else{
throw new RuntimeException("查询的uri不合法");
}</strong>
在第二个应用里面可以进行查询
<strong>public void query (View v) {
//得到ContentResolver
ContentResolver resolver = getContentResolver();
//调用其query,得到Content
Uri uri = Uri.parse("content://com.example.provider.PersonProvider/person/1");//根据id查询
//Uri uri = Uri.parse("content://com.example.provider.PersonProvider/person");不根据id查询
Cursor cursor = resolver.query(uri, null, null, null, null);
//取出curson中的数据,并显示
if (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
Toast.makeText(this, name+" "+id, 1).show();
}
}</strong>
2.增加
//我们知道增加只能增加信息,不能增加id
//第一个应用中增加方法的实现
<strong>public Uri insert(Uri uri, ContentValues values) {
Log.e("tag", "PersonProvider insert()");
//增加只有不根据id增加
SQLiteDatabase database = dbHelp.getReadableDatabase();
int code = matcher.match(uri);
if (code == 1) {
long id = database.insert("person", null, values);
//在返回前将id添加在uri中
uri = ContentUris.withAppendedId(uri, id);
database.close();
return uri;
}else {
database.close();
throw new RuntimeException("插入的uri不合法");
}
}</strong>
//第二个应用中对增加的实现
<strong>ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.example.provider.PersonProvider/person");
ContentValues values = new ContentValues();
values.put("name", "fanny");
uri = resolver.insert(uri, values);
Toast.makeText(this, uri.toString(), 0).show();</strong>
3.修改
//修改可以根据id进行修改也可以不根据id进行修改
//第一个应用
<strong>public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
Log.e("tag", "PersonProvider update()");
//更新 根据id更新和不根据id更新
int code = matcher.match(uri);
SQLiteDatabase database = dbHelp.getReadableDatabase();
int updateCount = -1;
if (code == 1) {
updateCount = database.update("person", values, selection, selectionArgs);
} else if (code == 2) {
long id = ContentUris.parseId(uri);
System.out.println(id);
updateCount = database.update("person", values, "_id="+id, null);
} else {
}
return updateCount;
}</strong>
//第二个应用
<strong>ContentResolver resolver = getContentResolver();
//根据id进行修改
Uri uri = Uri.parse("content://com.example.provider.PersonProvider/person/2");
ContentValues values = new ContentValues();
values.put("name", "fanny");
//不根据id进行修改
long d = resolver.update(uri, values, null, null);
// Uri uri = Uri.parse("content://com.example.provider.PersonProvider/person");
// long s = resolver.update(uri, values, "_id=2", null);
Toast.makeText(this, d+"", 0).show();</strong>
4.删除
//删除也是可以根据id进行删除,也可以不根据id进行删除
//第一个应用
<strong>public int delete(Uri uri, String selection, String[] selectionArgs) {
Log.e("tag", "PersonProvider delete()");
//删除可以根据id进行删除也可以不根据id进行删除
int code = matcher.match(uri);
SQLiteDatabase database = dbHelp.getReadableDatabase();
int deleteCount = -1;
if (code == 1) {
deleteCount = database.delete("person", selection, selectionArgs);
} else if (code == 2) {
long id = ContentUris.parseId(uri);
deleteCount = database.delete("person", "_id="+id, null);
} else {
throw new RuntimeException("删除的uri不合法");
}
database.close();
return deleteCount;
}</strong>
//第二个应用
<strong>ContentResolver resolver = getContentResolver();
//根据id进行删除
// Uri uri = Uri.parse("content://com.example.provider.PersonProvider/person/2");
// long s = resolver.delete(uri, null, null);
//不根据id进行修改
Uri uri = Uri.parse("content://com.example.provider.PersonProvider/person");
long s = resolver.delete(uri, "_id=3", null);
Toast.makeText(this, s+"", 0).show();
</strong>
//注意事项:
1.我们发现这些方法道理其实都相同,只是调用的方法不同而已
2.在第一个应用中,除了查询都应该把数据库进行关闭,er为什么查询不需要关闭数据库呢???
这是因为我们如果在查询的方法内把数据库关闭后,那么就不能返回查询的结果集了。