【问题标题】:Write a private access file to another app's files directory将私有访问文件写入另一个应用程序的文件目录
【发布时间】:2010-11-30 21:15:44
【问题描述】:

这两个应用具有相同的 sharedUserId。当我在 app1 中使用此代码时

context.openFileOutput("/data/data/org.me.app2/files/shared-data.dat", MODE_PRIVATE)

我收到一个异常,告诉我该文件包含路径分隔符。

我正在尝试将 app1 中的文件写入 app2 的存储空间。 (我当然需要先确保app2的文件目录存在)

理想情况下,我会写入特定于用户的目录而不是特定于应用程序的目录,但我不知道是否可以这样做

【问题讨论】:

    标签: android file shared


    【解决方案1】:

    首先,切勿使用像/data/data 这样的内部存储的完整路径。让操作系统为您提供路径(例如,通过Context.getFilesDir()Environment.getExternalStorageState())。不要假设数据在哪里。

    其次 - 你已经这样做了!与File 不同,Context.openFileOutput 已经将/data/data/[package] 添加到您的路径中,因此您无需指定。只需指定文件名。

    如果您真的觉得它安全且必要,并且如果两个应用程序在清单中使用 android:sharedUserId 共享相同的用户 ID,您可以使用 Context.createPackageContext() 获取另一个应用程序的上下文并使用 CONTEXT_RESTRICTED,然后使用仅包含文件名的 openFileOutput。

    【讨论】:

    • 但是我怎么说app1应该写一个文件到app2呢?
    • 通常不鼓励这样做。您永远不应该写入另一个应用程序的私人存储空间! MODE_PRIVATE 特别不会对你有多大好处 - 数据甚至不会被其他应用程序读取!如果真的需要,请使用File 指定绝对路径。但听起来你一开始就使用了错误的方法。
    • 首先(我认为)MODE_PRIVATE 会起作用,因为我使用的是相同的 sharedUserId。其次,我打算将共享数据写入两个应用程序。重要的是未知应用无权访问共享数据。
    • 尝试使用Context.createPackageContent() 为其他应用创建上下文,然后仅使用文件名使用openFileOutput。没有尝试过,但由于您有一个 sharedUserId,这可能只是工作。如果它不起作用,我不会感到惊讶。
    • 如果您将有用信息从 cmets 移至答案,我会给您一个赞成票。
    【解决方案2】:

    打开所需文件的FileOutputStream,相对于此路径:

    String filePath = getPackageManager().
        getPackageInfo("com.your2ndApp.package", 0).
        applicationInfo.dataDir;
    

    【讨论】:

    • +1:我可以使用它来检查修改时间/是否存在于其他应用程序上,而无需使用绝对路径。谢谢。
    • 实际上我最终使用了createPackageContent
    【解决方案3】:

    由于这已经有几个月了,我假设您已经解决了您的问题,但无论如何我都会做出贡献。

    在应用程序之间共享数据是 ContentProviders 的用途。假设您知道如何编写 ContentProvider 并对其进行访问,则可以通过 ParcelFileDescriptor 访问文件,其中包含用于创建文件的模式的常量。

    您现在需要的是限制访问,以便不是每个人都可以通过内容提供程序读取文件,而您可以通过 android 权限来做到这一点。在您的应用程序的清单中,将托管文件和内容提供程序的应用程序,编写如下内容:

    <permission android:name="com.example.android.provider.ACCESS" android:protectionLevel="signature"/>
    

    并在两个应用程序中添加以下内容:

    <uses-permission android:name="com.example.android.provider.ACCESS" /> 
    

    通过使用 protectionLevel="signature",只有您签名的应用才能访问您的内容提供商,从而访问您的文件。

    【讨论】:

    • 非常有趣。但是,我将无法尝试它,因为该解决方案已经实施,并且任何/所有其他应用程序/升级可能会重新使用现有系统。无论如何+1。我认为您的解决方案是有效的,即使我无法对其进行测试。
    【解决方案4】:

    您不应覆盖其他应用程序文件。也就是说你有两个解决方案

    1. 使用公共外部存储(如 SD 卡)在应用之间共享文件。
    2. 如果另一个应用程序不是你的,那么你不能写入它的 /data 目录,没有 root 权限。使用 root 一切皆有可能,只是不要期望您的用户都拥有 root 访问权限。

    编辑:开发者拥有这两个应用程序

    感谢 Roman Kurik 指出这一点。指向他在SO上的帖子的链接

    来自安卓docs

    android:sharedUserId

    Linux 用户 ID 的名称,它将 与其他应用程序共享。经过 默认情况下,Android 分配每个 应用程序自己的唯一用户 ID。 但是,如果此属性设置为 两个或多个相同的值 应用程序,他们都将共享 相同的 ID — 前提是它们也是 由相同的证书签名。 具有相同用户ID的应用程序可以 访问彼此的数据,如果 需要,在同一进程中运行。

    所以这正是用户 id 在 linux 中的工作方式,本质上你是两者的所有者并且对两者都有读/写访问权限。

    【讨论】:

    • 两个应用拥有相同的sharedUserId。我控制这两个应用程序。同样重要的是,不相关的应用程序无法访问我的数据。所以我认为这两个选项中的任何一个都不会起作用......但是关于根的那是什么。你是说我可以以 root 身份运行我的应用程序吗?
    • 大多数手机都可以获得root权限,这就是安装自定义rom的方式。从那里应用程序可以通过“超级用户”应用程序请求 root。但既然你控制了这两个应该有一个更简单的解决方案,我会尽快回复你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2015-11-09
    • 1970-01-01
    • 2014-11-10
    • 2019-01-28
    • 1970-01-01
    • 2011-12-10
    相关资源
    最近更新 更多