【问题标题】:Android - Correct way to handle a dangerous permission that must be granted for app to work?Android - 处理必须授予应用程序工作的危险权限的正确方法?
【发布时间】:2017-06-23 14:52:32
【问题描述】:

我的应用需要访问存储 - 只是为了读取一些 OBB 数据 - 由于我们正在处理的数据的大小。根据定义,这被 android 归类为“危险”权限,这是正确的,因此从 Android 6.0 开始,我们需要在应用启动时请求它,然后才能执行任何操作。

问题在于,当应用从根本上要求它在主菜单之外执行任何操作时,用户可以拒绝我们的许可。

当用户拒绝在运行时授予“危险”权限时,如果没有它,应用程序实际上毫无功能,那么正确的处理方法是什么?

编辑:澄清 我知道我需要执行此操作的代码以及所涉及的回调。代码示例不是必需的。我需要知道如果不断拒绝会削弱我的应用程序的用处,我应该怎么做。错误然后杀死应用程序?当用户尝试做任何事情时显示带有消息的主菜单? 值得注意的是,这是一个原生应用程序,因此 C++ 正在回调 java 来执行此操作。

【问题讨论】:

  • 只显示一个对话框,解释为什么您的应用需要此权限,并说没有它您将无法使用该应用,然后不要让他们在没有它的情况下通过主菜单
  • 向你的用户解释你为什么需要这个权限,如果他仍然拒绝然后退出你的应用程序,这里有一些解决方案stackoverflow.com/questions/41999564/…
  • 你能详细说明为什么你需要这个权限吗?通常,您可以将 OBB 文件放在您的 external file directory 中而无需额外权限,这就是 Google Play 处理应用扩展的方式。
  • @AlexCohn extract from this link under the header "Storage Location", developer.android.com/google/play/expansion-files.html :但是,在 Android 6.0(API 级别 23)的某些实现中,您可能需要在应用清单并在运行时请求许可
  • @AlexCohn 最初我们并没有请求许可,也无法读取某些设备的文件。我们最初的解决方案是在所有设备上请求许可,但我们将对其进行修复,看看我们是否可以避免在没有这种实现的设备上这样做。因此,当我们完成该任务时,我会通知您,并让您知道我们如何处理它 - 但它可能会采用以下形式:尝试,如果(错误){请求许可,再次尝试}

标签: android permissions android-ndk


【解决方案1】:

其他答案中尚未描述的关键位是在用户拒绝提供权限后,推荐的方法是显示一个基本原理对话框,解释为什么您的权限至关重要。有一个兼容性助手可以跟踪这个内部状态:

    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

        new AlertDialog.Builder(this)
                .setTitle(R.string.title_my_permission)
                .setMessage(R.string.text_my_permission)
                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //Prompt the user once explanation has been shown
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                MY_PERMISSIONS_REQUEST_TAG);
                    }
                })
                .create()
                .show();
    } else {
        // probably first time, request permission
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                MY_PERMISSIONS_REQUEST_TAG);
    }

但是您应该注意,用户始终处于控制之中,并且可能决定永远不会授予您的应用所需的权限,因此您需要尽可能多的语言环境中的大量文本来说服他们 :-)

更糟糕的是,他们可以在原始请求对话框中选择“不再询问”。在这种情况下,ActivityCompat.shouldShowRequestPermissionRationale 也返回 false。如果你真的想要,你可以使用第三个对话框警告用户。但是,在这种情况下,用户自己必须在 Android 设置活动中手动启用该权限。您可以使用意图帮助他们找到此活动,但他们必须在选择“不再询问”后手动检查权限。

【讨论】:

  • 请看编辑,我可能不够清楚,我知道代码,我在问如何处理一个实际上瘫痪的应用程序。但是你比其他任何人都更好地涵盖了这一点,因为我忘记了你可以打算设置。
  • 好的,我明白了,那么我会在您的应用程序每次启动时使用一个对话框(如果尚未授予权限),说明为什么需要权限并解释它必须是如果他们之前选择“不再询问”,则手动启用。在 OK 点击监听器上,通过 Intent 将它们发送到设置页面以手动启用它。在几乎所有情况下,用户都会对此感到满意。在您进入主要活动之前,我可能会在一些具有合适警告主题的自定义活动中实现这一点,因此很明显应用程序的功能几乎被禁用。
【解决方案2】:

您可以在开始时请求许可:

    if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

        } else {
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_WRITE_EXTERNAL_STORAGE);
        }
    }

如果未授予权限,则会显示一个对话框以授予权限,您可以在以下位置获得结果:

  @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode ==  RC_WRITE_EXTERNAL_STORAGE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        }
    }

【讨论】:

  • 这不是我要问的。我知道如何请求权限。问题是,如果他们否认,该应用程序就会瘫痪,并且无法通过主菜单进行任何操作。没有这些权限的处理方法是什么?
  • 您可以在用户未授予再次授予权限或向用户解释任何内容时显示一个对话框
  • 请看编辑,我可能不够清楚,我知道代码,因为你不是唯一这样做的人,我在问如何处理一个实际上瘫痪的应用程序我收到“拒绝”的事件总是由于“不要再问”的回应
【解决方案3】:

希望这个答案有帮助: https://stackoverflow.com/a/40142454/4819445

你可以在onRequestPermissionsResult()里面处理这个

【讨论】:

  • 请看编辑,我可能不够清楚,我知道代码,我在问如何处理一个实际瘫痪的应用程序。
【解决方案4】:

第 1 步:- 在清单文件中添加此权限

 android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
 android.Manifest.permission.READ_EXTERNAL_STORAGE,

第 2 步:请求运行时权限

String permission = android.Manifest.permission.READ_EXTERNAL_STORAGE;
        if (ActivityCompat.checkSelfPermission(MainActivity.this, permission)!= PackageManager.PERMISSION_GRANTED ) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]
                    {permission}, PERMISSION_CODE);

        }

第 3 步:处理 permsiion 结果

 @Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                   @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_CODE) {
    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {


        Toast.makeText(this, "permission_granted_msg", Toast.LENGTH_SHORT).show();

    } else {

        Toast.makeText(this, "permission_not_granted_msg", Toast.LENGTH_SHORT).show();
    }
}

}

【讨论】:

  • 请看编辑,我可能不够清楚,我知道代码,我在问如何处理一个实际瘫痪的应用程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
相关资源
最近更新 更多