以编程方式测试是否在Android 10+中禁用了旧版外部存储访问


12

是否有一个简单的API调用可以告诉我在Android 10或更高版本上运行的应用程序是否必须使用范围存储访问权限,即是否禁用了常规文件访问(又称为“旧版外部存储”)?请注意,即使AndroidManifest.xml中的应用程序也声明了:

  android:requestLegacyExternalStorage="true"

由于将来Google的政策更改,文件访问仍可能会被拒绝,因此测试该值是没有用的。我发现的唯一方法是测试外部存储根目录是否可读,为此,应用程序必须首先请求存储许可,如果禁用了旧存储,则该存储对其他任何东西都没有用。

public static boolean mustUseScopedStorage() {
    // Impractical must first ask for useless Storage permission...
    File exSD = Environment.getExternalStorageDirectory();
    return !exSD.canRead(); // this test works only if Storage permission was granted.
}

我想我曾经看过一种新的API可以检测到这一点,但是现在找不到该文章了...


an app running on Android 10 or later must use Scoped Storage access?你能解释一下你的意思吗?您要考虑哪些功能?我知道,例如,为N带来的存储卷和存储管理器已经被弃用了
Q。– blackapps,

我的意思是常规的Java File访问超出了系统分配给应用程序的沙箱的范围,例如在C / C ++ JNI代码fopen(“ filename.ext”,mode);中。如果文件路径超出系统分配的应用程序目录,将无法使用(访问被拒绝)。好吧,如果您在清单中使用android:requestLegacyExternalStorage =“ true”,它将立即在Android 10上运行,但这是一个临时解决方案,明年可能会完全禁用。更多如androidcentral.com/what-scoped-storage-android-q
gregko

即使在那篇文章中,也不清楚什么是范围存储。
blackapps

@blackapps,也许这篇文章可以更好地解释它:developer.android.com/training/data-storage/files/…–
gregko

好。仅限访问应用程序专用目录。
blackapps,

Answers:


8

您可以使用以下两种方法android.os.Environment

  • isExternalStorageLegacy(File path)

    返回给定路径上的共享/外部存储媒体是否为旧版视图,其中包括该应用程序不拥有的文件。

  • isExternalStorageLegacy()

    返回主要的共享/外部存储媒体是否为旧版视图,其中包括该应用程序不拥有的文件。

此值可能requestLegacyExternalStorage与应用清单中请求的值不同,因为应用可能会基于首次安装的时间继承其旧状态。

非旧版应用程序可以通过继续发现和读取属于其他应用程序的媒体MediaStore

如果您发现自己可以访问旧存储,我个人认为将数据迁移到作用域存储中并使用它会更好,因为旧存储可能会在没有警告的情况下停止工作。


1
谢谢@Zaffy,这正是我一直在寻找的答案。它运行完美,无需请求“存储访问”。
gregko
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.