具有多个对话框的Android权限UI问题

时间:2017-06-19 16:39:48

标签: java android user-interface permissions

我正在尝试重构一段处理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);
    }
}

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

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

有没有人为此提供干净的解决方案?我会很感激。

2 个答案:

答案 0 :(得分:0)

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

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
            }
  }

基本上,您通过传递您将要求的权限的参数来遍历权限。授予/拒绝权限后,它会中断,转到第二个权限,直到完成所有权限。

理论上这应该有用。

答案 1 :(得分:0)

只需使用此代码:

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();
            }

        }
    }

}