Andorid在M之后 将原有权限系统进行了重新的设计 ,将权限分为两大块分别是NormalPermission 和Dangerous Permission 。不管是哪种权限都和M之前的系统一样 只要使用就需要在清单文件中进行注册 ,但是对于Dangerous Permission 这样做还远远不够 ,开发者必须要动态的在代码使用权限的地方进行申请,必须经过用户同意之后才可以使用相应的权限。官方文档给出的Dangerous Permission 如下所示:
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
申请方式主要是分为三步:
1、检查运行时权限
ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.READ_SMS)!= PackageManager.PERMISSION_GRANTED
检查是否有权限 如有则执行相应代码,没有则执行第二步 向用户申请权限
2、动态申请权限
ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, READ_SMS_CODE);
申请权限 最后申请的结果会在onRequestPermissionsResult 方法中处理即第三步
3、接受权限处理结果
@Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
switch (requestCode) {
case READ_SMS_CODE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//权限同意 TODO
} else {
//权限决绝 TODO
}
return;
}
}
}
以上就是官方文档的处理方式,当然还有shouldShowRequestPermissionRationale 方法,此方法是当用户第一次拒绝权限后 第二次在弹出 是 申请权限对话框又多一个选项:不在提示,当用户勾选了后 会返回true 这个时候需要给用户相应的申请权限解释。
按照这个方式去处理6.0的动态权限会觉得很繁琐 所以 EasyPermissions 开源框架 应运而生。
首先引入库
dependencies {
compile 'pub.devrel:easypermissions:0.2.1'
}
EasyPermission提供了一个接口 里面有两个方法需要开发者自己实现 即需要动态申请权限的页面实现此接口
public interface PermissionCallbacks extends
ActivityCompat.OnRequestPermissionsResultCallback {
void onPermissionsGranted(int requestCode, List<String> perms); //权限同意
void onPermissionsDenied(int requestCode, List<String> perms); //权限拒绝
}
此外还需要在本身的权限回调方法中将处理结果交由EasyPermission处理
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
检查权限
@AfterPermissionGranted(CALL_PHONE)
public void requestCallPhonePermission() {
String[] perms = {Manifest.permission.CALL_PHONE};
if (EasyPermissions.hasPermissions(this.getContext(), perms)) {
call();
} else {
EasyPermissions.requestPermissions(this, "xxx请求拨打电话权限!", CALL_PHONE, perms);
}
}
此方法的方法名称随意起,hasPermissions 是检查app是否已经拥有此权限 如有则执行相应代码,如没有则调用requestPermissions 去申请权限 。权限申请的结果会回调到我们刚刚实现的那个接口中去处理。大家会看到 给这个方法加了注解 @AfterPermissionGranted(CALL_PHONE) 这个注解的代表的是 当申请的权限用户同意之后 在调用此方法其中参数CALL_PHONE代表的是request_code 。
但用户勾选不在提示弹框的时候 我们扔然需要给用户做出相应的解释。在onPermissionsDenied 中处理权限拒绝后的逻辑 如下:
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this, "为了您能使用拨打电话功能,请开启打电话权限!")
.setTitle("提示")
.setPositiveButton("去设置")
.setNegativeButton("取消", null)
.setRequestCode(CALL_PHONE)
.build()
.show();
}
}
这样就OK了 ,EasyPermissions框架就是将我们上面所讲的方式进行了二次封装,是我们的开发更加便捷和易懂。
最后附上EasyPermissions完整处理逻辑代码:
public class TestActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
private static final int CALL_PHONE = 0x01;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
TextView mTvCallPhone = (TextView) findViewById(R.id.tv_contacts);
mTvCallPhone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
requestCallPhonePermission();
}
});
}
@AfterPermissionGranted(CALL_PHONE)
public void requestCallPhonePermission() {
String[] perms = {Manifest.permission.CALL_PHONE};
if (EasyPermissions.hasPermissions(this, perms)) {
call();
} else {
EasyPermissions.requestPermissions(this, "xxx请求拨打电话权限!", CALL_PHONE, perms);
}
}
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
//权限同意
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
//权限拒绝
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this, "为了您能使用电话功能,请开启打电话权限!")
.setTitle("提示")
.setPositiveButton("去设置")
.setNegativeButton("取消", null)
.setRequestCode(CALL_PHONE)
.build()
.show();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
}