Android Q:file.mkdirs()返回false

khu*_*rav 2 android android-9.0-pie

我们有一个使用外部存储来存储一些临时文件的应用程序:图像,二进制数据。直到最近,用于该代码的代码已经运行了几年,没有太大的变化。在Android Q上不起作用:

File f = new File(Environment.getExternalStorageDirectory().toString() + File.separator + MainActivity.APP_DIR)
f.mkdirs();
// do sth with f
Run Code Online (Sandbox Code Playgroud)

mkdirs现在只返回false

清单中提供了所需的权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)

该代码可在Android的早期版本上正常运行。这种访问类型在系统级别上有变化吗?如果是这样,解决方法是什么?

Ano*_*p M 11

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


在 API 级别 29 中,不推荐直接访问共享/外部存储设备。当应用以 为目标时Build.VERSION_CODES.Q,从getExternalStorageDirectory()方法返回的路径不再可供应用直接访问。通过迁移到Context#getExternalFilesDir(String)MediaStoreIntent#ACTION_OPEN_DOCUMENT等替代方案,应用程序可以继续访问存储在共享/外部存储上的内容。

除非您的应用程序需要访问不在应用程序特定目录中的文件,否则最好使用作用域存储。

这些谁面临的问题与Android的-Q文件管理可以通过阅读文章,以进一步了解。


Paw*_*wel 7

通过引入Scoped Storage,android Q发生了巨大的隐私更改。

从Q beta 4开始,可以通过以下方式选择退出该功能:

  • 定位api 28(或更低版本)
  • 使用requestLegacyExternalStorage清单属性:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting Android Q. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

*请注意,我没有测试过,只是引用文档