美文网首页
Android 6.0 动态权限

Android 6.0 动态权限

作者: 3Q竹林 | 来源:发表于2017-09-28 17:00 被阅读148次
    这里我将介绍:
    *1. 动态权限的基本使用(包括个人理解)*
    *2. 动态权限使用时,我们需要去注意什么*
    
    先解释 再上例子
        为了用户体验考虑,Android6.0之后,希望当APP运行到需要被授予某项权限时,才会去提示用户开启某项权限,而不是像以前那样,直接在启动页就全部请求授予,这就要求我们,在需要时提示用户开启权限并对权限请求结果进行回调监听。
    
    • 需要知道的

      1. 两个与权限有关的变量:

        PackageManager.PERMISSION_GRANTED = 0     //表示授予权限;
        PackageManager.PERMISSION_DENIED  = -1    //表示权限未开启;
        
      2. 运行权限检测的三种方式:

            
          方式一:
          public static int checkSelfPermission(Activity activity,String writeContacts) {
              return PermissionChecker.checkSelfPermission(activity, writeContacts);
          }
        
          方式二:
          public static int checkSelfPermission(Activity activity,String writeContacts) {
              return ContextCompat.checkSelfPermission(WelcomeActivity.this,Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED);
          }
        
          方式三:
          public static boolean checkSelfPermission() {
              PackageManager pm = this.getPackageManager();
              for (String auth : authBaseArr) {
                //注意,这里是只要有一个权限未通过,则返回false,并不能对具体某个权限做区分
                if (pm.checkPermission(auth, this.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
              return false;
                }
              }
              return true;
          }
        
        
      3. 请求开启权限的弹窗显示:

        ActivityCompat.requestPermissions(mactivity, new String[] { CALL_PHONE ,CAMERA },REQUEST_CODE);
        

        注意:一次请求多个权限会有bug,当该次权限弹窗中有一个未被授予权限,那么再次执行该代码时,只会一直提示用户需要获取第一项权限,但是此时即使用户点击允许,依然会不断提示请求开启第一项权限(实则是需要开启后边的某项权限),所以还是每次都只请求一个权限稳妥!!! 例如你可以这样写:

           private void baiduPermission() {
               boolean canInitBaidu = true;
               // 申请权限
               if (android.os.Build.VERSION.SDK_INT >= 23) {
                 pm = this.getPackageManager();
                 if (pm.checkPermission(authBaseArr[0], this.getPackageName())
                 != PackageManager.PERMISSION_GRANTED) {
               requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
                   authBaseRequestCode);
               canInitBaidu = false;
                 }
        
                 if (pm.checkPermission(authBaseArr[1], this.getPackageName())
                 != PackageManager.PERMISSION_GRANTED) {
               requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                   authBaseRequestCode);
               canInitBaidu = false;
                 }
               }
                 if (canInitBaidu) {
               initLoc();
                 }
             }
        
      4. 权限请求结果监听:

        @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
           @NonNull int[] grantResults) {
           if (requestCode == BaiDuRequest && grantResults.length > 0 && grantResults[0]==-1){
               UtilsW.showMessageOKCancel(mactivity, "温馨提示",
                   "        当前操作需要开启“XXX”权限,您可到设置的权限管理中,修改该应用的相关权限。", null);
           } 
        }
        

        注意:这里使用了grantResults.length > 0 ,这是为防止同时有两个requestPermissions(new String[] { XXX},RequestCode);被调用,而引起的crash问题,grantResults[0]==-1(也就是grantResults[0]==PackageManager.PERMISSION_DENIED),表示用户拒绝了该项权限,那如果要申请多个权限怎么办?,我们可以在第一个成功后再去申请,如下:

        @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
           @NonNull int[] grantResults) {
           if (requestCode == BaiDuRequest && grantResults.length > 0 && grantResults[0]==-1){
               UtilsW.showMessageOKCancel(mactivity, "温馨提示",
                   "        当前操作需要开启“定位”和“存储”权限,您可到设置的权限管理中,修改该应用的相关权限。", null);
           } else if (ACCESS_FINE_LOCATION.equalsIgnoreCase(permissions[0]) && grantResults.length > 0 && grantResults[0]== 0) {
               ActivityCompat.requestPermissions(mactivity, new String[] {WRITE_EXTERNAL_STORAGE },BaiDuRequest);
           }
        }
        
      5. 对于非Android6.0版本的手机,我们还是可以在AndroidManifest.xml中,直接设置权限的(如:<uses-permission android:name="android.permission.READ_PHONE_STATE"/>),在启动APP时,就会有弹窗提示用户给予权限了,二者虽有重复,但谁让咱们大Android越来越贴心呢;

      6. shouldShowRequestPermissionRationale作用:

        1. 第一次请求权限时,用户拒绝了,下一次:shouldShowRequestPermissionRationale() 返回 true,应该显示一些为什么需要这个权限的说明;
        2. 第二次请求权限时,用户拒绝了,并选择了“不在提醒”的选项时:shouldShowRequestPermissionRationale() 返回 false
        3. 设备的策略禁止当前应用获取这个权限的授权:shouldShowRequestPermissionRationale() 返回 false
          注意:上面的:第二次请求权限时,才会有“不在提醒”的选项,如果用户一直拒绝,并没有选择“不在提醒”的选项,下次请求权限时,会继续有“不在提醒”的选项
      7. 应用方面举例:
        在获取DeviceID时,我们有很多方法,比如这样:

        /**
         * 获取DeviceId (IMEI方式)
         * 其他获取DeviceId方式: http://blog.csdn.net/u014651216/article/details/50767326 
         */
         public static String getDeviceID(Activity activity) {
           return ((TelephonyManager)activity.getSystemService(activity.TELEPHONY_SERVICE)).getDeviceId();
        }
      

      但是直接这样调用会报错的:

      SecurityException: getDeviceId: Neither user 10282 nor current process has android.permission.READ_PHONE_STATE.
      

      我们需要先判断是否有读取电话状态的动态权限,然后去申请该权限,如下:

        //电话状态读取的动态权限校验
       if (Utils.checkSelfPermission(this,READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
           Utils.showMessageOKCancel(this,"提示:\n\n该应用权限已关闭。\n开启方式:点击确定后,您可到“权限”中,开启该应用的“电话”权限。",
               new DialogInterface.OnClickListener() {
                   @Override public void onClick(DialogInterface dialog, int which) {
                       Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); //未开启该权限,引导用户到开启该项权限的页面
                       intent.setData(Uri.parse("package:" + getPackageName()));
                       startActivity(intent);
                   }
               });
           return ;
      

    或者直接再次申请权限:

     int permissionNum = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);  //检测某项权限是否开启
     if (permissionNum != PackageManager.PERMISSION_GRANTED) { //若该权限未开启
         ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
     }  //但这种若用户在第一次弹窗时,勾选了不再提醒,将不会再次有该项提示了
    

    .

    相关文章

      网友评论

          本文标题:Android 6.0 动态权限

          本文链接:https://www.haomeiwen.com/subject/fkcvextx.html