ContentProvider主要用来对外共享数据,可以把你应用中的数据,通过统一的Uri对外提供访问。简单的说,你的应用通过ContentProvider造出了与其他应用通信的窗口。
ContentResolver对与Uri对应的应用进行操作。
---------------------------------------------------------这是一条很长的分割线-----------------------------------------------------------------
ContentProvider的配置
第一步,继承ContentProvider。
第二步,在AndroidMainfest.xml中的<application>标签下,添加provider标签。
<!--DBshare继承了ContentProvider -->
<!-- authorities为通信的唯一标识 -->
<provider
android:name=".provider.DBshare"
android:authorities="com.example.testcontentprovider.dbshare"
android:exported="true">
</provider>
---------------------------------------------------------这是一条很长的分割线-----------------------------------------------------------------
下面写了个小例子,有两个App。
App1:TestContentProvider
DBOpenHelper数据库创建、MyData实体类、MyDataDao对数据库进行操作、DBshare为ContentProvider
App2:TestVisitor
用于获取App1的数据。
---------------------------------------------------------这是一条很长的分割线-----------------------------------------------------------------
代码,这里只展示关键代码
TestContentProvider
DBsharej.ava
/**
* ContentProvider用于对外共享数据
*
* @author xueda
*
*
* 对于delete、update、insert方法,要想有返回值可以更改MyDataDao中的方法.例如:saveOther();
*/
public class DBshare extends ContentProvider {
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSONS = 100;
private static final int PERSONS_1 = 200;
static {
// 匹配content://com.example.testcontentprovider.dbshare/myTest返回PERSONS的值100
matcher.addURI("com.example.testcontentprovider.dbshare", "myTest", PERSONS);
matcher.addURI("com.example.testcontentprovider.dbshare", "myTest/#", PERSONS_1);
}
/**
* 对数据库进行删除操作
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
switch (matcher.match(uri)) {
case PERSONS:
MyDataDao myDataDao = new MyDataDao(this.getContext());
myDataDao.delete(5);
Log.d("delete_ContentProvider", "DELETE_OK");
break;
default:
Log.i("query", "没有匹配成功");
break;
}
return 0;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
/**
* 对数据库进行添加操作
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
switch (matcher.match(uri)) {
case PERSONS:
MyDataDao myDataDao = new MyDataDao(this.getContext());
MyData myData = new MyData(values.getAsString("data1"), values.getAsString("data2"));
Log.d("insert_ContentValues", values.getAsString("data1") + "," + values.getAsString("data2"));
myDataDao.save(myData);
break;
default:
Log.i("query", "没有匹配成功");
break;
}
return null;
}
@Override
public boolean onCreate() {
return true;
}
/**
* 对数据库进行查询操作
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor cursor = null;
switch (matcher.match(uri)) {
case PERSONS:
//调用dao,对数据库进行操作
MyDataDao myDataDao = new MyDataDao(this.getContext());
cursor = myDataDao.getAllMyDatasByC();
Log.d("query_ContentValues", "query_ContentValues");
break;
default:
Log.i("query", "没有匹配成功");
break;
}
return cursor;
}
/**
* 对数据库进行更新
*/
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
switch (matcher.match(uri)) {
case PERSONS_1:
/**
* 除了用下面的方法,uri传递id以外,还可以使用ContentValues。
* 如:
* values.getAsString("id");
*/
//解析uri地址
//content://com.example.testcontentprovider.dbshare/myTest/1
//在这里获取的是1
int id = (int) ContentUris.parseId(uri);
MyDataDao myDataDao = new MyDataDao(this.getContext());
myDataDao.update("更改的数据1", "更改的数据2", id+"");
Log.d("update_ContentValues", id+"");
break;
default:
break;
}
return 0;
}
}
MyDataDao的saveOther()
public int saveOther(MyData myData) {
db = dbOpenHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("data1", myData.getData1());
contentValues.put("data2", myData.getData2());
long a = db.insert("myTest", "_id", contentValues);
return (int) a;
}
TestVisitor
主要方法
/**
* 获取TestContentProvider的数据
*
* @param v
*/
public void getData(View v) {
uri = Uri.parse("content://com.example.testcontentprovider.dbshare/myTest");
Cursor cursor = null;
cursor = contentResolver.query(uri, null, null, null, null);
if (cursor == null) {
Toast.makeText(MainActivity.this, "没有获取到数据", Toast.LENGTH_SHORT).show();
return;
}
while (cursor.moveToNext()) {
int _id = cursor.getInt(cursor.getColumnIndex("_id"));
String data1 = cursor.getString(cursor.getColumnIndex("data1"));
String data2 = cursor.getString(cursor.getColumnIndex("data2"));
Log.d("cursor", _id + "," + data1 + "," + data2);
}
}
/**
* 向TestContentProvider的数据库插入数据
*
* @param v
*/
public void insertData(View v) {
uri = Uri.parse("content://com.example.testcontentprovider.dbshare/myTest");
ContentValues contentValues = new ContentValues();
contentValues.put("data1", "外部控制插入数据");
contentValues.put("data2", "外部控制插入数据");
try {
contentResolver.insert(uri, contentValues);
} catch (IllegalArgumentException e) {
Toast.makeText(MainActivity.this, "没有找到匹配uri的应用", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(MainActivity.this, "插入数据成功", Toast.LENGTH_SHORT).show();
}
/**
* 向TestContentProvider的数据库删除数据
*
* @param v
*/
public void deleteData(View v) {
uri = Uri.parse("content://com.example.testcontentprovider.dbshare/myTest");
try {
contentResolver.delete(uri, "id=" + 5, null);
} catch (IllegalArgumentException e) {
Toast.makeText(MainActivity.this, "没有找到匹配uri的应用", Toast.LENGTH_SHORT).show();
}
}
/**
* 向TestContentProvider的数据库更新数据
*
* @param v
*/
public void updateData(View v){
uri = Uri.parse("content://com.example.testcontentprovider.dbshare/myTest/1");
ContentValues contentValues = new ContentValues();
contentValues.put("id", "1");
contentResolver.update(uri, contentValues, null, null);
}
---------------------------------------------------------这是一条很长的分割线-----------------------------------------------------------------
提一点
TestContentProvider运行后,点击“注入数据”,使数据库有数据可进行操作。
观看执行过程,请看控制台的LogCat。
源码:Demo