内容提供器的用法一般有两种:
1.使用现有的内容提供器来读取和操作相应程序中的数据
2.创建自己的内容提供器给我们程序的数据提供外部访问接口。
如果一个应用程序通过内容提供器对其数据提供了外部访问接口,那么任何其他的应用程序既可以对这部分数据进行访问。Android系统中自带的电话薄、短信、媒体库等程序都提供了类似的访问接口,这就使得第三方应用程序可以充分地利用这部分数据来实现更好的功能。
ContentResolver的基本用法
对于每一个应用程序来说,如果想要访问内容提供器中共享的数据,就一定要借助ContentResolver类,可以通过Context中的getContentResolver()方法获取到该类的实例。ContentResolver中提供了一系列的方法用于对数据进行CRUD操作,其中insert()方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据。这和SQLiteDatabase中的CRUD操作还是有点区别的。
不同于SQLiteDatabase,ContentResolver中的增删改查方法都是不接收表名参数的,而是使用一个Uri参数代替,这个参数被称为内容URI。内容URI给内容提供器中的数据建立了唯一标识符,它主要由两部分组成:authority和path。
authority:用于对不同的应用程序做区分的,一般为了避免冲突,都会采用程序包名的方式来进行命名。比如某个程序的包名com.example.app,那么该程序对应的authority就可以命名为com.example.app.provider。
path:用于对同一应用程序中不同的表做区分的,通常都会添加到authority的后面。比如某个程序的数据库里存在两张表table1和table2,这时就可以将path分别命名为/table1和/table2,然后把authority和path进行组合,内容URI就变成了com.example.app.provider/table1和com.example.app.provider/table2。
不过,目前还很难辨别出这两个字符串就是两个内容URI,我们还需要在字符串的头部加上协议声明。因此,内容URI最标准的格式写法如下:
协议名://包名.provider/表名
例:
content://com.example.app.provider/table1
content://com.example.app.provider/table2
有没有发现,内容URI可以非常清楚地表达出我们想要访问哪个程序中的哪张表里的数据。也正因此,ContentResolver中的增删改查方法才都接收Uri对象作为参数,因为如果使用表名的话,系统将无法得知我们期望访问的是哪个应用程序里的表。
在得到了URI字符串之后,我们还需要将它解析成Uri对象才可以作为传入。
解析方法:
Uri uri=Uri.pare("content://com.example.app.provider/table1");
只需要调用Uri.parse()方法,就可以将内容URI字符串解析成Uri对象了。
现在我们就可以使用这个Uri对象来查询table1表中的数据了,代码如下所示:
Cursor cursor=getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
uri:指定查询某个应用程序下的某一张表
projection:指定查询的列名(select column1,column2)
selection:指定where的约束条件(where column = value)
selectionArgs:为where中的占位符提供具体的值
sortOrder:指定查询结果的排序方式(order by column1,column2)
查询完成后返回的仍然是一个Cursor对象,这时我们就可以将数据从Cursor对象中逐个读取出来了。读取的思路仍然是通过移动游标的位置来遍历Cursor的所有行,然后再取出每一行中相应列的数据,代码如下所示:
if(cursor != null){
while(cursor.moveToNext()){
String column1=cursor.getString(cursor.getColumnIndext("column1"));
int column2=cursor.getInt(cursor.getColumnIndext("column2"));
}
cursor.close();
}
掌握了最难的查询操作,剩下的增删改操作就比较容易了。
增加数据:
ContentValues cv=new ContentValues();
cv.put("column1","text);
cv.put("column2",1);
getContentResolver().insert(uri,cv);
更新数据:
ContentValues cv=new ContentValues();
cv.put("column1","");
getContentResolver().update(uri,cv,"column1 = ? and column2 = ?",new String[]{"text","1"});
注意上述代码使用了selection和selectionArgs参数来对想要更新的数据进行约束,以防止所有的行都会受影响。
删除数据:
getContentResolver().delete(uri,"column2 = ?",new String[] {"1"});
这句话的意思是将column2列中,值为1的这一行数据给删除。