Android M 的动态权限解决方案
最近公司项目在内测用户群中发现严重问题,安卓6.0系统在声波配置的界面会闪退。毫无疑问那就是动态权限的问题,由于项目的 build.gradle 中 targetSdkVersion 23而代码中没有处理高危权限,抛出 Permission Denied异常而闪退。
下面列出可行解决的方案:
- 最简单的解决方案就是 把 build.gradle 中 targetSdkVersion 23 修改为 targetSdkVersion 22,在6.0的系统上运行的时候会使用原来的权限处理。然而这里有一个隐藏的问题,如果用户在应用权限中关闭所必须的权限,那么头疼的问题又来了,就需要第二种方案。作为程序员还是不要偷懒,多读书多看报,少吃零食早睡觉。。
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:support-annotations:23.3.0'
//需要注意如果有这样的依赖,则需要把 23.3.0,修改为22的版本。
.....
}
- Android系统包含默认的授权提示框, 但是我们仍需要设置自己来封装. 原因是系统提供的授权框, 会有不再提示的选项. 如果用户选择, 则无法触发授权提示. 使用自定义的提示页面, 可以给予用户手动修改授权的指导.这里我们就需要偷懒了,毕竟轮子那么多,拿来用总会有奇效。
我使用的 EasyPermission 进行封装调用一个方法即可检测运行时权限,还有很多第三方库。
public class BaseActivity extends AppCompatActivity implements
EasyPermissions.PermissionCallbacks {
private static final int RC_PERM = 123;
private CheckPermListener mListener;
public interface CheckPermListener {
void superPermission();
}
/*检测权限的方法
listener 权限通过回调
resString 权限的解释语句(引导用户开启权限)
mPerms 所需检测的权限
*/
@AfterPermissionGranted(RC_PERM)
public void checkPermission(CheckPermListener listener,int resString, String... mPerms) {
mListener = listener;
if (EasyPermissions.hasPermissions(this, mPerms)) {
mListener.superPermission();//回调
} else {
EasyPermissions.requestPermissions(this, getString(resString),
RC_PERM, mPerms);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == EasyPermissions.SETTINGS_REQ_CODE) {
//从设置界面返回
}
}
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
EasyPermissions.checkDeniedPermissionsNeverAskAgain(this,
getString(R.string.perm_tip),
R.string.setting, R.string.cancel, null, perms);
}
}
在其他Activity中只要extent BaseActivity 合适的触发条件直接调用方法即可,如:
@Override
protected void onResume() {
super.onResume();
checkPermission(
new BaseActivity.CheckPermListener() {
@Override
public void superPermission() {
//原来需要权限去完成的 工作写这里。。
}
}, R.string.ask_again,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE);
}
在依存于Activity的Fragment中使用参考如下:
((BaseActivity) getActivity()).checkPermission(
new BaseActivity.CheckPermListener() {
@Override
public void superPermission() {
toFindDevice(device);
}
}, R.string.ask_again,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_PHONE_STATE);
EasyPermission开源地址: https://github.com/googlesamples/easypermissions
高危权限列表:
联系作者
Github: https://github.com/forjrking
邮箱: forjrking@sina.com