Android M对应用的授权策略做了变动,如果我们想调用getDeviceId()获取手机串码,只在Manifest里添加android.permission.READ_PHONE_STATE权限是不够的,如果不做权限的动态申请和处理,可能会报如下错误:
- 1
- 1
那如何在代码中动态申请权限呢?分四步进行:
第一步,在Manifest文件中添加权限:
- 1
- 1
第二步, 要获取权限进行操作的Activity实现 ActivityCompat.OnRequestPermissionsResultCallback接口(这一步貌似不是必须):
- 1
- 2
- 1
- 2
第三步,动态申请权限并做处理:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
第四步, 重写onRequestPermissionsResult()方法,对权限申请结果做处理:
- 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 回调获取授权结果,判断是否授权。