自从Android在6.0引入动态权限,各种坑接踵而来,今天有时间专门整理一下动态权限的那些事。
一、动态权限基本知识group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
以上是需要动态申请的权限,一共9组,每组只要一个申请成功,这个组的权限默认就可以使用了。
申请的前提条件: 1.targetSdkVersion >= 23(废话)
2.在AndroidManifest.xml中申请
申请权限: 1.checkSelfPermission() 检查是否有此权限,没有则申请,有了直接可以向下执行
2.shouldShowRequestPermissionRationale() 这个是被拒绝后再次申请权限时对用户的解释,我基本不用此方法
3.requestPermissions() 申请权限,弹出一个对话框,用户是否允许开启此权限
举个例子:
private static final int STORAGE_CODE = 1;
private void requestStoragePermission() {
if ((ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)){//无此权限,申请
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
STORAGE_CODE);
}else {
//已经拥有此权限
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == STORAGE_CODE) {
int grantResult = grantResults[0];
boolean granted = grantResult == PackageManager.PERMISSION_GRANTED;
if (granted) {
//申请权限同意
} else {
//申请权限拒绝了
}
}
}
二、动态权限的坑
1.申请扫描附近的wifi,需要申请位置权限
2.有两个特殊的权限,SYSTEM_ALERT_WINDOW和WRITE_SETTINGS和以上介绍的权限申请有所区别,这俩权限需要开启一个页面,让用户打开权限,不是弹出窗!!
开启热点就需要WRITE_SETTINGS这个权限,上例子
private final static int REQUEST_CODE = 1;
private void requestWriteSettingPermission() {
if (!Settings.System.canWrite(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (Settings.System.canWrite(this)) {
//WRITE_SETTINGS permission granted
} else {
//WRITE_SETTINGS permission not granted
}
}
}
步骤:
1.使用Action Settings.ACTION_MANAGE_WRITE_SETTINGS 启动隐式Intent
2.使用"package:" + getPackageName()携带App的包名信息
3.使用Settings.System.canWrite方法检测授权结果
另外:申请SYSTEM_ALERT_WINDOW权限的话 第三步使用Settings.canDrawOverlays()判断就好了
如果觉得帮助,欢迎打赏!