背景
在 Android Q 之前,如果我们想获取有关 APK 文件的信息,我们可以使用 WRITE_EXTERNAL_STORAGE和 READ_EXTERNAL_STORAGE访问存储,然后使用 PackageManager.getPackageArchiveInfo文件路径上的函数。
也有类似的情况,比如使用ZipFile class在压缩文件上,可能还有无数的框架 API 和第三方库。
问题
谷歌最近宣布了对 Android Q 的大量限制。
其中之一称为 Scoped Storage ,在访问设备拥有的所有文件时会破坏存储权限。它允许您处理媒体文件,或使用非常受限的存储访问框架 (SAF),它不允许应用程序使用文件 API 和文件路径访问和使用文件。
当 Android Q Beta 2 发布时,它破坏了很多应用程序,包括谷歌。原因是它默认打开,影响所有应用程序,无论它们是否针对 Android Q。
原因是许多应用程序、SDK 和 Android 框架本身 - 都经常使用 File API。在许多情况下,它们也不支持 InputStream 或 SAF 相关的解决方案。这方面的一个例子正是我写的关于 (PackageManager.getPackageArchiveInfo) 的 APK 解析示例。
然而,在 Q beta 3 上,情况发生了一些变化,因此以 Q 为目标的应用程序将具有范围存储,并且有一个标志可以禁用它,并且仍然像往常一样使用正常的存储权限和文件 API。遗憾的是,该标志只是暂时的(阅读 here),因此它推迟了不可避免的 .
我试过的
我已经尝试过并发现了接下来的事情:
getPackageArchiveInfo
使用其路径.写了这篇 here 问题
最佳答案
当我只能处理文件或文件路径时如何处理 SAF?即使您只能将 Java File 对象或路径字符串发送到您无法修改的库函数,也有可能:
首先,获取您需要处理的文件的 Uri(以字符串形式,类似于“content://...”),然后:
try {
ParcelFileDescriptor parcelFileDescriptor =
getContentResolver().openFileDescriptor(uri, "r"); // may get FileNotFoundException here
// Obtain file descriptor:
int fd = parcelFileDescriptor.getFd(); // or detachFd() if we want to close file in native code
String linkFileName = "/proc/self/fd/" + fd;
// Call library function with path/file string:
someFunc(/*file name*/ linkFileName);
// or with File parameter
otherFunc(new File(linkFileName));
// Finally, if you did not call detachFd() to obtain the file descriptor, call:
parcelFileDescriptor.close();
// Otherwise your library function should close file/stream...
} catch (FileNotFoundException fnf) {
fnf.printStackTrace(); // or whatever
}
关于android - 当我只能处理文件或文件路径时如何处理 SAF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56199568/