Embed a database in the .apk of a distributed application [Android]
Asked Answered
A

2

6

My question is I think quite simple but I don't think the answer will be... I have quite a lot of content to have in my application to make it run properly, and I'm thinking of putting all of it in a database, and distribute it in an embeded database with the application in the market. The only trouble is that I have no idea of how to do that. I know that I can extract a file .db from Eclipse DDMS with the content of my database, and I suppose I need to put it in the asset folder of my application, but then how to make the application use it to regenerate the application database? If you have any link to some code or help, that would be great. Thanks

Acinaciform answered 10/6, 2010 at 9:4 Comment(0)
Y
12

Well to achieve what you're asking, you could put the .db file in your assets/ directory and copy it into place the first time you start your app.....

final String DB_DESTINATION = "/data/data/YOUR_PACKAGE_NAME/databases/MyDatabaseFile.db";

// Check if the database exists before copying
boolean initialiseDatabase = (new File(DB_DESTINATION)).exists();
if (initialiseDatabase == false) {

    // Open the .db file in your assets directory
    InputStream is = getContext().getAssets().open("MyDatabaseFile.db");

    // Copy the database into the destination
    OutputStream os = new FileOutputStream(DB_DESTINATION);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = is.read(buffer)) > 0){
        os.write(buffer, 0, length);
    }
    os.flush();

    os.close();
    is.close();
}

Where "initialiseDatabase" is some flag indicating if the app has been launched for the first time.

Although, if you are looking at storing a lot of data, as you mentioned: I strongly recommend you avoid bloating the APK file with it, and use the Internet connection to download the database records (from a hosted server) after the app has been launched. This way you can show a progress bar indicating to the user why they are waiting a long time to start using the app. Making the APK especially large usually deters people from installing it in the first place.

Yarmouth answered 10/6, 2010 at 9:35 Comment(7)
Well, I was using a progress bar before, but as I'm downloading lots of pictures, and parsing several XML, it takes quite a lot of time, especially when you use the 3G network instead of wifiAcinaciform
wouldn't it be easier to just check if the database already exist instead of using the boolean? How do I keep track of the boolean when the application is shut down? entry in the DB?Acinaciform
That is exactly what the boolean represents, I left that as an implementation exercise. I've updated the example code with how you might go about this.Yarmouth
Using the "bundle in APK" approach instead of downloading the data on launch isn't wrong, just be wary that if you exceed 5-10MB there is a good chance people will avoid installing your app. In-phone storage is simply too valuable on existing Android phones.Yarmouth
no no, I'm just loading 1.8Mo, however, i get an error about asset max size... telling me that my 1.8Mo is more than the allowed 1Mo...Acinaciform
found the solution of the size issue : code.google.com/p/android/issues/detail?id=4015 It can appear a weird way of doing so, but it's working... I tried several extension, like .txt .sql but only .mp3 workedAcinaciform
NEVER HARDCODE PATHS, particularly since the "destination" path used here is wrong for secondary accounts (e.g., Android 4.2+ tablets) and possibly other scenarios. The best answer for packaging a database with an app is to use SQLiteAssetHelper. If you really want to do it yourself, please use getDatabasePath() to find out the proper spot to copy the database to, rather than hardcoding a path.Cyclohexane
S
1

You can implement middle-of-the-road solution: Use approach above, but instead of distributing db file put it on server somewhere. In my experience getting files is only 10% of processing time, rest of it is parsing and serializing images to db

Stereograph answered 29/7, 2010 at 4:22 Comment(2)
Actually my purpose was to avoid putting it on a server and force a download directly after the installation of the application...Acinaciform
I understand. I was considering it for my app but then I looked at db size and its another +350K. People got touchy-feely about that, yet if you have decent connection it will definitely be faster than piecemeal downloading with subsequent processingStereograph

© 2022 - 2024 — McMap. All rights reserved.