运行时权限检查
概括
简单粗暴的来说一下,在 Android 6.0 即 API 23 之前,我们用到的权限只需要在 AndroidManifest 文件中统一进行申请就可以了,而且用户不可取消!
但是在 6.0 及以上,出于安全性考虑,开始由用户掌握了部分主动权!
Android 中的系统权限可以分为 normal 和 dangerous 两种。
normal 这类的权限不太会直接威胁到用户的隐私,只需要在 Manifest 文件中注册即可;
dnagerous 这类的权限使得 app 可以直接访问用户的一些隐私数据,从 Android 6.0 开始,这些权限就不仅仅只需要在 Manifest 文件中声明,而且需要在运行且适当的时候进行动态的申请,由用户决定是否授权,并且用户可以随时取消这些权限(在设置里的应用详细信息界面取消)。如果不进行权限检查而贸然执行一些“危险”的动作的话,应用可能是会崩溃的。
Dangerous Permissions List
这里只给出 dangerous 类的权限列表:
权限组 | 组内权限 |
---|---|
CALENDAR | READ_CALENDAR WRITE_CALENDAR |
CAMERA | CAMERA |
CONTACTS | READ_CONTACTS WRITE_CONTACTS GET_ACCOUNTS |
LOCATION | ACCESS_FINE_LOCATION ACCESS_COARSE_LOCATION |
MICROPHONE | RECORD_AUDIO |
PHONE | READ_PHONE_STATE CALL_PHONE READ_CALL_LOG WRITE_CALL_LOG ADD_VOICEMAIL USE_SIP PROCESS_OUTGOING_CALLS |
SENSORS | BODY_SENSORS |
SMS | SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEIVE_MMS |
STORAGE | READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE |
如上表,权限被分组了,值得一提的是 同一组中的任何一个权限被授权了,其他权限也就自动被授权了。
最基本的使用步骤
申请授权一般需要三步:
- 检查权限是否已经授权
- 申请用户授权
- 处理授权结果
好在 Android 提供了相应的 API 使得我们开发便利许多,下面以申请 “读取联系人权限” 为例展开这三个步骤。
第一步,检查权限是否已经授权:
//读取联系人的权限
String permission = Manifest.permission.READ_CONTACTS;
//检查权限是否已授权
int hasPermission = checkSelfPermission(permission);
只需要调用 checkSelfPermission(String permission) 方法,参数为 权限字符串。
如果是已授权的权限,该方法返回结果是 PackageManager.PERMISSION_GRANTED 常量为 0,
如果是未授权的权限,该方法返回结果是 PackageManager.PERMISSION_DENIED 常量为 -1。
第二步,对未授权权限 申请用户授权
//读取联系人的权限
String permission = Manifest.permission.READ_CONTACTS;
//检查权限是否已授权
int hasPermission = checkSelfPermission(permission);
//如果没有授权
if (hasPermission != PackageManager.PERMISSION_GRANTED) {
//请求权限,此方法会弹出权限请求对话框,让用户授权,并回调 onRequestPermissionsResult 来告知授权结果
requestPermissions(new String[]{permission}, REQUEST_CODE_ASK_SINGLE_PERMISSION);
}else {
//已经授权过
//做一些你想做的事情,即原来不需要动态授权时做的操作
doSomething();
}
需要调用 requestPermissions(@NonNull String[] permissions, int requestCode) 方法,该方法需要传入两个参数:
参数1:String[] permissions 是一个字符串数组,即要申请的权限的字符串数组,同时也说明了,可以一次性申请多个权限,用户会一个一个进行授权
参数2:int requestCode 是一个 int 常量,此处为代表请求码,在第三步中可能会用到
注意: