从Android6.0开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。同时系统默认为targetSdkVersion
小于23的应用授予了所申请的所有权限。
系统权限
系统权限分为两类:正常权限和危险权限
- 正常权限不会直接给用户隐私权带来风险。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。
- 危险权限会授予应用访问用户机密数据的权限。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。如果您列出了危险权限,则用户必须明确批准您的应用使用这些权限。
每个危险权限都属于一个权限组,我们在运行时权限处理时使用权限名,用户一旦同意授权了,那么该权限组中其他权限也将同时被授权。
权限组名 | 权限名 |
---|---|
CALENDAR | READ_CALENDAR WRITE_CALENDAR |
CAMERA | CAMERA |
CONTACTS | READ_CONTACTS WRITE_CONTACTS GET_ACCOUNTS |
LOCATION | ACCESS_COARSE_LOCATION ACCESS_FINE_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 |
请求权限
检查权限
如果应用需要危险权限,则每次执行需要这一权限的操作时都必须检查自己是否具有该权限。
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)
== PackageManager.PERMISSION_GRANTED) {
callPhone();
}
如果应用具有此权限,方法将返回PackageManager.PERMISSION_GRANTED
,否则返回PackageManager.PERMISSION_DENIED
private void callPhone() {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
请求权限
调用ActivityCompat.requestPermissions()
方法来申请我们需要的权限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CALL_PHONE},
REQUEST_CODE_CALL_PHONE);
系统将通过Activity
的onRequestPermissionsResult()
方法返回结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE_CALL_PHONE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
callPhone();
} else {
Toast.makeText(this,"权限被拒绝",Toast.LENGTH_LONG).show();
}
}
}
如果选择【Deny】,那么下次请求的时候会有一个【Don’t ask again】的选项,选择后不会再有提示框。
由于每次请求都会被拒绝,为了有一个好的用户提现,需要ActivityCompat.shouldShowRequestPermissionRationale()
方法。当【Don’t ask again】被选择后,该方法返回false
。
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE_CALL_PHONE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
callPhone();
} else {
Toast.makeText(this, "权限被拒绝", Toast.LENGTH_LONG).show();
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CALL_PHONE)) {
new AlertDialog.Builder(this)
.setMessage("该功能需要电话访问权限")
.setPositiveButton("确认", null)
.create().show();
}
}
}
}