在 Android Pie 之前,我总是存储应用程序需要存储在 /sdcard/my-app/
上的文件,我通过
File fBaseDir = new File(Environment.getExternalStorageDirectory(), "my-app");
我的一个应用程序在 /sdcard/my-app/favicons
中存储了数百个(最多数千个)图标,当用户创建应用程序的备份时,它会存储在 /sdcard/my-app/backups
中。网页-谷歌浏览器在与我的应用程序共享时截取的屏幕截图存储在 /sdcard/my-app/screenshots
中,依此类推。
当我卸载该应用程序时,我可以稍后重新安装它并且仍然有所有的网站图标、屏幕截图和备份可用于恢复状态,而不必重新下载所有的网站图标(并且可能丢失所有其他数据)。
我还可以轻松创建 /sdcard/my-app/
目录的备份,方法是将其复制到我的 PC,然后在另一部手机上恢复它,例如当我迁移到新设备时。
我还可以使用文件资源管理器查看该目录中有哪些文件,然后选择并通过电子邮件发送它们或将它们复制到 Google 云端硬盘,或者专门删除其中的一些文件(如旧备份文件)。
在 Android 10 中,这种方法已经崩溃。我无法将网站图标添加到图像媒体文件夹,因为它们不是真实图像,它们会不必要地扰乱视图,并可能因此禁止我的开发者帐户进入 Play 商店。我也不想将所有这些数据存储在 App-Private 目录中,因为当应用程序卸载时它会被删除,并且因为其他应用程序(如资源管理器)无法访问它们。
我有哪些选择?手动选择文件或目录不是一种选择,除非只需要选择一次目录,然后永远授予访问权限(读取和写入文件)。
我从不在 /sdcard/my-app/
之外阅读或写作。
原文由 Daniel F 发布,翻译遵循 CC BY-SA 4.0 许可协议
在 Android Q 中,默认情况下禁用私人文件夹之外的应用程序的直接文件访问。您可以在您的案例中使用以下几种策略:
requestLegacyExternalStorage
具有旧行为,但它不再适用于 Android R,因此它确实是一个短期解决方案;getExternalFilesDir()
方法保存文件。这是您的私人文件夹,其他应用只有在拥有READ_EXTERNAL_STORAGE
权限时才能访问这些文件。在这种情况下,最好使用FileProvider
授予其他应用程序对您的文件的访问权限。StorageManager
的方法getPrimaryStorageVolume().createOpenDocumentTreeIntent()
请求访问外部主卷。在这种情况下,您需要用户同意,并且您将无法直接使用File
api,但是使用DocumentFile
类你有一个非常相似的接口,所以这是更接近的解决方案到旧的行为。如果您需要在前台和后台执行操作,它就可以工作,即没有用户交互,除了第一次交互请求权限。我为第 3 点链接了 Flipper 库,它有助于管理文件,就像在旧的 android 版本中一样。