在6.0以后的手机上出现了手动权限的问题,那么就需要使用到动态的权限问题。
首先要先知道是否有这个权限,也就是说要先进行权限判断:
方法一:
int permission1 = ContextCompat.checkSelfPermission(this,
Manifest.permission.CALL_PHPNE);
首先获取权限开启值(以电话权限为例,其他权限相同),进行判断:
if (permission1 != PackageManager.PERMISSION_GRANTED) {}
如果permission1 != 0 就说命没有权限进行动态申请权限。
方法二:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED
&& permission1 != PackageManager.PERMISSION_GRANTED) {
}
直接进行if判断是否该权限;
如果有则进行其他操作,如果没有则进行动态申请权限:
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE},
REQUEST_CODE_ASK_READ_PHONE_STATE);
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_CODE_ASK_READ_PHONE_STATE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.i("WelcomeActivity", "权限允许"); //判断游客token是否为空 if (MyApplication.TOKEN.equals("")) { //进行游客登录 requestPost(UrlData.TOURIST_LOGIN, UrlData.getTouristLogin()); } //开启handler handler.sendEmptyMessageDelayed(1, 1000); } else { Log.i("WelcomeActivity", "权限拒绝"); showFaiingDialog(); return; } return; } }
private void showFaiingDialog() { new AlertDialog.Builder(this) .setTitle("权限申请") .setMessage("开启存储空间、电话、相机权限") .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); return; } }).setCancelable(false) .setPositiveButton("去设置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startSettings(); } }).show(); }
这样就可以做到权限的判断以及动态开启了;private void startSettings() { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent); }
但是还有一种情况就是在不使用到此功能时不会有任何问题,如果一旦用到则会因为没有权限问题而崩溃,例如相机;
所有,我在调用相机时会进行try{}cach{},以判断是否有权限,和上面相同的,在try内正常写入调用相机的代码,在cach内写入权限判断并动态设置权限。
昨天我又遇到一个通知的权限,这个权限不会出现任何崩溃问题,但如果有这个需求,那也没办法;
所以就使用了下面这个方法进行判断并打开设置通知页:
此方法如果返回true则表示已开启权限,返回false就是没有开启权限,当然了,这里还有个坑就是在android 4.4 以下则不管用了,因为在4.4以下是不能判断权限的,所有就默认是true已打开了。public static boolean isNotificationEnabled(Context context) { String CHECK_OP_NO_THROW = "checkOpNoThrow"; String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"; if (Build.VERSION.SDK_INT >= 19) { AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); ApplicationInfo appInfo = context.getApplicationInfo(); String pkg = context.getApplicationContext().getPackageName(); int uid = appInfo.uid; Class appOpsClass = null; try { appOpsClass = Class.forName(AppOpsManager.class.getName()); Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class); Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION); int value = (Integer) opPostNotificationValue.get(Integer.class); return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return false; } else { return true; } }
如果用户为打开通知则会进行其他操作,我则是用了一个dialog提示用户没有开启,问用户是否要打开:
这个方法是直接跳转至设置通知页的,也可进行跳转至设置权限的页面(上面的startSettings方法),看需求了。public static void openNotice(final Context context) { LemonHelloInfo info = new LemonHelloInfo() .setTitle("提示") .setContent("通知功能尚未开启,点击“去开启”启用通知提醒。") .setContentFontSize(16) .addAction(new LemonHelloAction("取消", new LemonHelloActionDelegate() { @Override public void onClick(LemonHelloView helloView, LemonHelloInfo helloInfo, LemonHelloAction helloAction) { helloView.hide(); } })) .addAction(new LemonHelloAction("去开启", Color.RED, new LemonHelloActionDelegate() { @Override public void onClick(LemonHelloView helloView, LemonHelloInfo helloInfo, LemonHelloAction helloAction) { //跳转登录页面 Intent intent = new Intent(); intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); intent.putExtra("app_package", context.getPackageName()); intent.putExtra("app_uid", context.getApplicationInfo().uid); context.startActivity(intent); helloView.hide(); } })); info.show(context); }
以上则是我自己遇到的权限问题,如有不对欢迎指出。