为什么要在说权限申请的时候,说targetSdkVersion呢!其实是有原因的,因为目标版本的值的修改,对权限的申请检查是有很大的影响!
例如当targetSdkVersion版本小于23(6.0)的时候,其在编译的时候,不会对权限申请去进行判断,只有在运行过程中才会知道。
当targetSdkVersion大于等于23的时候,就会在编译时候检查代码是否有申请权限的判断。也就会有如下提示:
Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with `checkPermission`) or explicitly handle a potential `SecurityException
消除这个错误,可以降低targetSdkVersion版本号(<23)或者在具体操作前在进行一次对权限申请的判断即可。(以下代码会有说明)。
说完了targetSdkVersion后,再来说权限申请过程。
权限分为普通权限和危险权限。普通权限在AndroidMainfest中直接申请。
其中所有的普通权限如下:
所有的危险权限:
危险权限需要在使用的时候,才去申请该权限。用户同意就开启,不同意就不能使用该功能!其中运行时权限如下所示:(运行时权限,使用到如下权限,必须进行判断是否有申请权限–分大类)
1.Calendar
2.Camera
3.Contacts
4.Location
5.MICROPhone
6.Phone
7.Sms
8.Sensors
9.Storage
具体细小的分类如下:
简单的一个打电话申请权限事例,targetSdkVersion版本在23
/**
* 拨打电话
*/
mCreateDB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 如果没有权限,判断不相等,就去申请权限
* Manifest.permission.CALL_PHONE 表示打电话需要申请的权限
* 1,表示申请的标示嘛
*/
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CALL_PHONE}, 1);
} else {
//有权限,直接呼出去
Call();
}
}
});
}
private void Call() {
try {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10000"));
/**
* targetSdkVersion在23时,在具体操作前,会进一步判断是否是否有申请权限
* 避免程序崩溃,
*/
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
//用户同意或者拒绝(动作)后的回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 1:
//授权的结果会封装在gransResults中
if(grantResults.length >0 && grantResults[0]==PackageManager.PERMISSION_GRANTED) {
Call();
}else {
Toast.makeText(this,"您应该同意该权限",Toast.LENGTH_LONG).show();
}
break;
default:
}
}
以上:在用户同意该权限后,下次进来就不需要在申请权限了,如果拒绝该权限后,如果再次想使用该功能,则又会让用户去申请!
如果有多个权限需要用户去申请,我们可以不必一个一个去申请,学习一下向下面的写法:
//进行运行时权限处理,定义权限集合
List permissionList = new ArrayList<>();
//读取手机联系人,需要权限,并添加到权限集合中
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission.READ_CONTACTS);
}
//地理位置权限
if (ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(ACCESS_COARSE_LOCATION);
}
//申请权限
if (!permissionList.isEmpty()) {
//将集合转化成数组
String[] permissions = permissionList.toArray(new String[permissionList.size()]);
ActivityCompat.requestPermissions(this, permissions, 1);
} else {
//说明授权了
readContactData();
}
//多个权限响应
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if(grantResults.length > 0) {
//拒绝权限集合
List refusePermissions = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
String permission = permissions[i];
if(grantResult != PackageManager.PERMISSION_GRANTED) {
refusePermissions.add(permission);
}
}
if(refusePermissions.isEmpty()) {
//说明都授权了
readContactData();
}else {
//未授权
}
}
break;
default:
}
}
再高版本的基础库中例如26版本中,是需要实现ActivityCompat.OnRequestPermissionsResultCallback接口,才能有所回调响应
如下图:
public class PermissionContact implements ActivityCompat.OnRequestPermissionsResultCallback{
private static PermissionContact mPermissionContact;
private Activity mActivity;
public static PermissionContact getInstance() {
if (mPermissionContact == null) {
mPermissionContact = new PermissionContact();
}
return mPermissionContact;
}
public void ApplyPermission(Activity activity) {
mActivity = activity;
List permissionList = new ArrayList<>();
if(ActivityCompat.checkSelfPermission(activity, Manifest.permission_group.STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission_group.STORAGE);
}
if(ActivityCompat.checkSelfPermission(activity, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission.RECEIVE_SMS);
}
if(ActivityCompat.checkSelfPermission(activity, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission.CALL_PHONE);
}
if(ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission.READ_PHONE_STATE);
}
if(ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if(ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission.READ_CONTACTS);
}
if(!permissionList.isEmpty()) {
String[] permissions = permissionList.toArray(new String[permissionList.size()]);
ActivityCompat.requestPermissions(activity,permissions,1);
}else {
// 说明都授权了
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1 :
if(grantResults.length > 0) {
//拒绝权限集合
List refusePermissions = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
String permission = permissions[i];
if(grantResult != PackageManager.PERMISSION_GRANTED) {
refusePermissions.add(permission);
}
}
if(refusePermissions.isEmpty()) {
//说明都授权了
}else {
//未授权
Toast.makeText(mActivity,"拒绝权限",Toast.LENGTH_SHORT).show();
}
}
break;
}
}
}
所以,还是要注意不同版本的区别
或者直接用开源库 Easy Permissions处理权限 或者 Permissions DisPatcher处理
以上: