当我只能处理文件或文件路径时如何处理 SAF?

2024-05-11

背景

在 Android Q 之前,如果我们想获取有关 APK 文件的信息,我们可以使用写外部存储 https://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE and 读外部存储 https://developer.android.com/reference/android/Manifest.permission.html#READ_EXTERNAL_STORAGE访问存储,然后使用PackageManager.getPackageArchiveInfo https://developer.android.com/reference/android/content/pm/PackageManager.html#getPackageArchiveInfo(java.lang.String,%20int)文件路径上的函数。

类似的情况也存在,例如使用压缩文件类 https://developer.android.com/reference/java/util/zip/ZipFile在压缩文件上,可能还有无数的框架 API 和第三方库。

问题

谷歌最近宣布了对 Android Q 的大量限制。

其中之一称为范围存储 https://developer.android.com/preview/privacy/scoped-storage,这会在访问设备拥有的所有文件时破坏存储权限。它可以让您处理媒体文件,或使用非常有限的存储访问框架(SAF https://developer.android.com/guide/topics/providers/document-provider),它不允许应用程序使用文件 API 和文件路径访问和使用文件。

当Android Q Beta 2发布时,它破坏了很多应用程序,包括谷歌的应用程序。原因是它默认打开,影响所有应用程序,无论它们是否针对 Android Q。

原因是许多应用程序、SDK 和 Android 框架本身 - 都经常使用文件 API。在许多情况下,它们也不支持 InputStream 或 SAF 相关的解决方案。一个例子就是我写的 APK 解析示例 (PackageManager.getPackageArchiveInfo)。

然而,在 Q beta 3 上,情况发生了一些变化,因此目标 Q 的应用程序将具有范围存储,并且有一个标志可以禁用它,但仍然像往常一样使用正常的存储权限和文件 API。遗憾的是,该标志只是暂时的(读here https://www.xda-developers.com/google-gives-developers-more-time-android-q-scoped-storage/),所以它推迟了不可避免的事情。

我尝试过的

我已经尝试并发现了接下来的事情:

  1. 使用存储权限确实不允许我读取任何非媒体文件的文件(我想找到 APK 文件)。就好像这些文件不存在一样。

  2. 使用 SAF,我可以找到 APK 文件,并通过一些解决方法来找到其真实路径(链接here https://issuetracker.google.com/issues/132825438),我注意到文件 API 可以告诉我文件确实存在,但它无法获取其大小,并且框架无法使用其路径getPackageArchiveInfo。写过这个here https://issuetracker.google.com/issues/132481545

  3. 我尝试创建一个到该文件的符号链接(链接here https://stackoverflow.com/questions/34608249/android-create-symbolic-link-in-the-app/56107194#56107194),然后从符号链接中读取。这没有帮助。

  4. 对于解析APK文件的情况,我尝试寻找替代解决方案。我找到了 2 个使用 File 类处理 APK 的 github 存储库(here https://github.com/jaredrummler/APKParser and here https://github.com/hsiafan/apk-parser),以及使用 InputStream 的一种(here https://github.com/joakime/android-apk-parser)。遗憾的是,使用 InputStream 的版本非常旧,缺少各种功能(例如获取应用程序的名称和图标),并且不会很快更新。此外,拥有一个库需要维护以跟上Android的未来版本,否则将来可能会出现问题,甚至崩溃。

问题

  1. 一般来说,有没有办法在使用 SAF 时仍然使用 File API ?我不是在谈论根解决方案或只是将文件复制到其他地方。我正在谈论一个更可靠的解决方案。

  2. 对于APK解析的情况,有没有办法克服框架只提供文件路径作为参数的问题?可能有任何解决方法或使用 InputStream 的方法吗?


当我只能处理文件或文件路径时如何处理 SAF?即使您只能发送 Java 文件对象或无法修改的库函数的路径字符串,这是可能的:

首先,获取您需要处理的文件的 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
    }          
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当我只能处理文件或文件路径时如何处理 SAF? 的相关文章

  • Twitter 登录说明

    我想在 Android 中创建一个 Twitter 应用程序 为此 我想创建一个登录页面并登录到 Twitter 为此 我们需要消费者密钥和消费者密钥 这是什么意思 要创建此登录页面 除了 Twitter 帐户之外 我们还需要其他任何东西吗
  • Service 和 IntentService,运行从服务器轮询数据库值的服务哪个更好?

    我读过很多关于Service and IntentService 然而 当做出决定时 我没有足够的信心选择使用哪种类型来创建一个后台服务 该服务将在一定时间间隔内从数据库轮询数据 并在获得所需数据时停止它 因为数据代表请求的状态 例如 订购
  • 从 Android 代码设置的 SECRET_CODE

    我知道如何使用清单文件中的秘密代码 它与此源代码配合良好
  • 调试:在 Android 1.0 中找不到文件

    今天我更新到 Android Studio v 1 0 在尝试编译任何项目时出现以下错误 app build intermediates classes debug 找不到文件 问题是在更新之前我没有任何问题 这是我实际尝试编译的代码 构建
  • Java:如何从转义的 URL 获取文件?

    我收到了一个定位本地文件的 URL 事实上我收到的 URL 不在我的控制范围内 URL 按照 RFC2396 中的定义进行有效转义 如何将其转换为 Java File 对象 有趣的是 URL getFile 方法返回一个字符串 而不是文件
  • 如何在android线性布局上获得阴影? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在android中为View设置阴影 https stackoverflow com questions 4406524 how to set shadow to a view in androi
  • 如何为发布而不是调试创建密钥库?扑

    我按照使用此网站部署 flutter 的步骤进行操作https flutter io android release https flutter io android release 当我运行 flutter build apk 时出现此错
  • 如何在android中设置权限WRITE_SECURE_SETTINGS? [复制]

    这个问题在这里已经有答案了 我正在尝试启用 4 0 以上的辅助功能服务设置 但它显示异常 即 引起原因 java lang SecurityException 权限拒绝 写入安全设置需要 android permission WRITE S
  • 如何在手机缓存中保存用户名和密码

    我有一个用户登录应用程序 它需要用户的电子邮件和密码 我想将电子邮件和密码保存在手机缓存中 以便用户不必再次输入 有什么办法可以将数据保存在Android缓存中吗 我认为你需要使用SharedPreference用于在设备中使用应用程序时保
  • glTexImage2D: 之前出错:( 0x506 内部 0x1908 格式 0x1908 类型 0x1401

    当使用 Android Studio 运行模拟器时 我在模拟器屏幕上看不到任何内容 一切都是黑色的 我得到以下事件日志 模拟器 glTexImage2D 出错了 0x506 内部 0x1908 格式 0x1908 类型 0x1401 我已经
  • 放置在 NavigationDrawer 顶部的片段

    我正在尝试添加一个PreferenceFragment在我的应用程序中 问题是 它自动放置在我的顶部NavigationDrawer public class SetPreferenceActivity extends Activity O
  • Android 应用程序中的 Eszett (ß)

    我的 res layout activity 文件中的德语 字符在我的应用程序中自动转换为 ss 即使我将语言和键盘设置为德语 它仍然不会显示 Android 中可以显示 吗 edit
  • 画透明圆,外面填充

    我有一个地图视图 我想在其上画一个圆圈以聚焦于给定区域 但我希望圆圈倒转 也就是说 圆的内部不是被填充 而是透明的 其他所有部分都被填充 请参阅这张图片了解我的意思 http i imgur com zxIMZ png 上半部分显示了我可以
  • Android FragmentTransaction 自定义动画(未知动画师名称:Translate)

    我正在尝试让自定义动画与我的片段一起使用 我已按照在线教程进行操作 但出现以下错误 java lang RuntimeException 未知的动画师名称 翻译 动画的 XML 如下
  • 有关 ListView 自定义行布局项目上的 onClick() 事件的帮助

    我有一个 ListView 其行由我格式化 每行都有 ImageView 和 TextView 的混合 我还实现了自己的适配器 并且能够通过它绘制每一行 现在 我想要这样的东西 用户单击 ImageView 不是行上的其他任何位置 但只有此
  • 如何在android asynctask中使用inputstream作为参数?

    我正在制作一个 Android 应用程序来跟踪股票详细信息 我将通过 csv 雅虎财经 检索数据 据我所知 在android 4 0中 网络连接无法在主线程上完成 因此 我将使用 asynctask 来建立连接 但是 我在参数方面遇到了一些
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • Android:AsyncTask ProgressDialog 将不会在 ActivityGroup 中打开

    我试图在轮询我的服务器时打开一个进度对话框 该类是一个 ActivityGroup 因为它嵌套在选项卡栏中 为了将视图保持在框架内 需要 ActivityGroup 这是我的 ActivityGroup 类的声明 public class
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 如何在片段中实现 onBackPressed() 和意图?

    我知道 onBackPressed 是活动中的一种方法 但是 我想在片段中使用该功能 以便当按下后退按钮时 它会通过 Intent 重定向到另一个活动 有什么办法解决这个问题吗 public class News Events fragme

随机推荐