Android系统从6.0开始对一些危险的权限进行了动态获取权限。
动态获取权限流程大概如下:
当用户的操作涉及到获取一些危险的权限时,我们要及时的检测是否已经获取了该权限,如果没有获取,应及时的去动态获取。
在检测是否已经获取相关权限时要注意一个问题,要看一下build.gradle中targetSdkVersion的版本。
当targetSdkVersion >= 23时使用:
context.checkSelfPermission(android.Manifest.permission.CAMERA)
如果是已授权结果等于PackageManager.PERMISSION_GRANTED > 0,
如果是未授权结果等于PackageManager.PERMISSION_DENIED > -1。
经测试使用targetSdkVersion < 23时的方法也是可行的。
----------------------------------------------------------------------------------------------------------------
当targetSdkVersion < 23时使用:
PermissionChecker.checkSelfPermission(context, android.Manifest.permission.CAMERA)
如果是已授权结果等于PackageManager.PERMISSION_GRANTED > 0,
如果是未授权结果等于PackageManager.PERMISSION_DENIED > -2
经测试当argetSdkVersion < 23 时,使用targetSdkVersion >= 23的方法检测权限是否获取时,不管有没有获取到权限,返回结果都是 > 已授权 > 0,所以不能用这个。
----------------------------------------------------------------------------------------------------------------
当检测到没有获取到权限时,判断Android系统是否大于等于6.0,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M。
如果小于6.0弹框提示用户手动开启权限,因为小于6.0去动态获取权限根本不会弹出申请权限的提示框。
如果大于等于6.0,执行动态申请权限的代码:
如果是在Activity中获取:ActivityCompat.requestPermissions()
如果是在Fragment中获取:fragment.requestPermissions()
实现OnRequestPermissionsResultCallback接口,在onRequestPermissionsResult回调中判断是否获取到了权限。如果系统版本大于6.0而且也动态申请权限了,还是没有弹框,有可能是第一次弹框时,用户点“拒绝”并且选择了“不再提示”,这时是不会再弹出申请权限提示框的,就得需要用到下面说的“申请权限结果回调”中使用的方法:
boolean shouldShow = ActivityCompat.shouldShowRequestPermissionRationale(activity,permission);
如果返回true表示用户点了禁止获取权限,但没有勾选不再提示。
返回false表示用户点了禁止获取权限,并勾选不再提示。
-----------------------------------------------以下是实现代码--------------------------------------------
检查是否已经获取了权限:
int permissioncamera;
int permissionaudio;
// 判断targetSdkVersion 是否大于等于23,这个都是自己写的,一般也不用判断,直接根据自己的版本选择方法就行
if (getActivity().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.M) {
//因为是在fragment中,所以使用的getActivity()
permissioncamera = getActivity().checkSelfPermission(android.Manifest.permission.CAMERA);
permissionaudio = getActivity().checkSelfPermission(android.Manifest.permission.RECORD_AUDIO);
} else {
permissioncamera = PermissionChecker.checkSelfPermission(getActivity(), android.Manifest.permission.CAMERA);
permissionaudio = PermissionChecker.checkSelfPermission(getActivity(), android.Manifest.permission.RECORD_AUDIO);
}
//如果两个都没获取到,直接申请两个,如果其中一个已获取,只获取另一个权限。
if (permissioncamera != PackageManager.PERMISSION_GRANTED && permissionaudio != PackageManager.PERMISSION_GRANTED) {
TestFragment.this.requestPermissions(new String[]{android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}, 1);
} else if (permissioncamera != PackageManager.PERMISSION_GRANTED && permissionaudio == PackageManager.PERMISSION_GRANTED) {
TestFragment.this.requestPermissions(new String[]{android.Manifest.permission.CAMERA}, 1);
} else if (permissioncamera == PackageManager.PERMISSION_GRANTED && permissionaudio != PackageManager.PERMISSION_GRANTED) {
TestFragment.this.requestPermissions(new String[]{android.Manifest.permission.RECORD_AUDIO}, 1);
}
//Fragment中动态申请获取权限:
TestFragment.this.requestPermissions(new String[]{android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}, 1);
//Activity中动态申请获取权限:
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}, 1);
//requestPermissions中的最后一个参数对应onRequestPermissionsResult中的requestCode,
//requestPermissions中的new String[]对应onRequestPermissionsResult中的permissions
申请权限结果回调:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// 通过grantResults判断有没有获取到权限,如果没有,用下面的方法判断用户点禁止的时候有没有勾选不在提示。
for (String permission : permissions) {
//如果返回true表示用户点了禁止获取权限,但没有勾选不再提示。
//返回false表示用户点了禁止获取权限,并勾选不再提示。
//我们可以通过该方法判断是否要继续申请权限
boolean shouldShow = ActivityCompat.shouldShowRequestPermissionRationale(activity,permission);
}
}
/*
相关参数:
可以通过requestCode来判断执行的哪一个申请授权的回调,
permissions是申请的权限数组,
grantResults为申请的权限数组的结果,0表示获取成功,可以通过grantResults的结果给用户相应的提示。
permissions和grantResults数组顺序是一一对应的。
*/