【问题标题】:Android permissions UI issue with multiple dialogs多个对话框的Android权限UI问题
【发布时间】:2017-06-19 16:39:47
【问题描述】:

我正在尝试重构一段处理 Android 权限的代码。它工作正常,除了一个让我很头疼的烦人的 UI 错误。代码如下:

private void getPermissions() {

    if (Build.VERSION.SDK_INT >= 23) {

        List<String> permissionsNeeded = new ArrayList<String>();

        final List<String> permissionsList = new ArrayList<String>();
        if (!addPermission(permissionsList, android.Manifest.permission.ACCESS_COARSE_LOCATION))
            permissionsNeeded.add(accessLocation);
        if (!addPermission(permissionsList, Manifest.permission.CAMERA))
            permissionsNeeded.add(accessCamera);

        if (permissionsList.size() > 0) {
            if (permissionsNeeded.size() > 0) {
                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
            }
        }
    }
}

private void showMessageOK (int message, final String perm) {

    if (shouldShowRequestPermissionRationale(perm)) {

        new AlertDialog.Builder(CreateSessionActivity.this)
                .setMessage(message)
                .setTitle("Permission required")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.dismiss();
                        requestPermissions(new String[] {perm},
                                REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);

                    }
                })
                .create()
                .show();
    }
}

private boolean addPermission(List<String> permissionsList, String permission) {

    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {

        permissionsList.add(permission);

        //check for rationale
        if (!shouldShowRequestPermissionRationale(permission))
            return false;
    }
    return true;
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    Map<String, Integer> perms = new HashMap<>();

    perms.put(android.Manifest.permission.ACCESS_COARSE_LOCATION, PackageManager.PERMISSION_GRANTED);
    perms.put(android.Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
    // Fill with results
    for (int i = 0; i < permissions.length; i++)
        perms.put(permissions[i], grantResults[i]);

    if (perms.get(accessLocation) != PackageManager.PERMISSION_GRANTED) {

        showMessageOK(R.string.permdesc_access_location,
                accessLocation);
    }

    if (perms.get(accessCamera) != PackageManager.PERMISSION_GRANTED) {

        showMessageOK(R.string.permdesc_access_camera,
                accessCamera);
    }
}

它基本上获取用户尚未授予的权限列表,循环访问它们并提示用户授予每个权限。完成后,它会检查尚未授予的任何剩余权限,并再次提示用户有关为什么需要该权限以及不允许该权限的结果的信息,直到他接受或选择“不再询问”。

我的问题出现在 onRequestPermissionResult() 中的链式“if”语句上。您可能会猜到,如果多个权限条件为真,则每个对话框都会在当前现有对话框的下方打开。这会在一个对话框关闭和下一个显示之间产生“跳跃”对话框效果。我已经尝试过 case 和 if/elseif 语句来解决这个问题,但它会导致我的其余权限逻辑出现问题。

有人对此有干净的解决方案吗?我将感激不尽。

【问题讨论】:

  • 恕我直言,最干净的解决方案是摆脱所有 showMessageOK() 电话。用户知道用户授予了您权限,因为用户只是这样做了。不要感谢他们授予权限——做任何用户要求的需要权限的事情。
  • 确保您要求的所有权限也在您的AndroidManifest 文件中声明

标签: java android user-interface permissions


【解决方案1】:

嗯,这可能不是最干净的代码,但是,

if (Build.VERSION.SDK_INT >= 23) {

    List<String> permissionsNeeded = new ArrayList<String>();            
    for(int i=0; i<4;i++){
            checkAndAsk(i);
    }
    if (permissionsList.size() > 0) {
        if (permissionsNeeded.size() > 0) {
            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
        }
    }
}
//out of the get permissions method
public void checkAndAsk(int i){
            switch(i){
                case 0:
                    if (!addPermission(permissionsList, android.Manifest.permission.ACCESS_COARSE_LOCATION))
                        permissionsNeeded.add(accessLocation);
                    break;
                case 1:
                    if (!addPermission(permissionsList, android.Manifest.permission.READ_CONTACTS))
                        permissionsNeeded.add(readContacts);
                    break;
                //You get the idea
            }
  }

基本上,您通过传递您将要求的权限参数来遍历权限。一旦一个权限被授予/拒绝,它就会中断,移动到第二个权限,直到全部完成。

理论上这应该可行。

【讨论】:

    【解决方案2】:

    只需使用此代码:

    private void RequestAllPermissions() {
    
            String[] PERMISSIONS = {Manifest.permission.CAMERA, Manifest.permission.RECEIVE_SMS, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.INTERNET, Manifest.permission.CALL_PHONE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_CONTACTS};
    
            if (!hasPermissions(this, PERMISSIONS)) {
                ActivityCompat.requestPermissions(this, PERMISSIONS, REQUESTCODE_PERMISSION_ALL);
            } else
    
        }
    
    public static boolean hasPermissions(Context context, String... permissions) {
    
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
                for (String permission : permissions) {
                    if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                        return false;
                    }
                }
            }
            return true;
    
        }
    
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    
        switch (requestCode) {
            case REQUESTCODE_PERMISSION_ALL: {
    
                boolean allpermissiongranted = true;
                if (grantResults.length > 0) {
                    for (int i = 0; i < permissions.length; i++) {
                        if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                            allpermissiongranted = false;
                            break;
                        }
                    }
                } else
                    allpermissiongranted = false;
    
                if (allpermissiongranted) {
                    //do task
    
                } else {
    
                    new SweetAlertDialog(mContext, SweetAlertDialog.WARNING_TYPE)
                            .setTitleText("Permission Not Granted")
                            .setContentText("Kindly grant all requested permission to proceed.")
                            .setConfirmText("Request")
                            .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
                                @Override
                                public void onClick(SweetAlertDialog sDialog) {
                                    sDialog.dismissWithAnimation();
                                    RequestAllPermissions();
                                }
                            })
                            .setCancelText("Exit")
                            .setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() {
                                @Override
                                public void onClick(SweetAlertDialog sweetAlertDialog) {
                                    sweetAlertDialog.dismissWithAnimation();
                                    finish();
                                }
                            })
                            .show();
                }
    
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 2012-08-20
      • 2020-09-28
      • 1970-01-01
      相关资源
      最近更新 更多