【问题标题】:Packaging files in an android application (but not in res or assets)在 android 应用程序中打包文件(但不在 res 或 assets 中)
【发布时间】:2012-10-23 16:25:27
【问题描述】:

好的,所以我被扔进了战壕,想以最干净最体面的方式离开。

目前我有 2 个 Android 项目,我需要在一个项目中打包一个文件,并让它被另一个项目成功读取。这可能会令人困惑,所以让我解释一下。

我有 2 个 Android 项目。一个名为 Engine 的 android 库项目和应用程序本身。

引擎处理网络通信和许多其他后台任务,这些任务无头运行且不与 UI 交互。引擎可以访问主应用程序的上下文,但没有其他权限。在我开发这个引擎的过程中,我遇到了一些有趣的事情。 Https(不要逃跑)以及它在android应用程序中出现的问题。有很多关于 android 应用程序如何非常不安全并且极易受到 MITM 攻击的博客文章。这是我在这个引擎中不能忽视的一个问题,因为它是一个非常现实的威胁。

如需更多阅读,我强烈推荐 Nikolay Elenkov 的 blog,因为他解释了在 Android 上实现安全的好方法!

我离题了,因为这个问题已经解决了。我的解决方案是使用存储在 .bks 文件中的自定义密钥库。同样,您无需担心它是如何创建的或将如何创建的。真正的麻烦是,当它被打包在一个 JAR 中时,我如何读取这个文件。

对于最终版本,引擎将打包为 jar 并包含在应用程序中。 将引擎打包到 jar 中的警告是 res 文件夹中的任何内容都不会被编译并且无法读取。根据定义,无论项目是 jar 还是库项目,库项目中的任何资产都将无法访问。

回顾一下,我们有 2 个项目。一个 Packaged Jar Android 库,其中包含我们的 BKS 文件和一个需要读取它的应用程序。

如果 BKS 文件位于 assets/ 或 res/ 文件夹中,则无法恢复它。

有没有人知道如何访问这个文件?

可能的解决方案:

  • 将文件存入lib目录并读取?

  • 将 BKS 存储在远程服务器上并在启动时加载?

  • 寻找另一种处理 ssl 证书的方法(不,我不会只接受任何和所有证书!)

  • 有一种超级秘密的方法可以读取另一个文件夹中的 android 库项目中的文件,这是你如何做到的......

【问题讨论】:

    标签: android ssl https io bouncycastle


    【解决方案1】:

    回顾一下,我们有 2 个应用程序

    不,你没有。

    一个打包的 Jar Android 库,其中包含我们的 BKS 文件和一个需要读取它的应用程序。

    这是一个应用程序,而不是两个。根据您的描述,您有两个项目,但有一个应用程序

    有人知道如何访问这个文件吗?

    将文件放入应用程序的项目中,是assets/ 还是res/raw/ 由您决定。如果从源代码控制的角度来看,您希望文件驻留在库项目的存储库中,请在应用程序项目中使用符号链接或硬链接,或使用提交挂钩,或在应用程序项目的位置制作副本。

    或者,你自己和use getResourceAtStream() to read it in打包库JAR中的文件。这个我没试过,但大概可以。

    【讨论】:

    • 我的意思是在摘要中使用项目而不是应用程序这个词。更新。我遇到的主要问题是,当一个库被打包在一个 JAR 中时,Android 似乎阻止了资源的加载。但是,这是使用 R.id.whatever 之类的资源标识符。根据您的回答,我应该能够通过手动指定位置来读取文件 [InputStream i = new InputStream ....getResourceAsSteam .... ("absolute_path_to_res/raw")]。我的理解正确吗?
    • @OVERTONE:只有在安排将你的文件放入 JAR 时才有效。默认情况下,JAR 将只包含您编译的类。
    • 我就是这么做的。我更改了 build.xml 文件以使用相关文件更新打包的应用程序。然后我根据您的评论使用输入流访问编辑。
    【解决方案2】:

    我能想到的一种方法是使用内容提供者。在您拥有 BKS 文件的引擎中实现内容提供程序。不要为实现 insert()、delete() 等而烦恼。只需将这些函数与空体结合即可。使用托管游标实现您的查询功能,并使用 BKS 文件的内容填充游标。从您的应用程序查询此内容提供程序。

    我做了类似的事情来在两个应用程序之间交换偏好。

    SharedPreferences prefs = null;
       String[] columns = new String[] { "mycolumn"};
       Context otherAppsContext = null;
       try {
           otherAppsContext = mContext.createPackageContext("com.blah.blah", Context.CONTEXT_IGNORE_SECURITY);
       } catch (NameNotFoundException e) {
       }
       prefs = otherAppsContext.getSharedPreferences("com.blah.blah_preferences_public",Context.MODE_WORLD_READABLE|Context.MODE_MULTI_PROCESS);
       isConfigured = prefs.getBoolean("mycolumn", false);
       Object[]values = new Object[] {isConfigured==true?1:0};
       Log.d(TAG,"isConfigured " + isConfigured);
       MatrixCursor c = new MatrixCursor(columns);
       c.addRow(values);
       return c;
    

    【讨论】:

    • 这实际上是一个不错的思考方式,因为它是 android 应用程序中的外部存储。得到我的部分是:“使用托管游标实现您的查询功能,并使用 BKS 文件的内容填充游标。”这可能是不可能的,因为为了做到这一点,bks 文件需要在引擎启动时可以访问。请记住,由于它是无头的,因此引擎没有自己的上下文。在我尝试之前,您确定可以在没有引擎上下文的情况下在内容提供程序中访问创建 bks 文件吗?
    • 好吧,我可以读取首选项并将其存储在矩阵光标中,并且我使用了调用应用程序的上下文,你的情况也是如此,调用应用程序应该具有上下文。不是吗?
    • 调用应用程序有一个上下文并且引擎可以访问相同的上下文。你跟着?引擎没有自己的上下文,它只是使用应用程序上下文。
    • 根据您的解释,引擎将存储该文件。它需要自己的上下文来存储在内容提供程序中,并且还需要对文件有一些初始访问权限。
    猜你喜欢
    • 1970-01-01
    • 2011-09-23
    • 2012-06-24
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    相关资源
    最近更新 更多