内容提供器(ContentProvider)
一.简介
内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性。目前,使用内容提供器是Android 实现跨程序共享数据的标准方式。
不同于文件存储和SharedPreferences 存储中的两种全局可读写操作模式,内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险。
内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内容提供器给我们程序的数据提供外部访问接口。
二.基本知识点
1.要访问内容提供器中共享的数据,就一定要借助ContentResolve 类.ContentResolver 中提供了一系列的方法用于对数据进行CRUD 操作,其中insert()方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据
2.ContentResolver 中的增删改查方法都是不接收表名参数的,而是使用一个Uri 参数代替,这个参数被称为内容URI。内容URI 给内容提供器中的数据建立了唯一标识符,它主要由两部分组成,权限(authority)和路径(path)。权限是用于对不同的应用程序做区分的,一般为了避免冲突,都会采用程序包名的方式来进行命名。比如某个程序的包名是com.example.app , 那么该程序对应的权限就可以命名为com.example.app. provider。路径则是用于对同一应用程序中不同的表做区分的,通常
都会添加到权限的后面。比如某个程序的数据库里存在两张表,table1 和table2,这时就可以将路径分别命名为/table1 和/table2,然后把权限和路径进行组合,内容URI 就变成了com.example.app.provider/table1 和com.example.app.provider/table2。
不过,目前还很难辨认出这两个字符串就是两个内容URI,我们还需要在字符串的头部加上协议声明。因此,内容URI 最标准的格式写法如下:
content://com.example.app.provider/table1 content://com.example.app.provider/table2
3.在得到了内容URI 字符串之后,我们还需要将它解析成Uri 对象才可以作为参数传入。解析的方法也相当简单,代码如下所示:
Uri uri = Uri.parse("content://com.example.app.provider/table1");
只需要调用Uri.parse()方法,就可以将内容URI 字符串解析成Uri 对象了。
现在我们就可以使用这个Uri 对象来查询table1 表中的数据了,代码如下所示:
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
这些参数和SQLiteDatabase 中query()方法里的参数很像,但总体来说要简单一些,毕竟这是在访问其他程序中的数据,没必要构建过于复杂的查询语句。下表对使用到的这部分参数进行了详细的解释。
读取到一个Cursor对象后,就可以获取数据了.
if (cursor != null) { while (cursor.moveToNext()) { String column1 = cursor.getString(cursor.getColumnIndex("column1")); int column2 = cursor.getInt(cursor.getColumnIndex("column2")); } cursor.close(); }
三.读取手机联系人代码(向系统提供的内容提供器获取数据):
1.关键代码:
protected void readContact(){ Cursor cursor = null; try{ cursor = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null ); while (cursor.moveToNext()){ String phone = cursor.getString(cursor.getColumnIndex(ContactsContract. CommonDataKinds.Phone.NUMBER)); String name = cursor.getString(cursor.getColumnIndex(ContactsContract. CommonDataKinds.Phone.DISPLAY_NAME)); contactList.add(name + "\n" + phone); } }catch (Exception e){ e.printStackTrace(); }finally { if( cursor != null ){ cursor.close(); } } }
2.权限申明
<uses-permission android:name="android.permission.READ_CONTACTS" />
3.测试时发现权限拒绝错误,这是因为android6.0将授权改为了用户授权
在Android Studio中修改build.gradle(Module:app),将targetSdkVersion 改为小于等于21