关闭

关于android6.0及以上版本运行时权限的学习笔记

标签: android运行时权限
66人阅读 评论(0) 收藏 举报
分类:

最近在做一个查询联系人的小功能的时候,出现了以下错误:

Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{374d058 4051:com.beasy.SiDaZuJian.www/u0a63} (pid=4051, uid=10063) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS

毫无疑问,这是一个关于权限的错误,但是我在AndroidManifest里面已经加了读取和写入联系人的权限了。经过在网上的搜索查阅之后我才发现这是一个关于SDK版本的问题,android6.0带来了许多变化,其中之一就是关于权限的变化,它被分为普通权限(Normal Permissions)和运行时权限(Dangerous Permission),这更好的保护了android手机用户的隐私

  • 普通权限(Normal Permissions)
    例如访问网络、链接WIFI,这些权限一般不泻需要获取用的隐私信息,所以不需要用户自己手动授权

  • 运行时权限(Dangerous Permission)
    例如访问SD卡,获取联系人,这些权限一般都要获取用户的隐私信息,需要用户自己手动授权


下面放上我修改后的代码:

 public final static int READ_CONTACTS_CODE = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_content_provider);
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS},
                    READ_CONTACTS_CODE);
        } else {
            LogInfo();
        }

    }

    public void LogInfo() {
        ContentResolver cr = getContentResolver();
        Cursor c = cr.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME}, null, null, null);
        if (c != null) {
            while (c.moveToNext()) {
                Log.i("info", "_id:" + c.getInt(c.getColumnIndex("_id")));
                Log.i("info", "name:" + c.getString(c.getColumnIndex("display_name")));
            }
        }
        c.close();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case READ_CONTACTS_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    LogInfo();
                } else {
                    Toast.makeText(ContentProviderActivity.this, "无法获取权限!", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED 是用来检查是否已经获取了读取联系人的权限,PackageManager.PERMISSION_GRANTED 是已经授权, PackageManager.PERMISSION_DENIED 是还未授权;

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, READ_CONTACTS_CODE) 申请授权,三个传入参数分别为context,权限和用于回调时检测的唯一值;

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 是回调函数,其中的参数 grantResults 是用户授权结果

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:602次
    • 积分:87
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:2篇
    • 译文:0篇
    • 评论:0条
    文章分类