57

I need to share a single database between 2 apps. I know that the database will be created on /data/data/MY_PACKAGE/databases/ . Since the packages names are different is it possible to define the path to one package name when I create the database on either app? Thanks.

bond
  • 573
  • 1
  • 6
  • 5
  • 1
    http://groups.google.com/group/android-developers/browse_thread/thread/ba56064a2e6b33f4 this thread is about something similar; see if it helps – Kevin Qiu Aug 13 '11 at 22:58

3 Answers3

87

UPDATE: The method described below relies on android:sharedUserId, deprecated as of API level 29 (Android 10).

You certainly can share a single database between 2 apps.

In order to share data between apps (provided they are issued by the same publisher) you will need to specify a shared user id in the AndroidManifest.xml of both apps.

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

(It's undocumented, but the shared user id needs to be a string with at least one dot separator)

The rest is easy, and you don't need to mess around with the database path. Just use the same DBAdapter in both apps. In the app that hosts the database, call the DBAdapter with the native context.

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

In the second app, access the database with the context of the database hosting app.
First, define the shared context:

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;
        }   

Then open the DBAdapter with the shared context:

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

As a final note, if your database exists previous to setting the shared user id in the manifest, you will need to uninstall/reinstall the apps on a physical device, lest you will lock yourself out of your database (sqlite error 14). The emulator, on the other hand, might prove to be more forgiving. Bottom line, if your apps are published on the Android market, setting a shared user id in an afterthought will not work.

Hope this helps.

Daniel Szmulewicz
  • 3,971
  • 2
  • 25
  • 26
  • 5
    This was awesome help, but still leaves me with an issue - namely, how to prevent losing the db when the "first" app is uninstalled. Please see [link](http://stackoverflow.com/questions/14049095/host-database-with-do-nothing-app-so-lite-and-pro-can-access). – Peri Hartman Dec 27 '12 at 03:54
  • 3
    True, not the "official" way. Android documentation recommends Content Providers to share data between apps, I think. This is more like a hack (a handy one). – Daniel Szmulewicz Jun 20 '13 at 15:50
  • I don't understand what is DbAdapter or PerformerDbAdapter, i don't see such classes in android API. Please clarify – ultraon Jul 14 '15 at 14:50
  • DbAdapter is not part of the API, but is a well known pattern in the Android world, at least it was when the post above was written. Here is the full rundown. https://lecturesnippets.com/android-sqlite-dbadapter-class/ – Daniel Szmulewicz Jul 15 '15 at 16:20
  • What happens if both applications accessing the database simultaneously with transaction? In my tests occurs the error "database is locked". – Ismael Jan 28 '16 at 10:38
  • Don't use this hack if your database will be accessed by more than one client at the time. – Daniel Szmulewicz Jan 28 '16 at 16:05
  • Used to be a good option... sharedUserId is now deprecated as of API 29 – DennisWelu Jan 07 '21 at 20:09
6

The database path is private for each application and as far as i know it's not possible to access it directly across applications.

However one approach is that one application makes it's database accessible to the other one using a ContentProvider. Check out if that works for you.

Content providers store and retrieve data and make it accessible to all applications. They're the only way to share data across applications; there's no common storage area that all Android packages can access.

mibollma
  • 14,959
  • 6
  • 52
  • 69
1

As long as you use the same certificate on both applications, your applications will run on same process and behave as being same application check this section of android documentation http://developer.android.com/tools/publishing/app-signing.html#strategies

Charleston
  • 1,539
  • 18
  • 10
  • Sharing a DB is all good until you run into conflicts, eventually I had to scrap this and go with the better design of Database Providers. Make one app create the Provider and then both apps can send requests to the same provider. Now you have a governing class that can dictate when the database is locked or not. – JPM Jun 02 '14 at 14:37