Android开发团队在6.0系统中加入运行时权限的功能,用户不需要在安装软件的时候一次性授权所有的权限,而是可以在软件使用过程中对某一权限进行授权。Android 将所有权限分为两类,一类是普通权限,一类是危险权限。
- 普通权限:不会直接威胁到用户的安全及隐私,系统会自动帮我们授权。
- 危险权限:那些可能触及用户的隐私,或者设备安全性的权限,比如设备联系人信息,定位设备地理位置等。
- 危险权限一共9组24个权限,分别为GALENDAR,CAMERA,CONTACTS,LOCATION,MICROPHONE,PHONE,SENSORS,SMS,STORAGE。在进行运行时权限处理使用的是权限名,一旦用户授权了,那么该组内的其他权限也同时被授权。
申请权限封装到 BaseActivity
public class BaseActivity extends AppCompatActivity {
private Activity activity = null;
private PermissionListener mListener;
private ArrayList<String> requestPermissionList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = this;
setContentView(R.layout.activity_base);
}
/**
* 请求权限
* @param permissions 权限组
* @param listener 权限回调
*/
protected void handlePermissions(String[] permissions, PermissionListener listener) {
if (permissions == null || activity == null) {
return;
}
mListener = listener;
requestPermissionList = new ArrayList<>();
//检验权限是否已授权,未授权则添加到集合中
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
requestPermissionList.add(permission);
}
}
//申请未授权的权限
if (!requestPermissionList.isEmpty()) {
ActivityCompat.requestPermissions(this,
requestPermissionList.toArray(new String[requestPermissionList.size()]), 1);
} else {
listener.onGranted();
}
}
/**
* 授权返回方法
* @param requestCode 请求码
* @param permissions 权限数组
* @param grantResults 授权结果
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
//处理授权结果,回调用户操作页面
case 1:
if (grantResults.length > 0) {
ArrayList<String> deniedPermission = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
String permission = permissions[i];
if (grantResult != 0) {
deniedPermission.add(permission);
}
}
if (!deniedPermission.isEmpty()) {
mListener.onDenied(deniedPermission);
} else {
mListener.onGranted();
}
}
break;
default:
}
}
}
申请权限的页面请求权限
public class PermissionActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission);
requestPermissionStatus();
}
private void requestPermissionStatus() {
handlePermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionListener() {
@Override
public void onGranted() {
//请求权限成功后,进行业务逻辑处理...
Toast.makeText(PermissionActivity.this, "成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onDenied(List<String> deniedPermissions) {
boolean allNeverAskAgain = true;
for (String deniedPermission : deniedPermissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(PermissionActivity.this,deniedPermission)) {
allNeverAskAgain = false;
break;
}
}
//禁止并勾选不在询问后,弹窗引导用户手动进入应用信息页面手动授权
if (allNeverAskAgain) {
Dialog dialog = new AlertDialog.Builder(PermissionActivity.this,R.style.GifFunAlertDialogStyle)
.setMessage("请在权限管理中心中允许权限")
.setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", PermissionActivity.this.getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
})
.setNegativeButton("取消",null)
.create();
dialog.show();
} else {
Toast.makeText(PermissionActivity.this,"权限被拒绝,无法进行操作",Toast.LENGTH_SHORT).show();
}
}
});
}
}
当使用 WindowManager 时,请求权限,requestPermissions 方法将会失效,不会有弹窗提示,需要以下方法获取权限。
@TargetApi(Build.VERSION_CODES.M)
private void getOverlayPermission() {
if (!Settings.canDrawOverlays(MainActivity.this)) {
Toast.makeText(this, "can not DrawOverlays", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + MainActivity.this.getPackageName()));
startActivityForResult(intent, 1);
} else {
// Already hold the SYSTEM_ALERT_WINDOW permission, do addview or something.
}
}
//启动设置页面用户手动设置后,判断是否已授权。
@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (!Settings.canDrawOverlays(this)) {
// SYSTEM_ALERT_WINDOW permission not granted...
} else {
// Already hold the SYSTEM_ALERT_WINDOW permission, do addview or something.
}
}
}