37

Google 最近在 API 29 中引入了一些与存储 API 相关的更改,例如范围存储,我们通过在 Manifest 中添加“requestLegacyExternalStorage=true”来选择退出。但是现在当我以 SdkVersion 30 为目标时,这似乎不再起作用。此更改后,下载目录中的某些文件未列出 (File.listFiles)。

4

5 回答 5

52

但是现在当我以 SdkVersion 30 为目标时,这似乎不再起作用

那是对的。Android 11 (API 30+) requestLegacyExternalStorage=true什么都不做,你不能再“选择退出”。它在 Android 10 中可用,为开发人员提供过渡/宽限期,以便能够迁移到范围存储模型。

选项 1:在您的应用程序中迁移数据,同时仍以 API 29 为目标,一旦您迁移的数据与范围存储兼容,您应该能够发布针对 API 30 的更新 - https://developer.android.com/training/数据存储/用例

如果用户跳过此版本并直接从以前的版本更新到最新版本,并且您遇到无法访问的未迁移数据,这可能会带来其自身的问题。

选项 2:Google 似乎看到了这个明显的警告,并preserveLegacyExternalStorage=true在针对 API 30 时包含了一个选项,以允许您迁移数据。https://developer.android.com/reference/android/R.attr#preserveLegacyExternalStorage

展望未来,您可以参考此表来根据用例决定使用什么存储“框架”:https ://developer.android.com/training/data-storage

某些应用程序可能根本无法成功迁移,这取决于它们与FileAPI 的交互方式,因为 Google 的解决方案不会涵盖所有当前用例,并且可能没有迁移路径。

例如,几年前我发布了一个应用程序,它允许用户使用MediaStoreContentResolver更新专辑封面图像的数据来更新专辑封面 - 这存储在共享存储中。查看 Android 10+ AOSPMediaProvider源代码后,似乎用于MediaStore更新专辑插图以指向数据文件的应用程序不再有效,这仅仅是因为MediaProvider内部在隐藏文件夹中创建自己的插图,.thumbnails直接查看 mp3 和使用MediaExtractor, 并且从不引用ContentValues插入以引用艺术品的 。因此,即使您可以自己更新艺术品,查询MediaStore它并查看它,其他应用程序也必须使用ContentResolver#loadThumbnail在 API 29+ 中,它不引用您更新的值,要么懒惰地创建艺术品,要么选择文件.thumbnails夹中已经生成的文件。显然,这些都没有记录在案,我的应用程序遭到了负面评论的强烈反对,但这些变化是破坏性的变化,完全超出了我的控制,让我查看了 AOSP 源代码,发现 Android 从根本上改变了行为。

(这不是咆哮,而是一个示例,说明这些更改如何因为 AOSP 的基本未记录行为而无法提供迁移路径)。

于 2020-08-11T19:40:24.790 回答
39

https://developer.android.com/about/versions/11/privacy/storage中所述,Android 11 上的存储有一些变化:

  • 安卓 10 设备
    • requestLegacyExternalStorage无论目标 sdk 如何,都将继续工作
  • 安卓 11 设备
    • 针对 sdk 29 的新安装:requestLegacyExternalStorage尊重价值
    • 针对 sdk 30 的新安装:requestLegacyExternalStorage总是false
    • 从目标 sdk 29 升级到 30:如果preserveLegacyExternalStorage已设置,requestLegacyExternalStorage则为true(这是纯粹的迁移情况,如果用户卸载/重新安装应用程序,则不会保留此状态)

此时您几乎被迫实施范围存储。除非您准备好迁移,否则请继续以 sdk 29 为目标,因为无法在具有目标 sdk 30 的 Android 11 设备上强制执行旧版存储。

更新:截至 2021 年 8 月,Play 商店需要目标 sdk 30

于 2020-08-11T19:45:00.257 回答
4

直到 2021 年初才这样做(谷歌说):-

如果你想定位到 android 11,你应该使用 MANAGE_EXTERNAL_STORAGE 权限。

访问此页面了解更多详情:https ://developer.android.com/training/data-storage/manage-all-files

于 2020-12-20T12:55:30.213 回答
1

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

于 2021-05-27T16:01:08.723 回答
0

无需调用不适用于 Android 11+ 的“requestLegacyExternalStorage=true”。

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

于 2021-11-01T20:38:44.167 回答