位置权限对话框未在 activity 中正确显示

Location Permission Dialog not showing up properly in an activity

我在 ActionBar 中有一个位置按钮。单击它将加载给定函数 cityLocation() .

代码执行如下

  1. 第一次按下时会请求位置权限
  2. 如果接受它 运行s showCity() ,否则弹出一个 Toast
  3. 如果拒绝后再次点击,则执行shouldShowRequestPermissionRationale()部分(PS。我没有点击不再显示)

无论如何,这只是我第二次单击该按钮,它没有再次询问我位置许可(带有不再显示复选框),而是执行了 shouldShowRequestPermissionRationale() 部分。

我希望代码使用“不再询问”复选框请求位置权限,如果权限是第一次被拒绝,然后如果我再次拒绝(使用复选框),然后单击操作栏项目, 那么它应该 运行 MaterialDialog.Builder 代码。

这是我现在拥有的代码:

private void cityLocation() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (ActivityCompat.checkSelfPermission(WeatherActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(WeatherActivity.this,
                    Manifest.permission.ACCESS_COARSE_LOCATION)) {
                MaterialDialog dialog;
                MaterialDialog.Builder builder = new MaterialDialog.Builder(this);
                builder.title("Permission needed")
                        .content("This Action Requires the Location Setting to be enabled. Go to Settings and check the Location Permission inside the Permissions View")
                        .positiveText("SETTINGS")
                        .negativeText("CANCEL")
                        .onPositive(new MaterialDialog.SingleButtonCallback() {
                            @Override
                            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                final Intent i = new Intent();
                                i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                i.addCategory(Intent.CATEGORY_DEFAULT);
                                i.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
                                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                                i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                                startActivity(i);
                            }
                        })
                        .onNegative(new MaterialDialog.SingleButtonCallback() {
                            @Override
                            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                dialog.dismiss();
                            }
                        });
                dialog = builder.build();
                dialog.show();
            }
            else
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                        READ_COARSE_LOCATION);
        } else {
            showCity();
        }
    }
    else {
        showCity();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode == READ_COARSE_LOCATION
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        showCity();
    }
    else {
        Toast.makeText(getApplicationContext() , "Denied Location Permission" , Toast.LENGTH_SHORT).show();
    }
}

等待解决方案。

如果您在权限对话框中选中了复选框 neverAskAgain,则

ActivityCompat.shouldShowRequestPermissionRationale()

方法将 return 错误。因此,如果将 material 对话框保留在 if 块中,那么再次显示 material 对话框的逻辑将不起作用。

如果必须再次显示,请在 else 块中执行。

这里是完整的运行时权限检查代码:

 private void cityLocation() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (!checkIfAlreadyhavePermission()) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, READ_COARSE_LOCATION);
        } else {
            showCity();
        }
    } else {
        showCity();
    }
}

private boolean checkIfAlreadyhavePermission() {
    int result = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
    return result == PackageManager.PERMISSION_GRANTED;
}

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case READ_COARSE_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                showCity();

            } else {
                permission_denied();
            }
            break;
        }
        // other 'case' lines to check for other
        // permissions this app might request
    }
}

public void permission_denied() {
    // permission was not granted
    //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
    // shouldShowRequestPermissionRationale will return true
    //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
    if (ActivityCompat.shouldShowRequestPermissionRationale(WeatherActivity.this,
            Manifest.permission.ACCESS_COARSE_LOCATION)) {
        showDialogOK("Permission is required for register",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case DialogInterface.BUTTON_POSITIVE:
                                showCity();
                                break;
                            case DialogInterface.BUTTON_NEGATIVE:
                                // proceed with logic by disabling the related features or quit the app.
                                break;
                        }
                    }
                });
    } //permission is denied (and never ask again is  checked)
    //shouldShowRequestPermissionRationale will return false
    else {
        Toast.makeText(getApplicationContext(), "Go to settings and enable External storage permissions", Toast.LENGTH_LONG).show();
        showMaterialDialog();
    }
}

public void showMaterialDialog() {
    MaterialDialog dialog;
    MaterialDialog.Builder builder = new MaterialDialog.Builder(this);
    builder.title("Permission needed")
            .content("This Action Requires the Location Setting to be enabled. Go to Settings and check the Location Permission inside the Permissions View")
            .positiveText("SETTINGS")
            .negativeText("CANCEL")
            .onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    final Intent i = new Intent();
                    i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    i.addCategory(Intent.CATEGORY_DEFAULT);
                    i.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                    i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                    startActivity(i);
                }
            })
            .onNegative(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    dialog.dismiss();
                }
            });
    dialog = builder.build();
    dialog.show();

}

private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(getActivity())
            .setMessage(message)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", okListener)
            .create()
            .show();
}
  1. 如果用户拒绝权限,它将显示一个对话框...

  2. 如果用户也选中不再询问它将显示 material 对话框..

  3. 如果用户授予权限,它将执行所需的功能..