Android M动态申请获取权限android.permission.READ_PHONE_STATE

Android M对应用的授权策略做了变动,如果我们想调用getDeviceId()获取手机串码,只在Manifest里添加android.permission.READ_PHONE_STATE权限是不够的,如果不做权限的动态申请和处理,可能会报如下错误:

 AndroidRuntime: java.lang.SecurityException: getDeviceId: Neither user 10201 nor current process has android.permission.READ_PHONE_STATE.
 
 
  • 1
  • 1

那如何在代码中动态申请权限呢?分四步进行:

第一步,在Manifest文件中添加权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
 
  • 1
  • 1

第二步, 要获取权限进行操作的Activity实现 ActivityCompat.OnRequestPermissionsResultCallback接口(这一步貌似不是必须):

public class MainActivity extends Activity
        implements ActivityCompat.OnRequestPermissionsResultCallback {
 
 
  • 1
  • 2
  • 1
  • 2

第三步,动态申请权限并做处理:

        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);

        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
        } else {
            //TODO
        }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

第四步, 重写onRequestPermissionsResult()方法,对权限申请结果做处理:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_READ_PHONE_STATE:
            if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                //TODO
            }
            break;

        default:
            break;
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

下面对关键方法做一个解释:

1、检查是否有权限: 
ActivityCompat.checkSelfPermission

eg:检查是否有读取联系人权限 
ActivityCompat.checkSelfPermission(this,Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED

2、是否重新请求授权(用户之前拒绝过): 
ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_CONTACTS) 
如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true,意思是说要给用户一个 解释,告诉用户为什么要这个权限。 
然而,在实际开发中,很多手机对原生系统做了修改,比如小米4的6.0的shouldShowRequestPermissionRationale 就一直返回false,而且在申请权限时,如果用户选择了拒绝,则不会再弹出对话框了。如果是这样,我们可以在回调里面处理,如果用户拒绝了这个权限,则打开本应用信息界面,由用户自己手动开启这个权限。

3、请求授权: 
ActivityCompat.requestPermissions 
注意的是,调用此方法后,系统会弹出一个权限申请框,供用户选择,这个选择框我们无法更改: 
这里写图片描述

而且此时activity会调用onPause()方法,用户做了选择之后,此对话框消失,onResume()方法又会执行。

注:在华为设备上测试,如果用户勾选了“不再询问”的选项的话,shouldShowRequestPermissionRationale会返回false。而且如果再次调用requestPermissions申请权限,就不会有申请框弹出,而是直接返回申请失败。但是activity的生命周期方法的执行顺序和有系统提示框弹出时的顺序是一样的。

4、搜权结果,通过 ActivityCompat.OnRequestPermissionsResultCallback 回调获取授权结果,判断是否授权。

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_INFO_OF_PHONE_SETTINGS) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                L.d("imei", "permission is granted after requested!");
            } else if (grantResults[0] == PackageManager.PERMISSION_DENIED){
                L.d("imei", "permission is not granted after requested!");
                //这里表示申请权限后被用户拒绝了
            } else {
                L.d("imei", "permission is not granted after requested!");
            }
        }
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值