OS 4.0上的Android棉花糖权限模型读取\外部\存储权限始终未授予

OS 4.0上的Android棉花糖权限模型读取\外部\存储权限始终未授予,android,android-permissions,android-6.0-marshmallow,Android,Android Permissions,Android 6.0 Marshmallow,在Android OS 4.0上运行我的应用程序并请求READ\u EXTERNAL\u STORAGE权限时,我遇到问题: ActivityCompat.requestPermissions(ctx, requestedPermissions, requestCode); 我总是接到回电 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull

在Android OS 4.0上运行我的应用程序并请求
READ\u EXTERNAL\u STORAGE
权限时,我遇到问题:

ActivityCompat.requestPermissions(ctx, requestedPermissions, requestCode);
我总是接到回电

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
        @NonNull int[] grantResults) { 

grantResults != PackageManager.PERMISSION_GRANTED
使用
ActivityCompat检查权限。checkSelfPermission
始终返回
permissionDenied

通过使用system dialog请求权限,它在OS 6.0上运行良好。 Android操作系统4.x(4.0除外)始终授予权限。 OS 4.0其他权限(照相机、日历、联系人、电话)运行正常,但导致此问题的
读取外部存储

可能是操作系统问题?

是:

  • 如果您使用的是Android 6.0+,请调用real
    requestPermissions()
    ,或者

  • 使用
    PackageManager
    查看您是否持有旧版本Android上请求的权限

READ_EXTERNAL_STORAGE
的问题在于它是在API级别16(Android 4.1)中添加的。你不能在旧版本的Android上保存它,原因很简单,它并不存在

要么:

  • minSdkVersion
    设置为16,或

  • 将您自己的逻辑放进去处理这种情况,认识到
    READ\u EXTERNAL\u STORAGE
    在API级别16之前是不相关的


我在Android 8.0上处理前台服务时发现了这个问题。不幸的是,我的解决方案依赖于异常处理,但它不需要处理支持权限的API级别。您可以使用此方法检查当前API级别上是否存在权限:

private boolean permissionExistsOnCurrentApiLevel(String permission) {
    try {
        getPackageManager().getPermissionInfo(permission, PackageManager.GET_META_DATA);
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }

    return true;
}
使用此方法,您可以实现自己版本的
ContextCompat.checkSelfPermission
,其中所有不存在的权限都将自动视为已授予:

private int myCheckSelfPermission(@NonNull Context context, @NonNull String permission) {
    if(!permissionExistsOnCurrentApiLevel(permission)) {
        return PackageManager.PERMISSION_GRANTED;
    }

    return ContextCompat.checkSelfPermission(this, permission);
}

这很奇怪。您能否尝试使用常规的权限方法,即requestPermission(requestedPermissions,requestCode)@dex问题在于,权限的活动相关方法只能在API上访问23@Skirx:是的,您需要设置targetSDK=23和compileSDK=23才能使用它们,如果您没有设置这些,那么您将无法支持Android M anyhow@dex这里的问题是我正在设置android:minSdkVersion=“14”和android:targetSdkVersion=“23”. 正如你在下面的问题上所看到的,4.0.3版本的许可被拒绝。如果我设置android:minSdkVersion=“23”和android:targetSdkVersion=“23”,它只在OS 6.0上工作,并且行为正常,没有问题。这里的问题是checkSelfPermission必须返回OS 4.0.3上授予的权限,而不是拒绝。CompatLibrary问题我认为一个简单的解决方法是请求
WRITE\u EXTERNAL\u STORAGE
权限,这就是API 4。在M中,
WRITE
READ
位于同一权限组中,因此请求前者也将授予后者访问权限。唯一的缺点是4.1之前的版本会看到需要新的权限,如果您以前只要求
READ
@dextor:这假设Android将始终在权限组级别而不是权限级别向用户请求权限。我不会做出这样的假设。