在 Android API 中访问外部存储 29

Accessing external storage in Android API 29

我正在尝试实现一些清理工具。越来越多的厂商出于某些“安全原因”禁止root设备,禁止不要求解锁。

在API28之后,这段代码会报错:


ActivityCompat.requestPermissions(this, new String[]{
  Manifest.permission.READ_EXTERNAL_STORAGE,
  Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 1); // Request permission or not, Will got same result

File rootFolder = Environment.getExternalStorageDirectory(); // That is working fine
rootFolder.listFiles(); // That will return null

当然可以,我可以用这个:

android:requestLegacyExternalStorage="true"

但我相信将来会被杀死。

那么,有什么优雅的方式来管理 SDCard 吗?

On Android 10 Environment.getExternalStorageDirectory()Environment.getExternalStoragePublicDirectory() 将 return 存储路径,但路径不可读或不可写。

  1. 对于 Android 10,如果将 android:requestLegacyExternalStorage="true" 添加到应用程序,您可以继续使用 Environment.getExternalStorageDirectory() 和 Environment.getExternalStoragePublicDirectory() 提供的路径清单文件中的标记。在运行时,您的应用可以调用 Environment.isExternalStorageLegacy() 来检查请求是否已完成。

  2. 另一种(未知)可能性(仅适用于 Android 10)是将 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> 添加到清单文件。 用户必须转到应用程序的高级设置并从 Advanced settings Install unknown apps | Allow from this source 启用。 这样做的好处是用户可以切换访问权限。如果你实现一个意图,你可以让用户更容易 Settings.ACTION_APPLICATION_DETAILS_SETTINGS 他可以在其中更改设置。 有趣的是 Environment.isExternalStorageLegacy() return 也是真的。

  3. 为 Android 11 编译这两个选项在 Android 11 设备上均无效。 (但他们继续为 Android 10 台设备工作)。 Environment.getExternalStorageDirectory() 和Environment.getExternalStoragePublicDirectory() 的路径是usable again in read mode and very often in write mode too。这很棒,因为可以再次使用文件 class 简单地列出目录的内容,例如下载或图片或 DCIM/Camera。 但是将 <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> 添加到清单文件并实现一个意图 Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION 将允许您的应用 read/write 访问所有文件,甚至是可移动微型 SD 卡上的文件。 (最后,您可以删除 google 禁止使用您自己的应用程序 read/write 在您自己的 Android 设备上使用您自己的微型 SD 卡)。 Environment.isExternalStorageManager() 可用于检查权限是否为 on/off。 只要您不尝试将您的应用程序上传到 Play 商店就可以了。

在下面的清单中使用 android:requestLegacyExternalStorage="true"