株洲品牌网站建设,淘宝无货源一键铺货软件,云南公司网站建设,望江县城乡建设局网站ContentProvider主要用于在不同的应用程序之间实现数据共享的功能#xff0c;它提供了一套完整的机制#xff0c;允许一个程序访问另一个程序中的数据#xff0c;同时还能保证被访问数据的安全性。 目前#xff0c;使用ContentProvider是Android实现跨程序共享数据的标准方…ContentProvider主要用于在不同的应用程序之间实现数据共享的功能它提供了一套完整的机制允许一个程序访问另一个程序中的数据同时还能保证被访问数据的安全性。 目前使用ContentProvider是Android实现跨程序共享数据的标准方式。 Android系统的权限机制设计得非常简单就是用户如果认可你所申请的权限就会安装你的程序如果不认可你所申请的权限那么拒绝安装就可以了。
而在Android 6.0系统中新增了运行时权限功能。
现在用户不需要在安装软件的时候一次性授权所有申请的权限而是可以在软件的使用过程中再对某一项权限申请进行授权。
比如一款相机应用在运行时申请了地理位置定位权限就算拒绝了这个权限也应该可以使用这个应用的其他功能而不是像之前那样直接无法安装它。
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)makeCall.setOnClickListener {if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) ! PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CALL_PHONE), 1)} else {call()}}}override fun onRequestPermissionsResult(requestCode: Int, permissions: ArrayString, grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)when (requestCode) {1 - {if (grantResults.isNotEmpty() grantResults[0] PackageManager.PERMISSION_GRANTED) {call()} else {Toast.makeText(this, You denied the permission, Toast.LENGTH_SHORT).show()}}}}private fun call() {try {val intent Intent(Intent.ACTION_CALL)intent.data Uri.parse(tel:10086)startActivity(intent)} catch (e: SecurityException) {e.printStackTrace()}}}ContentResolver的基本用法
ContentResolver中的增删改查方法都不接收表名参数而是使用一个Uri参数代替这个参数被称为内容URI。
内容URI给ContentProvider中的数据建立了唯一标识符它主要由两部分组成authority和path。
内容URI最标准的格式如下 content://com.example.app.provider/table1 content://com.example.app.provider/table2 得到了内容URI字符串之后我们只需要调用Uri.parse()方法就可以将内容URI字符串解析成Uri对象了。 val uri Uri.parse(“content://com.example.app.provider/table1”)
读取系统联系人 读取系统联系人示例写法如下省略了申请运行时权限部分
class MainActivity : AppCompatActivity() {private val contactsList ArrayListString()private lateinit var adapter: ArrayAdapterStringoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)adapter ArrayAdapter(this, android.R.layout.simple_list_item_1, contactsList)contactsView.adapter adapter……readContacts()}……private fun readContacts() {// 查询联系人数据contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null)?.apply {while (moveToNext()) {// 获取联系人姓名val displayName getString(getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))// 获取联系人手机号val number getString(getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))contactsList.add($displayName\n$number)}adapter.notifyDataSetChanged()close()}}
}创建ContentProvider的步骤: ContentProvider类中有6个抽象方法我们在使用子类继承它的时候需要将这6个方法全部重写。
class MyProvider : ContentProvider() {override fun onCreate(): Boolean {return false}override fun query(uri: Uri, projection: ArrayString?, selection: String?, selectionArgs: ArrayString?, sortOrder: String?): Cursor? {return null}override fun insert(uri: Uri, values: ContentValues?): Uri? {return null}override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: ArrayString?): Int {return 0}override fun delete(uri: Uri, selection: String?, selectionArgs: ArrayString?): Int {return 0}override fun getType(uri: Uri): String? {return null}}创建ContentProvider的步骤
onCreate() .初始化ContentProvider的时候调用通常会在这里完成对数据库的创建和升级等操作返回true表示ContentProvider初始化成功返回false则表示失败。 query () 从contentrovider中查询数据uri参数用于确定查询那张表projection 参数用于确定查询那些列selection和selectionArgs参数用于约束查询哪些行sortOrder参数用于对结果进行排序查询的结果存放在Cursor对象中返回。
insert()。向ContentProvider中添加一条数据。uri参数用于确定要添加到的表待添加的数据保存在values参数中。添加完成后返回一个用于表示这条新记录的URI。
update()。更新ContentProvider中已有的数据。uri参数用于确定更新哪一张表中的数据新数据保存在values参数中selection和selectionArgs参数用于约束更新哪些行受影响的行数将作为返回值返回。
delete()。从ContentProvider中删除数据。uri参数用于确定删除哪一张表中的数据selection和selectionArgs参数用于约束删除哪些行被删除的行数将作为返回值返回。
getType()。根据传入的内容URI返回相应的MIME类型。
实现跨进程数据共享
借助UirMatcher 这个类能够实现匹配内容URi的功能。 当调用UriMaticher的match方法时可以将一个Uri对象传入返回值是某个能够匹配这个Uri对象所对应的自定义代码利用这个代码就可以判断出调用方期望访问的是哪个表中的数据了
class MyProvider : ContentProvider() {private val table1Dir 0private val table1Item 1private val table2Dir 2private val table2Item 3private val uriMatcher UriMatcher(UriMatcher.NO_MATCH)init {uriMatcher.addURI(com.example.app.provider, table1, table1Dir)uriMatcher.addURI(com.example.app.provider , table1/#, table1Item)uriMatcher.addURI(com.example.app.provider , table2, table2Dir)uriMatcher.addURI(com.example.app.provider , table2/#, table2Item)}…override fun query(uri: Uri, projection: ArrayString?, selection: String?, selectionArgs: ArrayString?, sortOrder: String?): Cursor? {when (uriMatcher.match(uri)) {table1Dir - {// 查询table1表中的所有数据}table1Item - {// 查询table1表中的单条数据}table2Dir - {// 查询table2表中的所有数据}table2Item - {// 查询table2表中的单条数据}}…}…
}实现跨程序数据共享
getType()方法是所有的ContentProvider都必须提供的一个方法用于获取Uri对象所对应的MIME类型。一个内容URI所对应的MIME字符串主要由3部分组成Android对这3个部分做了如下格式规定
必须以vnd开头。
如果内容URI以路径结尾则后接android.cursor.dir/如果内容URI以id结尾则后接android.cursor.item/。
最后接上vnd.. 。
所以对于content://com.example.app.provider/table1这个内容URI它所对应的MIME类型就可以写成vnd.android.cursor.dir/vnd.com.example.app.provider.table1
对于content://com.example.app.provider/table1/1这个内容URI它所对应的MIME类型就可以写成vnd.android.cursor.item/vnd.com.example.app.provider.table1
实现跨进程数据共享在这里插入代码片 getType()方法中的逻辑如下所示
class MyProvider : ContentProvider() {…override fun getType(uri: Uri) when (uriMatcher.match(uri)) {table1Dir - vnd.android.cursor.dir/vnd.com.example.app.provider.table1table1Item - vnd.android.cursor.item/vnd.com.example.app.provider.table1table2Dir - vnd.android.cursor.dir/vnd.com.example.app.provider.table2table2Item - vnd.android.cursor.item/vnd.com.example.app.provider.table2else - null}
}