调用相册,调用音乐等(上一遍已经介绍了)。这是怎么实现的呢?其实就是ContentProvider
的功劳。系统封装好了ContentProvider
,而我们只需要调用就行。
而现在我们需要自己对应用建立ContentProvider
,以供别的应用访问。
结合实例:应用A要访问应用B 的数据库。
1:新建ContentProvider
1:new--->Other--->Content Provider
,新建时:URI Authorities
代表主机名,组成建议这样的:包名+自定义名。
新建完成后系统会重写多个方法,接下来我们需要做的就是对这些方法做具体的实现。
2:实现方法:
实现以下方法,前提需要实现了SQLiteOpenHelper
等创建数据库的操作,具体可参我的一篇文章(下面的例子也就是基于这篇文章里所创建的数据库):已创建的数据库
直接上代码:
假设应用为 A :
public class MyContentProvider extends ContentProvider {
private SQLiteUtil sqLiteUtil;
//根据uri匹配
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static{
//可有多个主机名,以便访问多个表
MATCHER.addURI("com.index.test.sqlitetest.conp","user_info",1);//查询全表数据
MATCHER.addURI("com.index.test.sqlitetest.conp","user_info/#",2);//根据唯一标识符查询
}
public MyContentProvider() {
}
@Override
public String getType(Uri uri) {
//系统回调,该方法会区分查询是全表查询还是单条数据查询,写法固定
switch (MATCHER.match(uri)){
case 1:
return "vnd.android.cursor.dir/user_info";//必须以vnd开头
case 2:
return "vnd.android.cursor.item/user_info";//必须以vnd开头
}
return null;
}
//selection是查询条件,selectionArgs是要查询具体条件值,返回的是对数据库的影响行数
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
//判断查询条件,要判断的值
switch (MATCHER.match(uri)){
case 1:
return db.delete("user_info",selection,selectionArgs);
case 2:
long rowid = ContentUris.parseId(uri);//获取表的id
String where = "_id = "+rowid;
if (selection!=null && !selection.equals("")){
where = selection+" and "+where;
}
return db.delete("user_info",where,selectionArgs);
}
return 0;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
switch(MATCHER.match(uri)){
case 1:
long rowid = db.insert("user_info",null,values);
return ContentUris.withAppendedId(uri,rowid);
default:
break;
}
return null;
}
@Override
public boolean onCreate() {
sqLiteUtil = new SQLiteUtil(this.getContext(),2);
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = sqLiteUtil.getReadableDatabase();
switch (MATCHER.match(uri)){
case 1:
return db.query("user_info",projection,selection,selectionArgs,null,null,sortOrder);
case 2:
long rowid = ContentUris.parseId(uri);
String where = "_id = "+rowid;
if (selection!=null && !selection.equals("")){
where = selection +" and "+ where;
}
return db.query("info_user",projection,where,selectionArgs,null,null,sortOrder);
}
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
switch (MATCHER.match(uri)){
case 1:
return db.update("user_info",values,selection,selectionArgs);
case 2:
long rowid = ContentUris.parseId(uri);
String where = "_id = "+rowid;
if (selection!=null && !selection.equals("")){
where = selection +" and "+ where;
}
return db.update("user_info",values,where,selectionArgs);
}
return 0;
}
}
2:B访问A中的数据库
上面已经创建好了应用 A 的ContentProvider
,现在我们从另外一个应用(假设应用为 B )中访问A 的数据库:
其实也很简单:
B 中通过A 主机名获取Uri
,通过getContentResolver()
获得ContentResolver
,通过ContentResolver
执行数据库操作。
实例: B 获得A中user_info
表的所有数据;点击往user_info
表中添加一条数据:
public class ProviderActivity extends AppCompatActivity {
private Button button1,button2;
private TextView textView1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_provider);
button1 = (Button)findViewById(R.id.getUser);
button2 = (Button)findViewById(R.id.add);
textView1 = (TextView)findViewById(R.id.showProvider);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//“com.index.test.sqlitetest.conp”是A中provider的主机名,“user_info”是数据库表,如果需要查询单条数据库,只需要在“user_info”后加上id即可,如“/user_info#3”,A中的provider会自动判断是单条查询还是全表查询
Uri uri = Uri.parse("content://com.index.test.sqlitetest.conp/user_info");
//获取ContentResolver ,用来执行数据库操作
ContentResolver contentResolver = getContentResolver();
//ContentResolver执行数据库操作,返回类型为Cursor 的结果集
Cursor c = contentResolver.query(uri, null, null, null, null);
//读取并显示数据
StringBuffer stringBuffer = new StringBuffer();
while (c.moveToNext()){
stringBuffer.append(c.getString(0)+"\n");
stringBuffer.append(c.getString(1)+"\n");
stringBuffer.append(c.getString(2)+"\n");
stringBuffer.append(c.getString(3)+"\n");
stringBuffer.append(c.getString(4)+"\n");
}
textView1.setText(stringBuffer.toString());
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addUser();
}
});
}
//添加操作
public void addUser(){
//原理同上
Uri uri = Uri.parse("content://com.index.test.sqlitetest.conp/user_info");
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put("name","xiaosheng");
contentValues.put("age","20");
contentValues.put("imgUrl","地址");
contentValues.put("pwd", "admin");
contentResolver.insert(uri, contentValues);
}
}