1. 简介
从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限。它还让用户可以对应用的功能进行更多控制;例如,用户可以选择为相机应用提供相机访问权限,而不提供设备位置的访问权限。用户可以随时进入应用的“Settings”屏幕调用权限。
2. 分析
运行时请求权限主要有3种方法:
- Google官方示例
- EasyPermissions
- PermissionsDispatcher
这里主要讲Google官方示例和EasyPermissions。
3. 使用Google官方示例
官方示例是最简单的方法,不需要添加依赖库,只需要调用requestPermissions()方法。效果图如下图。
代码如下。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 23) {
requestPermission();
} else {
initFragment();
}
}
private void requestPermission() {
//1. 检查是否已经有该权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//2. 权限没有开启,请求权限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_RW_EXSTORAGE);
}else{
//权限已经开启,做相应事情
Log.i(TAG, "requestPermission: 权限已经开启");
initFragment();
}
}
//3. 接收申请成功或者失败回调
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == RC_RW_EXSTORAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//权限被用户同意,做相应的事情
Log.i(TAG, "onRequestPermissionsResult: 权限被用户同意");
initFragment();
} else {
//权限被用户拒绝,做相应的事情
Log.i(TAG, "onRequestPermissionsResult: 权限被用户拒绝");
onBackPressed();
}
}
}
4. 使用EasyPermissions
查看OSChina安卓客户端的开源项目,发现用的是EasyPermissions,果断试用一下EasyPermissions。优点是可以方便地添加解释对话框,而且可以设置回调函数。缺点是在某些自定义主题中文字显示会有问题。效果图如下图。
- 添加依赖库
dependencies {
compile 'pub.devrel:easypermissions:0.4.2'
}
- 添加接口和重写回调函数
public class MainActivity extends BaseAppCompatActivity implements EasyPermissions.PermissionCallbacks {
private final static int RC_CONTACTS = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myactivity_main);
requestContacts();
}
@AfterPermissionGranted(RC_CONTACTS)
private void requestContacts() {
//所要申请的权限
String perm = Manifest.permission.READ_CONTACTS;
if (EasyPermissions.hasPermissions(this, perm)) {//检查是否获取该权限
Log.i(TAG, "已获取权限");
syncContactToGlass(false, firstBind);
} else {
//第二个参数是被拒绝后再次申请该权限的解释
//第三个参数是请求码
//第四个参数是要申请的权限
EasyPermissions.requestPermissions(this, getResources().getString(R.string.no_read_contact_permission), RC_CONTACTS, perm);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// 把申请权限的回调交由EasyPermissions处理
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
//下面两个方法是实现EasyPermissions的EasyPermissions.PermissionCallbacks接口
//分别返回授权成功和失败的权限
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
Log.i(TAG, "获取成功的权限" + perms);
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
Log.i(TAG, "获取失败的权限" + perms);
}
}
5. 参考文档
googlesamples/easypermissions: Simplify Android M system permissions https://github.com/googlesamples/easypermissions
在运行时请求权限 | Android Developers https://developer.android.google.cn/training/permissions/requesting.html
系统权限 | Android Developers https://developer.android.google.cn/guide/topics/security/permissions.html#normal-dangerous
Android开源项目-Easypermissions - 简书 http://www.jianshu.com/p/2b3661928e66
Android 6.0运行时权限的申请使用及EasyPermissions的使用 - lzy的博客 - CSDN博客 http://blog.csdn.net/lylodyf/article/details/53158091
Android基础——适配安卓6.0新权限系统 - Hensen_的博客 - CSDN博客 http://blog.csdn.net/qq_30379689/article/details/57407306