内容提供器是啥?
内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,不同于文件存储和SharedPreferences存储中的两种全局可读写操作模式,内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险。
我们可以用内容提供器来干什么呢?
例如系统的电话簿程序,它的数据库中保存了很多的联系人信息,如果这些数据都不允许第三方的程序进行访问的话,恐怕很多应用的功能都要大打折扣了。除了电话簿之外,还有短信、媒体库等程 序都实现了跨程序数据共享的功能,而使用的技术就是内容提供器了。
举个大家最熟悉的例子,微信通过联系人添加好友。
在使用内容提供器的时候很多情况下会使用到很多危险权限
,如通讯录、摄像机、拨打电话、发送短信… …等权限。
而一般权限
在AndroidManifest.xml
中配置一下就可以了,如
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test">
<!-- 振动权限 -->
<uses-permission android:name="android.permission.VIBRATE" />
......
</manifest>
而危险权限
不仅需要在AndroidManifest.xml
中配置,还需要用户授权
才能使用。
权限详情请见:Android权限详解
对于每一个应用程序来说,如果想要访问内容提供器中共享的数据,就一定要借助ContentResolver类,可以通过Context中的getContentResolver()方法获取到该类的实例。
ContentResolver contentResolver = getContentResolver();
ContentResolver中提供了一系列的方法用于对数据进行CRUD操作。
和SQLiteDatabase不同的是,ContentResolver中的增、删、改、查方法都是不接收表名参数的,而是使用一个Uri参数代替,这个参数被称为“内容URI”。
“内容URI”给内容提供器中的数据建立了唯一标识符,它主要由两部分组成,权限(authority)和路径(path)。权限是用于对不同的应用程序做区分的,一般为了避免冲突,都会采用程序包名的方式来进行命名。
如:某个程序的包名是com.example.test
那么该程序对应的权限就可以命名为com.example.test.provider。
路径则是用于对同一应用程序中不同的表做区分的,通常都会添加到权限的后面。 比如某个程序的数据库里存在两张表teacher和student,这时就可以将路径分别命名为/teacher和/student,然后把权限和路径进行组合,内容URI就变成了com.example.test.provider/teacher和 com.example.test.provider/student。
最后,我们还需要在字符串的头部加上协议声明。内容URI标准格式为:content://com.example.test.provider/teacher和content://com.example.test.provider/student
最后调用Uri.parse()方法,将内容URI字符串解析成Uri对象。
Uri uri = Uri.parse("content://com.example.test.provider/teacher");
接下来要做的就是调用方法进行增、删、改、查了。
insert()方法用于添加数据,看一下官方的介绍:
Uri uri = Uri.parse("content://com.example.test.provider/teacher");
ContentValues contentValues = new ContentValues();
contentValues.put("column1", "value1");
contentValues.put("column2", "value2");
contentValues.put("column3", "value3");
/**
* SQL:
* insert into table (column1,column2,column3,...)
* values (value1,value2,value3,...);
*
* 参数:
* uri 指定将数据插入某个应用程序下的某一张表(相当于SQL中的“insert into table”的“table”)
* values 添加到数据库的一系列键值对(相当于SQL中的“(col1,col2,...) values (val1,val2,...)”)
*/
Uri uri1 = insert(Uri url, ContentValues values);
delete()方法用于删除数据
/**
* SQL:
* delete from table
* where column=value;
*
* 参数:
* uri 指定删除某个应用程序下的某一张表中的数据(相当于SQL中的“from table”)
* where 指定约束条件(相当于SQL中的“where column=value”中的“column”)
* selectionArgs 指定的约束条件的值(相当于SQL中“where column=value”中的“value”)
*/
int resultCode = delete(Uri url, String where, String[] selectionArgs)
update()方法用于更新数据
/**
* SQL:
* update table
* set column1=value1,column2=value2,...
* where column=value;
*
* 参数:
* uri 指定更新某个应用程序下的某一张表(相当于SQL中的“table”)
* values 添加到数据库的一系列键值对(相当于SQL中的“set column1=value1,column2=value2,...”)
* where 指定约束条件(相当于SQL中的“where column=value”中的“column”)
* selectionArgs 指定的约束条件的值(相当于SQL中“where column=value”中的“value”)
*/
int resultCode = update(Uri uri, ContentValues values, String where, String[] selectionArgs);
query()方法用于查询数据
/**
* SQL:
* select column1,column2
* from table
* where column=value
* order by column;
*
* 参数:
* uri 指定查询某个应用程序下的某一张表(相当于SQL中的“from table”)
* projection 指定查询的列名(相当于SQL中的“select column1, column2”)
* selection 指定约束条件(相当于SQL中“where column = value”中的“column”)
* selectionArgs 指定的约束条件的值(相当于SQL中“where column=value”中的“value”)
* sortOrder 指定查询结果的排序方式(相当于SQL中的“order by”)
*/
Cursor cursor = contentResolver.query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
if (cursor != null) {
while (cursor.moveToNext()) {
//获取每一个字段的值
String column1 = cursor.getString(cursor.getColumnIndex("column1"));
int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
......
}
cursor.close();
}
OK,内容提供器的基本使用介绍完了,参数解释、(伪)代码都很详细,在官方文档和各种搜索引擎(百度、Google)的帮助下圆满完成。