Android入门(ContentProvider)不同应用共享数据
ContentProvider主要用于在不同的应用程序之间实现数据共享的功能
运行时权限
这是ContentProvider能否使用的基础.
运行时权限的意义:在旧版android中,所有的权限都是在应用安装时会直接声明出来,如果你接受这些条件就安装。否则拒绝安装就可以了。而这就会导致一些店大欺客的问题。比如:旧版微信就会申请几乎所有的权限。而你如果不接受你就不能使用微信。
所以运行时权限就有了他存在的意义:应用会在需要使用该权限时才会像用户发起申请,即便用户拒绝了,也可以正常使用其他功能。
当然,并不是所有权限都需要在运行时申请,对于用户来说,不停地授权也很烦琐。Android现在将常用的权限大致归成了两类,一类是普通权限,一类是危险权限。对于普通权限,系统会帮我们自动授权。而危险权限都交给用户决定。
以下是Android到Android10版本所有的危险权限:
运行时权限申请样例:
1 |
|
访问其他应用的数据
ContentProvider的使用:
- 他想要获取数据就需要借助ContentResolver类。可以通过Context中的getContentResolver()方法获取实例。
- ContentResolver类与
SQLiteDatabase
类似,也具有insert()
,等四个增删改查方法。 - 但不同于
SQLiteDatabase
,他第一个参数接收的不是表名,而是Uri
参数。它由三部分组成:协议,authority,path。authority是用于对不同的应用程序做区分的,一般为了避免冲突,会采用应用包名的方式进行命名。path就是对同一应用不同的表做区分,就像表名。它的比较标准的格式如下:content://com.example.app.provider/table1
。只需要调用Uri.parse()方法,就可以将内容URI字符串解析成Uri对象了 - query()
它与数据库的参数很像,就是第一个不是表名,而是Uri。而且他的参数会更加简单一点。
它返回的也是一个cursor对象,对于cursor对象,只需要遍历,并且按照列数完成对每一列的读取即可。 - insert() 它接收是也是Uri对象和contentValues对象。
1
2val values = contentValuesOf("column1" to "text", "column2" to 1)
contentResolver.insert(uri, values) - update() 这里使用了selection和selectionArgs参数来对想要更新的数据进行约束
1
2val values = contentValuesOf("column1" to "")
contentResolver.update(uri, values, "column1 = ? and column2 = ?", arrayOf("text", "1")) - delete()
1
contentResolver.delete(uri, "column2 = ?", arrayOf("1"))
- query()
构建自己的ContentProvider
已知:只需要获得该应用程序的内容URI,然后借助ContentResolver进行增删改查操作就可以了,但是如何向外部提供接口并保证数据的安全?
步骤:
- 新建一个类继承ContentProvider,然后重写其6个抽象方法。
(1) onCreate()。初始化ContentProvider的时候调用。通常会在这里完成对数据库的创建和升级等操作,返回true表示ContentProvider初始化成功,返回false则表示失败。
(2) query()。从ContentProvider中查询数据。uri参数用于确定查询哪张表,projection参数用于确定查询哪些列,selection和selectionArgs参数用于约束查询哪些行,sortOrder参数用于对结果进行排序,查询的结果存放在Cursor对象中返回。
(3) insert()。向ContentProvider中添加一条数据。uri参数用于确定要添加到的表,待添加的数据保存在values参数中。添加完成后,返回一个用于表示这条新记录的URI。
(4) update()。更新ContentProvider中已有的数据。uri参数用于确定更新哪一张表中的数据,新数据保存在values参数中,selection和selectionArgs参数用于约束更新哪些行,受影响的行数将作为返回值返回。
(5) delete()。从ContentProvider中删除数据。uri参数用于确定删除哪一张表中的数据,selection和selectionArgs参数用于约束删除哪些行,被删除的行数将作为返回值返回。
(6) getType()。根据传入的内容URI返回相应的MIME类型。
- uri解析
一个标准的uri写法content://com.example.app.provider/table1
这就表示调用方期望访问的是com.example.app这个应用的table1表中的数据。content://com.example.app.provider/table1/1
表示调用方期望访问的是com.example.app这个应用的table1表中id为1的数据
- *表示匹配任意长度的任意字符。
#
表示匹配任意长度的数字。
一个能够匹配任意表的内容URI格式就可以写成:content://com.example.app.provider/*
一个能够匹配table1表中任意一行数据的内容URI格式就可以写成:content://com.example.app.provider/table1/#
UriMatcher
类有两个方法:
- addURI():接收三个参数分别把authority,path和一个自定义代码传进去
- match():接收一个uri对象作为参数。能够匹配到这个uri对象的自定义代码
URI所对应的MIME字符串主要由3部分组成,Android对这3个部分做了如下格式规定。
- 必须以vnd开头。
- 如果内容URI以路径结尾,则后接
android.cursor.dir/
;如果内容URI以id结尾,则后 - 接
android.cursor.item/
。 - 最后接上vnd.
. 。