在Android 11 - API 30中,requestLegacyExternalStorage无法正常工作。

48

谷歌最近在API 29中引入了一些与存储API相关的更改,例如作用域存储,我们通过在清单文件中添加'requestLegacyExternalStorage=true'来选择退出。但是现在当我将targetSdkVersion升级到30时,这似乎不再起作用了。此更改后下载目录中的某些文件未列出(File.listFiles)。


确实。那只适用于Android Q。 - blackapps
1
下载目录中的一些文件未列出。我认为没有一个文件被列出。 - blackapps
是的,那是真的。 - Ebin Joy
5个回答

59
但是,当我将targetSdkVersion升级到30时,这似乎不再起作用。
这是正确的。Android 11(API 30+)中,requestLegacyExternalStorage=true无效,你不能再“退出”。在Android 10中,它可用于为开发人员提供一个过渡/宽限期,以便能够迁移到范围存储模型。
选项1:在仍然针对API 29的情况下迁移应用程序中的数据,然后一旦您的迁移数据与范围存储兼容,您应该能够发布一个针对API 30的更新。https://developer.android.com/training/data-storage/use-cases 如果用户跳过此版本并直接从以前的版本更新到最新版本,则可能会出现问题,并且您将无法访问未迁移的数据。
选项2:看来谷歌已经注意到了这个明显的警告,并在针对API 30时包含了一个preserveLegacyExternalStorage=true选项,使您可以迁移数据。https://developer.android.com/reference/android/R.attr#preserveLegacyExternalStorage 未来,您可以参考此表格根据用例来决定使用哪种存储“框架”:https://developer.android.com/training/data-storage 由于Google的解决方案不会涵盖所有当前用例,并且可能没有迁移路径,因此有可能某些应用程序根本无法成功迁移,这取决于它们如何与File API进行交互。
例如,我几年前发布了一个应用程序,允许用户使用MediaStoreContentResolver更新专辑封面图像的数据 - 这些数据存储在共享存储中。查看Android 10+ AOSP MediaProvider源代码后,似乎以前使用MediaStore将专辑封面图像更新到指向数据文件的应用程序不再起作用,仅仅是因为MediaProvider内部在隐藏的.thumbnails文件夹中创建自己的艺术品,直接查看mp3并使用MediaExtractor,从未引用插入的ContentValues来引用艺术品。因此,即使您可以自己更新艺术品,查询MediaStore并查看它,其他应用程序也必须在API 29+中使用ContentResolver#loadThumbnail,该方法不引用您更新的值,并且会懒惰地创建艺术品,或者选择.thumbnails文件夹中已经生成的文件。显然,这些都没有文档记录,我的应用程序受到了巨大的反弹和负面评价,但是这些变化是破坏性的变化,完全超出了我的控制范围,而且我需要查看AOSP源代码才能发现Android已经从根本上改变了行为。{{这不是抱怨,而是说明由于基本未记录的AOSP行为,这些更改没有提供迁移路径的例子。}}

2
Android SDK 29以下的版本怎么办?如何处理权限?我的应用支持SDK 21+。我仍然需要考虑这些版本的权限。谢谢! - Mark Delphi
我在Play Store中针对29版本发布了应用程序。我需要在5月5日之前立即在Play Store上发布新版本吗?还是我可以等到下一个版本发布? - user3066829
不需要 - 只有当您的应用程序针对Android 11(API级别30)并声明MANAGE_EXTERNAL_STORAGE权限时,才需要这样做。该权限在Android 11中添加 - https://support.google.com/googleplay/android-developer/answer/10467955 - 毫无疑问,这将是一个暂时的缓解,Google可能会在未来某个时候决定所有新应用程序和发布都要针对30+。基本上,当您针对API 30时,应该有一个迁移策略。我会感到惊讶,除非您是应用领域的大玩家,否则您将很难获得该权限。 - Mark
更新:根据@Pawel的最新消息,自2021年8月起,Play商店将要求目标SDK为30。 - Mark
1
@MarkKeen,你能否看一下这个问题:https://dev59.com/TVIG5IYBdhLWcg3wrziG#sB3tnYgBc1ULPQZFEYIX - Dr.jacky
我还以为苹果对开发者已经够糟糕了 :眼-roll: - Dale_Plante

43
根据 https://developer.android.com/about/versions/11/privacy/storage,Android 11 的存储方面发生了一些变化:
  • Android 10 设备
    • requestLegacyExternalStorage 将继续工作,无论目标 sdk 如何
  • Android 11 设备
    • 新的安装目标 sdk 29:将尊重 requestLegacyExternalStorage
    • 新的安装目标 sdk 30: requestLegacyExternalStorage 总是 false
    • 从目标 sdk 29 升级到 30:如果设置了 preserveLegacyExternalStorage,则 requestLegacyExternalStoragetrue(这是纯迁移情况,如果用户卸载/重新安装应用程序,则不会保留此状态)
现在你几乎被迫实施范围存储。除非你已经准备好进行迁移,否则请继续以 targeting sdk 29 为目标,因为没有办法在 targeting sdk 30 的 Android 11 设备上强制使用旧的存储方式。 更新:从 2021 年 8 月起,应用商店要求 targeting sdk 必须为 30。

1
有关如何进行此操作的任何教程,请? - Moustafa EL-Saghier
2
我搜索了6个小时,但最终找到了清晰的概念,谢谢。但是,有没有任何教程可以展示迁移并支持所有API? - Noor Hossain
你测试过从目标SDK 29升级到30的情况吗?我尝试了好几次,但是无论是从28到30还是从29到30,访问旧存储空间总是失败的。 - opLW
@opLW 我在 API 30 模拟器上的升级安装没有任何问题。 - Pawel
1
@Pawel 我将我的代码迁移到了新的 Android API 30 的解决方案上,并且在模拟器 API 30 上运行良好,但是在模拟器 API 29 上仍然无法从图库中选择图片。目标 SDK 是 30;但是,如果我在使用新解决方案(MediaStore - API 30)时添加 requestLegacyExternalStorage = true ,则可以在所有 API 版本上运行。这样做是否正确? - Dr.jacky
显示剩余5条评论

4

13
需要翻译的内容:This comes with a big caveat, the app must conform to the Google Play policy for this permission, " the app’s usage of the permission must fall within permitted uses, and must be directly tied to the core functionality of the app" - so unless your app is a File Manager or Virus scanning app etc.. I'd advise not to use this permission, otherwise you might find its rejected and have a load of refactoring to do.这带有一个重要的限制条件,应用必须符合Google Play政策关于此权限的规定,“应用程序对该权限的使用必须符合允许使用,并且必须直接与应用程序的核心功能相关联”- 所以除非您的应用是文件管理器或病毒扫描应用等,否则我建议不要使用此权限,否则可能会被拒绝并需要进行大量的重构工作。 - Mark
@MarkKeen 这个问题有什么解决方案吗? - RkKhanpuriya
我申请了这个权限并且得到了批准。我的应用是一款电子书阅读器。但问题是现在我的应用只能在Android 11+上运行。对于旧版本,无法获取MANAGE_EXTERNAL_STORAGE权限。 - Jianwu Chen

1
在Android 11上运行但针对Android 10(API级别29)的应用程序仍可以请求requestLegacyExternalStorage属性。此标志允许应用程序暂时退出与作用域存储相关的更改,例如授予对不同目录和不同类型的媒体文件的访问权限。 将应用程序更新为针对Android 11后,系统将忽略requestLegacyExternalStorage标志。

-1

无需调用“requestLegacyExternalStorage=true”,因为它在Android 11+上不起作用。

https://github.com/apache/cordova-plugin-media有一个新的更新,可以解决Android 11+的文件保存路径问题。

如果您在项目中更新“/platforms/android/app/src/main/java/org/apache/cordova/media/AudioHandler.java”和“/platforms/android/app/src/main/java/org/apache/cordova/media/AudioPlayer.java”,那么它应该可以工作。

https://raw.githubusercontent.com/apache/cordova-plugin-media/4093f7e14fe65f94ffbef072ed188a0205e78a59/src/android/AudioHandler.java

https://raw.githubusercontent.com/apache/cordova-plugin-media/4093f7e14fe65f94ffbef072ed188a0205e78a59/src/android/AudioPlayer.java


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接