android6.0权限

申请权限

如果是6.0以下的手机,ActivityCompat.checkSelfPermission()会始终等于PERMISSION_GRANTED

但是,如果用户关闭了你申请的权限(如下图,在安装的时候,将一些权限关闭了),ActivityCompat.checkSelfPermission()则可能会导致程序崩溃(java.lang.RuntimeException: Unknown exception code: 1 msg null)

你可以使用try{}catch(){},处理异常,也可以判断系统版本,低于23就不申请权限,直接做你想做的。

(1)checkSelfPermission:检查是否拥有这个权限

(2)requestPermissions:请求权限,一般会弹出一个系统对话框,询问用户是否开启这个权限。

(3)shouldShowRequestPermissionRationale:Android原生系统中,如果第二次弹出权限申请的对话框,会出现“以后不再弹出”的提示框,如果用户勾选了,你再申请权限,则shouldShowRequestPermissionRationale返回true,意思是说要给用户一个 解释,告诉用户为什么要这个权限。然而,在实际开发中,需要注意的是,很多手机对原生系统做了修改,比如小米,小米4的6.0的shouldShowRequestPermissionRationale 就一直返回false,而且在申请权限时,如果用户选择了拒绝,则不会再弹出对话框了。。。。 所以说这个地方有坑,我的解决方法是,在回调里面处理,如果用户拒绝了这个权限,则打开本应用信息界面,由用户自己手动开启这个权限。

(4)每个应用都有自己的权限管理界面,里面有本应用申请的权限以及各种状态,即使用户已经同意了你申请的权限,他也随时可以关闭
检查申请权限
 //打开定位的权限
        if (Build.VERSION.SDK_INT >= 23) {
            //判断有没有定位权限
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                //请求打开定位功能
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE);
            }else {
                toSportsRunFragment();
            }
        }else {
            toSportsRunFragment();
        }
权限结果返回

if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    //用户点击了禁止访问后不在询问
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(SportsRunActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                     dialog = new AlertDialog.Builder(SportsRunActivity.this)
                            .setMessage("跑步功能需要获取位置信息,才能正常使用!")
                            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    //ActivityCompat.requestPermissions(SportsRunActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE);
                                    // 去应用信息
                                    Intent localIntent = new Intent();
                                    localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    if (Build.VERSION.SDK_INT >= 9) {
                                        localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                                        localIntent.setData(Uri.fromParts("package", SportsRunActivity.this.getPackageName(), null));
                                    } else if (Build.VERSION.SDK_INT <= 8) {
                                        localIntent.setAction(Intent.ACTION_VIEW);
                                        localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
                                        localIntent.putExtra("com.android.settings.ApplicationPkgName", SportsRunActivity.this.getPackageName());
                                    }
                                    startActivity(localIntent);
                                    dialog.dismiss();
                                    finish();
                                }
                            })
                            .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    finish();

                                }
                            }).create();
                    dialog.show();
                    return;
                }else {
                    //用户没有点击不在询问且直接禁止权限
                    finish();
                }
                  
                } else if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED
                        && (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) {
                    toSportsRunFragment();
                }
                                                                                                

android6.0需要使用权限列表

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

Fragment中运行时权限的特殊处理

在Fragment中申请权限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否则会回调到Activity的onRequestPermissionsResult

如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方法,onRequestPermissionsResult不会回调回来,建议使用getParentFragment().requestPermissions方法,
这个方法会回调到父Fragment中的onRequestPermissionsResult,加入以下代码可以把回调透传到子Fragment

  @Override
  public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      List fragments = getChildFragmentManager().getFragments();
      if (fragments != null) {
          for (Fragment fragment : fragments) {
              if (fragment != null) {
                  fragment.onRequestPermissionsResult(requestCode,permissions,grantResults);
              }
          }
      }
  }

Android各大手机品牌手机跳转到权限管理界面

当我们的用户使用App时不小心拒绝了某项必要权限,而导致无法正常使用。这时候希望重新去打开该权限,那么问题来了,Android厂家定制的room五花八门,很多时候却发现找不到权限管理的入口。为了解决这一问题,如果我们应用中直接提供权限管理入口给用户
由于各个厂商权限管理入口的方式都不同所有用以下方法
有两个通用的方法,一个是引导至系统设置页面,另一个引导至应用信息页面:

应用信息界面

Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 9) {
     localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
     localIntent.setData(Uri.fromParts("package", getPackageName(), null));
 } else if (Build.VERSION.SDK_INT <= 8) {
     localIntent.setAction(Intent.ACTION_VIEW);
     localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
     localIntent.putExtra("com.android.settings.ApplicationPkgName", getPackageName());
 }
 startActivity(localIntent);
系统设置界面

Intent intent =  new Intent(Settings.ACTION_SETTINGS);
startActivity(intent);

你可能感兴趣的:(android6.0权限)