背景
直到 Android Q,如果我们想获取有关 APK 文件的信息,我们可以使用WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE来访问存储,然后在文件路径上使用PackageManager.getPackageArchiveInfo函数。
存在类似的情况,例如在压缩文件上使用ZipFile 类,可能还有无数的框架 API 和第三方库。
问题
谷歌最近宣布了对 Android Q 的大量限制。
其中之一称为Scoped Storage,它在访问设备拥有的所有文件时会破坏存储权限。它允许您处理媒体文件,或使用非常受限的存储访问框架 ( SAF ),它不允许应用程序使用 File API 和文件路径访问和使用文件。
当 Android Q Beta 2 发布时,它破坏了很多应用程序,包括谷歌。原因是它默认打开,影响所有应用程序,无论它们是否针对 Android Q。
原因是许多应用程序、SDK 和 Android 框架本身 - 都经常使用 File API。在许多情况下,它们也不支持 InputStream 或 SAF 相关的解决方案。这方面的一个例子正是我写的关于 (PackageManager.getPackageArchiveInfo) 的 APK 解析示例。
然而,在 Q beta 3 上,情况发生了一些变化,因此以 Q 为目标的应用程序将具有范围存储,并且有一个标志可以禁用它,并且仍然像往常一样使用正常的存储权限和文件 API。可悲的是,旗帜只是暂时的(在这里阅读),所以它推迟了不可避免的事情。
我试过的
我已经尝试过并发现了接下来的事情:
使用存储权限确实没有让我读取任何不是媒体文件的文件(我想查找 APK 文件)。就好像文件不存在一样。
使用 SAF,我可以找到 APK 文件,并通过一些解决方法来找到它的真实路径(链接在这里),我注意到 File API 可以告诉我文件确实存在,但它无法获得它的大小,并且框架未能使用其路径使用
getPackageArchiveInfo
. 在这里写了这个我试图对文件建立一个符号链接(链接在这里),然后从符号链接中读取。它没有帮助。
对于解析APK文件的情况,我尝试寻找替代解决方案。我找到了 2 个使用 File 类(此处和此处)处理 APK 的 github 存储库,以及一个使用 InputStream 代替(此处)的存储库。遗憾的是,使用 InputStream 的那个非常旧,缺少各种功能(例如获取应用程序的名称和图标)并且不会很快更新。此外,拥有一个库需要维护以跟上未来的 Android 版本,否则将来可能会出现问题,甚至崩溃。
问题
一般来说,有没有办法在使用 SAF 时仍然使用 File API?我不是在谈论根解决方案或只是将文件复制到其他地方。我说的是更可靠的解决方案。
对于APK解析的情况,有没有办法解决框架只提供文件路径作为参数的问题?也许有任何解决方法或使用 InputStream 的方法?