API 26+:WRITE_EXTERNAL_STORAGE权限始终被拒绝

Den*_*hev 20 android android-permissions android-8.0-oreo

我已将我的应用程序切换到目标API 27,现在它无法获得WRITE_EXTERNAL_STORAGE权限 - grantResult始终是-1.

我的应用程序需要此权限,因为它不使用应用程序私有外部存储空间(不需要 WRITE_EXTERNAL_STORAGE从API 19开始).

我知道在API 26中有权限的行为更改.然而,这并不能解释我的问题.

我以标准方式请求两者READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE权限:

ActivityCompat.requestPermissions(activity, new String[] {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    }, requestCode);
Run Code Online (Sandbox Code Playgroud)

(两个权限都通过<uses-permission清单声明).

出现对话框,然后单击"允许":

在此输入图像描述

但是在onRequestPermissionsResult回调中我得到(并且被授予)-1(拒绝).WRITE_EXTERNAL_STORAGE0READ_EXTERNAL_STORAGE

0因为我已经要求并且可能两者都同意,结果不应该是两者兼而有之吗?

我试图WRITE_EXTERNAL_STORAGE单独请求,但在这种情况下,对话框根本不会出现.

还有一个细节:我刚检查了合并的清单build/intermediates/manifests/full/debug,发现WRITE_EXTERNAL_STORAGE权限有属性android:maxSdkVersion="18"(我的清单中没有这样的属性).这可能会发生,因为我的应用程序有minApiVersion=21,但我不确定.

Com*_*are 33

沿着这条线的某个地方,你正在拾取那个android:maxSdkVersion="18"属性.我的猜测是它来自一个图书馆.在编辑自己的清单时,请检查Android Studio中的"Merged Manifest"选项卡.它将详细介绍各种元素和属性的贡献.

android:maxSdkVersion具有<uses-permission>在更高的Android SDK版本上删除元素的效果,至少在运行时权限的工作方式方面如此.

因为你需要这个权限的所有版本,增加tools:remove="android:maxSdkVersion"了对<uses-permission>元素应该恢复了android:maxSdkVersion="18",给你你所期望的.

  • 从来没有注意到,Android Studio中实际上有一个“ Merged Manifest”选项卡,这确实很棒。 (2认同)
  • 像@DenisKniazhev有100%确切的问题,但这个解决方案有效!我也不知道有什么像"Merged Manifest".对于像我这样的人,当您在"文本"选项卡旁边打开"AndroidManifest.xml"文件时,可以找到"Merged Manifest"选项卡,该文件位于您的清单左下方(对于Android Studio 3.1.3)文件. (2认同)
  • 如果您使用的是HockeyApp,则无法写入外部存储,这就是原因。您也可以执行`tools:node =“ replace”`。 (2认同)