views:

345

answers:

3

Here is some background about my app:

I am developing an Android app that will display a random quote or verse to the user. For this I am using an SQLite database. The size of the DB would be approximately 5K to 10K records, possibly increasing to upto 1M in later versions as new quotes and verses are added. Thus the user would need to update the DB as and when newer versions are of the app or DB are released.

After reading through some forums online, there seem to be two feasible ways I could provide the DB: 1. Bundle it along with the .APK file of the app, or 2. Upload it to my app's website from where users will have to download it

I want to know which method would be better (if there is yet another approach other than these, please do let me know).

After pondering this problem for some time, I have these thoughts regarding the above approaches:

Approach 1: Users will obtain the DB along with the app, and won't have to download it separately. Installation would thereby be easier. But, users will have to reinstall the app every time there is a new version of the DB. Also, if the DB is large, it will make the installable too cumbersome.

Approach 2: Users will have to download the full DB from the website (although I can provide a small, sample version of the DB via Approach 1). But, the installer will be simpler and smaller in size. Also, I would be able to provide future versions of the DB easily for those who might not want newer versions of the app.

Could you please tell me from a technical and an administrative standpoint which approach would be the better one and why?

If there is a third or fourth approach better than either of these, please let me know.

Thank you!

Andruid

A: 

It sounds like your app and your db are tightly bound -- that is, the db is useless without the database and the database is useless without the app, so I'd say go ahead and put them both in the same .apk.

That being said, if you expect the db to change very slowly over time, but the app to change quicker, and you don't want your users to have to download the db with each new app revision, then you might want to unbundle them. To make this work, you can do one of two things:

  1. Install them as separate applications, but make sure they share the same userID using the sharedUserId tag in the AndroidManifest.xml file.
  2. Install them as separate applications, and create a ContentProvider for the database. This way other apps could make use of your database as well (if that is useful).
JohnnyLambada
That's correct, the database and the app are tightly bound. And, both the app and the database will change, perhaps or perhaps not at the same time.I like the idea of having another app which implements a ContentProvider for the main app to make use of the database. Thanks.
Pankaj Godbole
So, you should accept the answer (or another one if you like it better) and perhaps hit the up-arrow of any comments you like.Cheers!
JohnnyLambada
A: 

If you are going to store the db on your website then I would recommend that you just make rpc calls to your webserver and get data that way, so the device will never have to deal with a local database. Using a cache manager to avoid multiple lookups will help as well so pages will not have to lookup data each time a page reloads. Also if you need to update the data you do not have to send out a new app every time. Using HttpClient is pretty straight forward, if you need any examples please let me know

Bob.T.Terminal
Thanks for your answer, but the idea is to use a local database only. Sorry, if I didn't say this clearly in my post. Once the user has obtained the database by whichever means, he/she will not need to go to the website again, until and unless there is a newer version of the database which the user wants. I'm not expecting to update the database that often, actually - perhaps once in 3-4 months or so.So, I suppose my question should have been whether to bundle the DB along with the .apk file, or to leave it separate (perhaps residing on the SD card).
Pankaj Godbole
+3  A: 

I built a similar app for Android which gets periodic updates with data from a government agency. It's fairly easy to build an Android compatible db off the device using perl or similar and download it to the phone from a website; and this works rather well, plus the user gets current data whenever they download the app. It's also supposed to be possible to throw the data onto the sdcard if you want to avoid using primary data storage space, which is a bigger concern for my app which has a ~6Mb database.

In order to make Android happy with the DB, I believe you have to do the following (I build my DB using perl).

$st = $db->prepare( "CREATE TABLE \"android_metadata\" (\"locale\" TEXT DEFAULT 'en_US')");
$st->execute();

$st = $db->prepare( "INSERT INTO \"android_metadata\" VALUES ('en_US')");
$st->execute();

I have an update activity which checks weather updates are available and if so presents an "update now" screen. The download process looks like this and lives in a DatabaseHelperClass.

public void downloadUpdate(final Handler handler, final UpdateActivity updateActivity) {
    URL url;
    try {
        close();

        File f = new File(getDatabasePath());
        if (f.exists()) {
            f.delete();
        }

        getReadableDatabase();
        close();

        url = new URL("http://yourserver.com/" + currentDbVersion + ".sqlite");

        URLConnection urlconn = url.openConnection();
        final int contentLength = urlconn.getContentLength();
        Log.i(TAG, String.format("Download size %d", contentLength));
        handler.post(new Runnable() {
            public void run() {
                updateActivity.setProgressMax(contentLength);
            }
        });

        InputStream is = urlconn.getInputStream();

        // Open the empty db as the output stream
        OutputStream os = new FileOutputStream(f);

        // transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024 * 1000];
        int written = 0;
        int length = 0;
        while (written < contentLength) {
            length = is.read(buffer);
            os.write(buffer, 0, length);
            written += length;
            final int currentprogress = written;
            handler.post(new Runnable() {
                public void run() {
                    Log.i(TAG, String.format("progress %d", currentprogress));
                    updateActivity.setCurrentProgress(currentprogress);
                }
            });
        }

        // Close the streams
        os.flush();
        os.close();
        is.close();

        Log.i(TAG, "Download complete");

        openDatabase();
    } catch (Exception e) {
        Log.e(TAG, "bad things", e);
    }
    handler.post(new Runnable() {
        public void run() {
            updateActivity.refreshState(true);
        }
    });
}

Also note that I keep a version number in the filename of the db files, and a pointer to the current one in a text file on the server.

Fiid
Thanks. Actually, the data will be fairly static, and the app won't have to check for updates in the data every time is it used. I'm expecting the data to change perhaps only every few months or so. If and when the user wants the new data then he/she can request it from my app's website, or by reinstalling the whole app.I guess my question would be: should I provide the database along with the app or separately on the website.
Pankaj Godbole
Can you access the DB directly if it's part of the APK? Or do you have to duplicate it out to the data directory? That might be a reason to make it a separate download.
Fiid