两个安卓应用如何共享SQLite数据库?

57

我需要在两个应用程序之间共享一个数据库。我知道数据库将在 /data/data/MY_PACKAGE/databases/ 上创建。由于包名不同,所以是否可以在创建数据库时为其中一个应用程序定义路径?

谢谢。

1
这个线程与某些类似的内容有关;看看它是否有帮助。 - Kevin Qiu
3个回答

87

更新:下面所描述的方法依赖于android:sharedUserId,从API级别29(Android 10)开始已经被弃用。

确实可以在两个应用程序之间共享单个数据库。

为了在应用程序之间共享数据(前提是它们由同一发布者发布),您需要在两个应用程序的AndroidManifest.xml中指定一个共享用户ID。

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:sharedUserId="my.app" ... >

(这是未记录在文档中的,但共享用户ID需要是至少带有一个点分隔符的字符串)

其他部分很容易,您无需在数据库路径周围瞎折腾。只需在两个应用程序中使用相同的DBAdapter即可。在托管数据库的应用程序中,使用本地上下文调用DBAdapter。

DBadapter hostDBAdapter = new DbAdapter(getApplicationContext());
performerDBadapter.open();

在第二个应用程序中,使用数据库托管应用程序的上下文访问数据库。
首先,定义共享上下文:

Context sharedContext = null;
    try {
        sharedContext = this.createPackageContext("replace.with.host.package.name", Context.CONTEXT_INCLUDE_CODE);
        if (sharedContext == null) {
            return;
        }
    } catch (Exception e) {
        String error = e.getMessage(); 
        return;
        }   

然后使用共享上下文打开DBAdapter:

DbAdapter sharedDBadapter = new PerformerDbAdapter(sharedContext);
sharedDBadapter.open();

最后提醒一点,如果你在清单文件里设置共享用户ID之前已经存在数据库,那么你需要在物理设备上卸载/重新安装应用程序,否则你将被锁定在你的数据库中(sqlite错误14)。然而,模拟器可能会更加宽容。总之,如果你的应用程序已发布到Android市场,事后设置共享用户ID是不起作用的。

希望这可以帮到你。


5
这是非常有帮助的,但仍然让我有一个问题 - 即如何防止在卸载"第一"应用程序时丢失数据库。请参见链接 - Peri Hartman
3
没错,这不是“官方”的方式。Android文档推荐使用内容提供者在应用之间共享数据。我认为这更像是一种技巧(一个很方便的技巧)。 - Daniel Szmulewicz
我不明白什么是DbAdapter或PerformerDbAdapter,在Android API中我没有看到这样的类。请澄清一下。 - ultraon
如果两个应用程序同时使用事务访问数据库会发生什么?在我的测试中会出现错误“数据库被锁定”。 - Ismael
如果你的数据库将被多个客户端同时访问,请不要使用此方法。 - Daniel Szmulewicz
显示剩余2条评论

6

每个应用程序的数据库路径都是私有的,据我所知,不可能直接跨应用程序访问它。

然而,一种方法是,一个应用程序使用 ContentProvider 使其数据库对另一个应用程序可访问。请查看这是否适用于您。

内容提供程序存储和检索数据,并使其可供所有应用程序访问。它们是在应用程序之间共享数据的唯一方式;没有所有Android包都可以访问的公共存储区域。


1

共享数据库在没有冲突的情况下是很好的,但最终我不得不放弃这个方案,采用更好的数据库提供者设计。让一个应用程序创建提供者,然后两个应用程序都可以向同一个提供者发送请求。现在你有了一个管理类,可以决定何时锁定或解锁数据库。 - JPM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接