12

考虑以下场景。一家公司发布了许多应用程序。他们希望在所有这些应用程序之间共享一些数据。这些应用程序中的任何一个都可以创建或读取这些数据,就像一个通用数据库一样。因此公司决定创建一个用于此目的的 android 库。我搜索了几天,下面给出我的分析。

  1. SharedPreferences - 不推荐且已弃用。它也没有达到目的。所有其他应用程序都需要知道创建数据的应用程序的包名称以创建 PackageContext。在这里这是不切实际的,因为任何应用程序都可以创建/更新/读取数据,并且无法说出谁是谁。

  2. ContentProviders - 这对我不起作用。ContentProviders 的原因必须存在于每个应用程序中。一个设备中不能有 2 个同名的内容提供者。除此之外,ContentProviders 基本上意味着一个应用程序创建数据,而其他应用程序使用 Content_Uri 订阅它。

  3. 网络连接 - 我们不想在任何服务器中存储数据。

  4. 外部存储 - 这是剩下的唯一选项。我应该去这个吗?

有趣的是,数据也必须得到保护,这在任何存储选项中都不受支持。

注意:对于 iOS,我们使用 keychain 来实现相同的功能

4

3 回答 3

7

了解Android上的问题

具有讽刺意味的是,由于 iOS 上的强沙盒,只要需要共享数据的应用程序都由同一个开发人员提供,就有一种直接的方法来实现这一点(应用程序组)。可能是因为 Android 在安全性方面更加灵活,这实际上最终成为了一个更困难的问题。到目前为止,Android 团队认为不适合提供一种方便且安全的方式来专门共享此类数据,因为安全性较低的解决方法。

也就是说,有很多方法可以在不涉及云的情况下在应用程序之间共享数据。

共享首选项

原始问题指出 SharedPreferences 已被弃用。据我所知,这不是真的,但是不推荐使用 MODE_WORLD_READABLE 和 MODE_WORLD_WRITABLE 上下文,这使得这种方法在未来无法工作。不过,该模式已被弃用了一段时间 - 自 Android 4.2 (2012) 以来。当前的 Android 文档中没有任何威胁表明他们实际上正在逐步淘汰它(有时弃用只是意味着“这不是一个好主意”而不是“这将被删除”)。我怀疑在设置级别的应用程序数据共享缺乏更安全的操作系统级别的直接替代方案,这可能是过去 5 年将其保留在弃用状态的原因。

文件访问

我知道在 Android 上实现应用程序之间数据共享的最简单和最常见的方法是简单地请求设备上的文件访问,并在外部存储上为这些数据创建一个共享位置。(不要对“外部存储”的名称感到困惑——这正是 Android 指代共享数据的方式。它不一定指的是 SD 卡。)你给文件一个唯一的名字,然后你把它存储在某个地方您的应用程序知道在哪里寻找它。获得该路径的最佳方法是:Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)

明显的问题是安全性。虽然操作系统没有弃用它,但它引入了与 Android 文档列出的相同问题,作为弃用 MODE_WORLD_* 的原因 - 它本质上是不安全的,并且会在您的应用程序中打开潜在的漏洞。

  • 你把你的信息放在任何东西都可以随时访问的地方。
  • 您正在请求您的应用可能不需要的权限。
  • 您正在阅读无法验证其来源的文件。

如果您的应用程序没有处理任何敏感数据,那么这可能对您无关紧要(可能对您的用户而言)。如果您打算从这些文件中读取数据,则应确保在解析之前为该数据提供最大程度的验证。检查文件的大小,验证格式等。

创建自己的服务

您始终可以创建服务或 IntentService。(两者之间存在细微差别,但 IntentService 是 Service 的子类,它在 Worker 线程中运行,而 Service 中断主线程。IntentService 还实现了 Intent 支持,它提供了 Android 上最直接的应用程序间通信)。

该服务有自己的私有存储,它具有完全的读/写访问权限,但没有其他权限。然后,该服务提供一个接口来接收来自其他应用的 Intent,并将结果(作为 Intent)返回给这些应用。这是一种非常友好的方式来实现应用程序间数据,同时最大限度地提高数据的隐私性和安全性。如果外围应用程序主要需要从中央应用程序请求非常基本的信息,那么这是您的入门级选项。

实现广播接收器

与此类似的是 BroadcastReceiver 类。根据您打算在应用程序之间共享哪种数据,以及这些应用程序对您的特定方法的熟悉程度,这是另一种可能性。同样,您将在一个应用程序的私有存储下管理共享数据。通信是由 Intent 完成的,因此它类似于 IntentService - 除了应用程序可以通过发出系统范围的事件与 BroadcastReceiver 进行通信(也就是说,它们不需要显式地与您的应用程序或服务通信 - 他们大喊大叫世界的一条信息,并期待一个答案。)

创建内容提供者

原始帖子似乎误解了 ContentProvider 是什么以及它是如何工作的。你必须像考虑云解决方案一样考虑这种类型的项目——即使它在你的设备上是本地的。每个应用程序都不需要 ContentProvider - 它们都需要与 ContentProvider 通信,而 ContentProvider 维护、更新和返回数据。

对于这个特定的用例,这可能是最“Android-y”的解决方案,并提供了最大的可扩展性。您实现了一个独立的进程来处理数据存储并响应其他应用程序。然而,它是一种更先进的解决方案——因此可能更具挑战性。如果你需要一个真正的数据库服务,而不是一个相当简单的请求/响应类型的服务,ContentProvider 似乎是最好的选择。

于 2017-02-26T07:11:00.127 回答
2

似乎您需要的是共享用户 id

如果它们都由相同的签名签名,它允许应用程序沙箱在多个 android 应用程序之间共享。

但是,当心陷阱

于 2013-10-30T18:57:35.260 回答
0

是的。可能对所有应用程序在外部存储中使用相同的路径是最好的方法。代码的公共部分可用于了解数据库是否存在,从而打开或创建新的。为了安全起见,我建议在连接数据库时始终使用“用户”和“密码”,但如果您认为这还不够,我建议您查看: http://www.hwaci.com/sw/sqlite/see。 html

于 2013-10-30T19:40:24.280 回答