首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我们如何在Android M的运行时权限中区分Never-Asked和Stop-Asked?

我们如何在Android M的运行时权限中区分Never-Asked和Stop-Asked?
EN

Stack Overflow用户
提问于 2015-08-11 04:48:19
回答 9查看 27.1K关注 0票数 65

根据Google的说法,当涉及M开发人员预览运行时权限时

  1. 如果您以前从未请求过某个权限,则只需请求该权限即可(如果您以前请求过该权限,而用户说"no",然后用户尝试执行需要被拒绝的权限的操作),您应该提示用户解释您为什么需要该权限,然后再继续请求该权限,如果您之前请求过几次,并且用户已经说过"no,
  2. ask“(通过运行时权限对话框上的复选框),则您应该停止麻烦(例如,禁用需要该权限的UI )

但是,我们只有一个返回boolean的方法shouldShowRequestPermissionRationale(),并且我们有三个状态。我们需要一种方法来区分从未询问状态和停止询问状态,因为我们从shouldShowRequestPermissionRationale()获取了这两种状态的false

有很多方法可以确定这可能是你的应用程序的第一次运行(例如,SharedPreferences中的boolean值),所以你假设如果这是你的应用程序的第一次运行,你就处于从未被询问的状态。

但是,运行时权限的部分愿景是,您可能不会预先请求所有权限。与边缘功能相关的权限,您可能只会在稍后用户点击需要该权限的内容时才要求该权限。在这里,这个应用程序可能已经运行了很多次,在我们突然需要请求另一个许可之前,已经运行了几个月。

在这种情况下,我们是否应该跟踪自己是否请求了许可?或者,Android M API中有没有我遗漏的东西,告诉我们我们之前是否问过了?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2015-08-11 05:02:37

根据当前示例:https://github.com/googlesamples/android-RuntimePermissions/blob/master/Application/src/main/java/com/example/android/system/runtimepermissions/MainActivity.java#L195

代码语言:javascript
复制
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {
    if (requestCode == REQUEST_CAMERA) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            doThing();
            //STORE FALSE IN SHAREDPREFERENCES
        } else {
            //STORE TRUE IN SHAREDPREFERENCES
        }
    }

如上所述,将一个布尔值存储在SharedPreferences中,并将key作为权限代码和值,以指示该首选项以前是否已被拒绝。

不幸的是,你可能不能在你的应用程序运行时检查已经被接受然后又被拒绝的首选项。最终的规范不可用,但你的应用程序可能会重新启动,或者在下一次启动之前获得模拟值。

票数 15
EN

Stack Overflow用户

发布于 2016-02-19 08:49:45

我知道我发得很晚,但详细的例子可能会对某些人有帮助。

我注意到的是,如果我们将shouldShowRequestPermissionRationale()标志签入到onRequestPermissionsResult()回调方法中,它只显示两种状态。

状态1:-Return true:--任何时候用户点击Deny permissions (拒绝权限)(包括第一次。

状态2 :-返回false:-如果用户选择“s”,则不再询问。

下面是一个包含多个权限请求的示例:-

应用程序在启动时需要2个权限。SEND_SMS和ACCESS_FINE_LOCATION (在manifest.xml中都有提到)。

一旦应用程序启动,它就会一起请求多个权限。如果两个权限都被授予,则正常流程继续。

代码语言:javascript
复制
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if(checkAndRequestPermissions()) {
        // carry on the normal flow, as the case of  permissions  granted.
    }
}

private  boolean checkAndRequestPermissions() {
    int permissionSendMessage = ContextCompat.checkSelfPermission(this,
            Manifest.permission.SEND_SMS);
    int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
    List<String> listPermissionsNeeded = new ArrayList<>();
    if (locationPermission != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
    }
    if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.SEND_SMS);
    }
    if (!listPermissionsNeeded.isEmpty()) {
        ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
        return false;
    }
    return true;
}

如果没有授予一个或多个权限,activityCompat.requestPermissions()将请求权限,并且控制转到onRequestPermissionsResult()回调方法。

您应该在onRequestPermissionsResult()回调方法中检查shouldShowRequestPermissionRationale()标志的值。

只有两种情况:

情况1:-Any用户单击拒绝权限(包括第一次)时,将返回true。因此,当用户拒绝时,我们可以显示更多的解释,并继续询问。

案例2:-Only如果用户选择“never asks”,则返回false。在这种情况下,我们可以继续使用有限的功能,并引导用户从设置中激活更多功能的权限,或者如果权限对应用程序来说微不足道,我们也可以完成设置。

案例- 1

案例- 2

代码语言:javascript
复制
@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        Log.d(TAG, "Permission callback called-------");
        switch (requestCode) {
            case REQUEST_ID_MULTIPLE_PERMISSIONS: {

                Map<String, Integer> perms = new HashMap<>();
                // Initialize the map with both permissions
                perms.put(Manifest.permission.SEND_SMS, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
                // Fill with actual results from user
                if (grantResults.length > 0) {
                    for (int i = 0; i < permissions.length; i++)
                        perms.put(permissions[i], grantResults[i]);
                    // Check for both permissions
                    if (perms.get(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED
                            && perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        Log.d(TAG, "sms & location services permission granted");
                        // process the normal flow
                        //else any one or both the permissions are not granted
                    } else {
                            Log.d(TAG, "Some permissions are not granted ask again ");
                            //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(this, Manifest.permission.SEND_SMS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                                showDialogOK("SMS and Location Services Permission required for this app",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                switch (which) {
                                                    case DialogInterface.BUTTON_POSITIVE:
                                                        checkAndRequestPermissions();
                                                        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(this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
                                        .show();
    //                            //proceed with logic by disabling the related features or quit the app.
                            }
                    }
                }
            }
        }

    }

    private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", okListener)
                .create()
                .show();
    }
票数 68
EN

Stack Overflow用户

发布于 2015-09-16 18:03:25

不,你不需要跟踪你是否请求了许可,你也不需要区分Never-Asked和Stop- and。

对于app开发者来说,状态1和3是一样的:你需要权限和ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED,然后你只需要通过ActivityCompat.requestPermissions()请求权限,无论你请求了多少次,只要用户点击了需要权限的功能。用户最终将“允许”它,或“拒绝”它,并选中“永不再问”。该设计不会阻止您多次弹出权限请求对话框。

然而,这个设计确实鼓励你在某些时候解释权限的目的-你的状态2。shouldShowRequestPermissionRationale()不是用来决定你是否应该请求权限,它是用来在你请求权限之前决定你是否应该显示解释。

关于状态3,还有几个解释:

  1. 是的,我们应该停止显示解释,而不是停止请求来打扰用户。这就是为什么他们提供了shouldShowRequestPermissionRationale().
  2. It's,而不是麻烦地保持许可请求。在用户选择“永不再问”后,ActivityCompat.requestPermissions()将不再弹出对话框。
  3. 在单用户会话期间,每次我们发现自己没有权限时,最好禁用相关的UI。返回false,而不是在shouldShowRequestPermissionRationale()之后禁用UI。
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31928868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档