内容提供器(Content Provider),主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性。目前,使用内容提供器是android实现跨程序共享数据的标准方式。
不同于文件存储和sharedpreferences存储中的两种全局可读可写操作模式,内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄露的风险。
内容提供器的用法一般有两种,
一种是使用现有的内容提供器来读取和操作相应程序中的数据,
另一种是创建自己的内容提供器,给我们程序的数据提供外部访问接口。
我们先来学习一下使用现有的内容提供器(Content Provider)
在正式学习之前,我们需要了解一个概念,内容提供器(Content Provider)就是提供了一些可以访问一些数据,是暴露在外的,那么要想拿到数据就需要一个类,android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据 。
所以,我们在跨应用获取数据,使用ContentResolver来拿到别的应用中的数据,先来介绍一下它的用法,这也是在使用现有的内容提供器时仅仅需要做的地方,话不多说,开始吧。
ContentResolver的基本用法
对于每一个应用程序来说,如果想要访问内容提供器中共享的数据,就一定要借助ContentResolve类,可以通过Context中的getContentResolver()方法获取到该类的实例。ContentResolver中提供了一系列的方法用于对数据的CRUD操作,其中insert()方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据,和SQLiteDatabase很相似的,下面来介绍具体用法。
不同于SQLiteDatabase,ContentResolver中的增删改查方法都是不接受表名参数的,而是使用一个Uri参数代替,这个参数被称为内容URI。内容URI给内容提供器中的数据建立了唯一的标识,它主要由两部分组成,
权限(authority)和
路径(path)。
权限是用于对不同的应用程序做区分的,一般为了避免冲突,都会采用程序包名的方式来进行命名。比如某个程序的包名是:com.example.app,那么该程序对应的权限就可以命名为com.example.app.provider。
路径则是用于同一应用程序中不同的表做区分的,通常会添加到权限的后面。比如某个程序的数据库里存在两张表table1 和table2,这时就可以将路径分别命名为/table1 和/table2,然后把权限和路径进行组合,内容URI就变成了com.example.app.provider/table1。
但是,这还不是标准的URI,我们还需要给它加一个头部的协议声明:content://com.example.app.provider/table1。
URI中可以明确的表达出我们想要访问哪个程序中的哪张表里的数据,所以ContentResolve的增删改查都是用URI来作为其中一个参数来使用的,简单写一下URI对象如何获取
Uri uri = Uri.parse("content://com.example.app.provider/table1");
现在我们就可以使用这个URI对象来查询table1表中的数据,看如下的代码:
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
来介绍一下每个参数
query()方法参数
|
对应SQL部分
|
描述
|
uri
|
from table_name
|
指定查询某个应用程序下的某一张表
|
projection
|
select column1,column2
|
指定查询的列名
|
selection
|
where column = value
|
指定where的约束条件
|
selectionArgs
|
-
|
为where中的占位符提供具体的值
|
orderBy
|
order by column1,column2
|
指定查询结果的排序方式
|
查询过后会获得一个cursor对象,然后就是遍历所有行,然后取出每一行中相应列的数据
if(cursor != null){
while(cursor.moveToNext()){
String column1 = cursor.getString(cursor.getColumnIndex("column1"));
int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
}
cursor.close();
}
以上就是查询操作的全部动作(最难的已经学会了),下面我们来看看增删改,就直接给代码了,因为比较简单啦
删除:
getContentResolver().delete(uri,"column2 = ?",new String[]{"1"});
修改:
ContentValue values = new ContentValue();
values.put("column1","");
getContentResolver().update(uri,values,"column1 = ? and column2 = ?",new String[]{"text","1"});
增加:
ContentValue values = new ContentValue();
values.put("column1","text");
values.put("column2",1);
getContentResolver().insert(uri,values);
上面谈了这么多,也算是把ContentResolve将完了,该回到咱们的内容提供器身上了,这次讲的是现有的内容提供器,就像通讯录中的联系人,图库中的照片,都算是现有的提供器,所有下面就用代码来展示一下了。
老方法,先把要干的事列出来
1.搞一个ListView布局出来,用来显示从android通讯录中拿到的信息。
2.在mainActivity中写一下数据的获取和装填。
3.记得注册一下权限,要不android不会允许你随便那通讯录中的信息的。
开始吧
1.写布局
<
ListView
android :id= "@+id/contacts_view"
android :layout_width= "match_parent"
android :layout_height= "match_parent">
android :id= "@+id/contacts_view"
android :layout_width= "match_parent"
android :layout_height= "match_parent">
</ListView>
2.把数据获取一下,用adapter装填一下,显示出来就好
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
readContacts();
contactsView = (ListView) findViewById(R.id. contacts_view);
adapter = new ArrayAdapter<String>( this,android.R.layout. simple_list_item_1, contactsList);
contactsView.setAdapter( adapter);
}
private void readContacts(){
Cursor cursor = null;
try{
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone. CONTENT_URI, null, null, null, null);
while(cursor.moveToNext()){
//获取联系人姓名
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone. DISPLAY_NAME));
//获取联系人电话
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone. NUMBER));
contactsList.add(displayName+ " \n "+number);
}
} catch (Exception e){
e.printStackTrace();
} finally {
if (cursor != null){
cursor.close();
}
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
readContacts();
contactsView = (ListView) findViewById(R.id. contacts_view);
adapter = new ArrayAdapter<String>( this,android.R.layout. simple_list_item_1, contactsList);
contactsView.setAdapter( adapter);
}
private void readContacts(){
Cursor cursor = null;
try{
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone. CONTENT_URI, null, null, null, null);
while(cursor.moveToNext()){
//获取联系人姓名
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone. DISPLAY_NAME));
//获取联系人电话
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone. NUMBER));
contactsList.add(displayName+ " \n "+number);
}
} catch (Exception e){
e.printStackTrace();
} finally {
if (cursor != null){
cursor.close();
}
}
}
3.最后千万记得注册啊,在AndroidManifest.xml文件中。
<
uses-permission
android
:name=
"android.permission.READ_CONTACTS"/>
就是这样就可以了。好了这一篇介绍现有内容提供器就到这里了。可以多在网络上搜一下现有内容提供器的更多信息,下一篇将讲一下自己创建的内容提供器。