android - 如何解决 Android 10 的存储问题

标签 android file android-fileprovider storage-access-framework scoped-storage

由于Android在文件访问方面不同主要版本之间非常不一致,我感到有些失落。
我尝试尽可能简单地描述问题:

My Company 使用商业原生 DRM 来保护我们提供的其他原生库。我们有一个 Licensing App,它调用了一些 Voodoo,最终得到了/sdcard/companyname/LicenseContainer/中的 Licensing 文件。其他 protected 应用程序在 native 代码中查看此目录,检查用户是否拥有有效的许可证。

然而,Android 10 更新完全使此工作流程无效,因为它仅提供 scoped storage access .我们可以使用 Storage Manager 来解决问题。授予访问权限,不幸的是现在也已弃用。

所以我现在的问题是:
一个应用程序如何将文件保存到/sdcard/FOLDER 上的某个位置

  • 删除应用时未删除
  • 可在 native 代码中访问其他应用程序

  • 我对所有可能的解决方案(SAF、FileProvider 等)有点不知所措,这些解决方案经常调用一个应用程序授予另一个应用程序的权限。但是这些文件应该可以在没有安装的第一个应用程序的情况下访问。

    我知道必须有一个解决方案,因为最近的 FileManager(即 Files by Google )可以访问整个 /sdcard/目录。

    没有像 android:requestLegacyExternalStorage="true" 那样调用“黑客”的最简单、面向 future 的路线是什么?

    最佳答案

    您可以要求用户授予您对任何文件或目录的访问权限,包括内部存储或外部 SD 卡的根目录。您可以为您的应用程序永久访问此访问权限,之后可以使用 Scoped Storage API 在任何地方读取/写入文件,直到应用程序被卸载或重置。

    然后,如果您需要在 native C/C++ 代码中读取或写入文件,您可以获取文件的 Linux 文件描述符(int 编号)并将其传递给 native 代码以与 fdopen() 调用一起使用。

    这是一个 Java 代码 fragment ,用于从单个文件 Uri 中获取文件描述符(字符串形式类似于 content://...)

        ParcelFileDescriptor parcelFileDescriptor =
                getContentResolver().openFileDescriptor(uri, "r"); // gets FileNotFoundException here, if file we used to have was deleted
        int fd = parcelFileDescriptor.getFd(); // detachFd() if we want to close in native code
    

    如果您有本地库的源代码,或者可以使用 C FILE* 调用它们 - 它会正常工作。唯一的问题是当您没有源代码并且他们需要文件路径/名称时。 * 更新 * :仍然可以使用路径/文件名字符串传递给需要文件名的 C/C++ 函数。简单地代替“真实路径/文件名”,为符号链接(symbolic link)创建一个名称,如下所示:
    // fd is file descriptor obtained in Java code above
    char fileName[32];
    sprintf(fileName, "/proc/self/fd/%d", fd);
    // The above fileName can be passed to C/C++ functions that expect a file name.
    // They can read or write to it, depending on permissions to fd given in Java,
    // but I guess C/C++ code can not create a new file. Someone correct me,
    // if I'm mistaken here.
    

    但是,此时我不确定当您以这种方式在应用程序“沙盒”之外的目录中创建文件时,如果系统在卸载后也会删除该文件......需要编写一个快速测试Android 10 找出来,然后我们仍然不知道谷歌是否会在 future 改变这种行为。

    关于android - 如何解决 Android 10 的存储问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57809181/

    相关文章:

    java - Android:无法提供结果,无法找到具有权限的提供者的元数据

    android - Android 11 中的 PDF 查看器权限问题

    java - 在闪屏中显示图像

    Android - 如何从网络服务器下载文件

    c - 二维字符数组出现问题,程序无法打印

    PHP file_get_contents() : content truncated from 2147483648 to 2147483647 bytes

    android - 添加我的 FileProvider 时出现问题

    Android iBeacon 库测距 api

    java - 如何在 Android 上的 SQLite 中存储字符串集合?

    file - 如何使用批处理文件添加到现有 Rar 存档?