http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/1110/3670.html 泡在网上的日子

 安卓开发之路fndroid

鸿洋


今天在测试项目的过程中出现崩溃,在安卓6.0手机上点击拨打电话功能出现闪退情况查找原因终于知道原来是6.0之后权限设置的相关问题

Android 6.0 相比之前的Android版本有一个很大的不同点,就是动态获取权限

从一个例子入手吧。假如在App中需要进行拨打电话的操作,当点击按钮,直接拨出一个电话,代码如下:


Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:10086"));
startActivity(intent);


但是如果你的编译版本是23或者以上,那么Android Studio就会报出一个错误


android拒绝权限后没有弹窗 安卓app权限被拒绝_ide

提示我们要进行权限请求。

如果我们直接对这个错误进行自动修复,会在startActivity方法之前增加一段代码用于权限检查,如果当前没有赋予该权限,则直接return结束方法:



if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
      // TODO: Consider calling
      //    ActivityCompat#requestPermissions
      // here to request the missing permissions, and then overriding
      //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
      //                                          int[] grantResults)
      // to handle the case where the user grants the permission. See the documentation
      // for ActivityCompat#requestPermissions for more details.
      return;
}



如果这个时候直接运行,你的APP照样是没有得到这个权限的,因为默认安装的时候,这个权限会被关闭到,所以方法直接就返回了。要是需要在点击按钮的时候,直接向用户请求权限,可以使用下面的方法:


ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUESTCODE);


这个时候,再重新运行App,会得到下面的一个界面来请求用户权限:


android拒绝权限后没有弹窗 安卓app权限被拒绝_checkSelfPermission_02

允许:以后不再弹出请求框,直接允许应用获得该权限

拒绝:下次需要时会重新弹出,直到用户选择允许,否则会不断出现

 

不再询问并拒绝了请求会怎样呢?答案是以后不会再弹出,并且默认拒绝权限请求,也就是说,应用再也不能获得这个权限,除非用户主动进入应用设置中重新授权。

 

为了更好的用户体验,可以在用户选择了不再询问和拒绝之后,创建一个AlertDialog来询问用户是否需要重新授予权限,是的话,跳转到应用设置界面。

当我们调用requestPermissions方法的时候,无论成功与否,都会将结果回调给Activity中的onRequestPermissionsResult方法中,我们可以通过重写这个方法来处理结果:



@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUESTCODE) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
                    AskForPermission();
                }
            }
        }
    }



shouldShowRequestPermissionRationale方法来检查权限申请框是否会显示,因为如果用户选择了不再询问,则申请框会不出现,这个方法会返回false,如果申请框没有出现,则创建一个AlertDialog来询问用户:



private void AskForPermission() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Need Permission!");
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        builder.setPositiveButton("Settings", 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);
            }
        });
        builder.create().show();
    }