Android 6.0 多重权限

新手上路,请多包涵

我知道 Android 6.0 有新的权限,我知道我可以用这样的方式调用它们

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
    PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
        new String[] {
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        }, PERMISSION_WRITE_STORAGE);
}

今天我看到一个谷歌应用程序需要 3 个权限:联系人、短信和相机。它正在制作 1-3 页并同时调用它们来激活。

谁能告诉我如何调用 4 个权限同时激活,如短信、相机、联系人和存储?

示例(忘记了谷歌应用程序的名称 :( )

该应用程序需要短信、联系人和摄像头

该应用程序问我(并制作了一个对话框第 1-3 页)激活短信,激活联系人,然后激活相机。所以这个谷歌应用程序同时调用了所有 3 个必需的权限,我的问题是我怎样才能获得相同的权限?

原文由 Frank 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 754
2 个回答

只需在 ActivityCompat.requestPermissions(...) 调用中包含所有 4 个权限,Android 就会像您提到的那样自动将它们分页在一起。

我有一个辅助方法来检查多个权限并查看是否有任何权限未被授予。

 public static boolean hasPermissions(Context context, String... permissions) {
    if (context != null && permissions != null) {
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
    }
    return true;
}

或者在科特林中:

 fun hasPermissions(context: Context, vararg permissions: String): Boolean = permissions.all {
    ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}

然后只需将所有权限发送给它。 Android 只会询问它需要的那些。

 // The request code used in ActivityCompat.requestPermissions()
// and returned in the Activity's onRequestPermissionsResult()
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
  android.Manifest.permission.READ_CONTACTS,
  android.Manifest.permission.WRITE_CONTACTS,
  android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
  android.Manifest.permission.READ_SMS,
  android.Manifest.permission.CAMERA
};

if (!hasPermissions(this, PERMISSIONS)) {
    ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}

原文由 James McCracken 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是具有多个权限请求的详细示例:-

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

我正在使用 支持库 v4 ,它已准备好处理 Android pre-Marshmallow,因此无需检查构建版本。

应用程序启动后,它会同时请求多个权限。如果授予这两个权限,则正常流程进行。

在此处输入图像描述

在此处输入图像描述

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

ContextCompat.checkSelfPermission()、ActivityCompat.requestPermissions()、ActivityCompat.shouldShowRequestPermissionRationale() 是支持库的一部分。

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

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

只有两种情况:——

情况 1: - 任何时候用户单击拒绝权限(包括第一次),它都会返回 true。所以当用户否认时,我们可以给出更多的解释并继续询问

情况 2: - 只有当用户选择“不再询问”时,它才会返回 false。在这种情况下,我们可以继续使用有限的功能并引导用户从设置中激活权限以获得更多功能,或者如果权限对于应用程序来说微不足道,我们可以完成设置。

情况1

在此处输入图像描述

案例二

在此处输入图像描述

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

原文由 Nicks 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题