Android学习笔记(八)

本文详细介绍了Android系统的权限机制,包括运行时权限的概念及其应用,特别关注危险权限如打电话和读取联系人的处理。此外,深入探讨了内容提供器(ContentProvider)的工作原理,如何通过ContentResolver访问数据,以及自定义内容提供器的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内容提供器主要是为了程序之间共享数据,同时还保证安全性。

运行时权限

权限机制:用户在安装程序时会得到程序获得的权限的提醒,同时用户能够查看任意一个程序获得的权限。运行时权限是为了用户能够在程序运行过程中为软件授权而不需要在安装时一次性授权。权限分为危险权限和普通权限,普通权限系统自动授权,危险权限需要用户手动授权。

由于打电话是危险权限,需要在运行时授权。
首先用ContextCompat查询当前是否有权限,那么就向ActivityCompat的requestPermissions方法传入一个权限数组,申请权限。如果有权限直接拨打电话。

    public void onClick(View v) {
        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(MainActivity.this,new
                    String[]{Manifest.permission.CALL_PHONE},1);
        }else{
            call();
        }
    }

需要对用户的授权结果进行处理,重写onRequestPermissionsResult方法,如图:

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    call();
                }else{
                    Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }

访问其他程序中的数据

ContentResolver

通过getContentResolver获取该类的实例,提供了一系列方法insert(),update(),delete(),query(),与Sqlite不同,表明变成了内容URI,格式如下:
content://com.example.app.provider/table1,com.example.app是包名,com.example.app.provider是authority,table1是path。

然后需要将内容URI通过Uri.parse转化为URI对象。
Uri uri = Uri.parse(content://com.example.app.provider/table1;

就可以通过uri来查询记录了

Cursor cursor = getContentResolver.query(
    uri,
    projection,
    selection,
    selectionArgs,
    sortOrder();
)

uri指定表,projection指定列,selection指定where后面的条件,selectionArgs指定条件上的占位符,sortOrder()指定排序方式。返回的是一个Cursor,需要对每一行进行遍历,然后取出一行中的值。

读取系统联系人

首先去获取运行时权限:

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)!=
                PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this,new String[]{
                    Manifest.permission.READ_CONTACTS},1);
        }else{
            readContacts();
    }

使用getContentResolver().query()去获取系统联系人的数据,这里的ContactsContract.CommonDataKinds.Phone.CONTENT_URI是android封装好的URI对象

    cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.
                CONTENT_URI,null,null,null,null);

遍历游标,取出对象,封装成数组,通过adapter适配给ListView,最后完成系统联系人的显示。

自定义内容提供器

自定义MyProvider继承ContentProvider,重写6个方法。

使用通配符*,#
content://com.example.app.provider/*匹配所有表
content://com.example.app.provider/table1/#匹配一张表中的所有列

然后使用uriMatch这个方法来实现URI和功能之间的对应。所有的Provider必须提供getType方法,需要返回一个MIME类型,比如:content://com.example.app/table1是以路径结尾的,那么对应的MIME就是vnd.android.cursor.dir/vnd.com.example.app.provider.table1;而content://com.example.app/table1/1是以item结尾的,那么对应的MIME类型就是vnd.andorid.cursor.item/vnd.com.example.app.provide.table1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值