Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to put existing database in the .apk file?

I have prebuild database of mostly string objects. I want to know how to put in my apk file so the database will be already created when the user installs the database.

like image 635
ilija139 Avatar asked Oct 26 '10 10:10

ilija139


People also ask

Where do I put DB files on Android?

You can add your database file in assets folder. you can add your db file in the assets folder. If it solution isn't true, should describe your problem.

How do I find my APK database?

Database that is actually used is not stored in the APK. It needs to be in a writable location. Canonically it's in databases under the application's data directory e.g. /data/data/package.name/databases .

How to modify an existing APK file in Java?

In order to execute the commands described below, you need to have Java on your PATH variable of your Windows system (see [1] for an explanation). There are 3 steps that need to be followed in order to modify an existing .apk file: 1. Do the actual desired modifications inside the .apk file 2. Sign the .apk 3. Install the .apk on the device 1.

How to add existing database in app_data folder in ASP NET?

How to add existing database in app_data folder in asp.net? just cope and paste your_database.mdf file in app_data folder.. Please Sign up or sign in to vote.

How do I install an APK file on my Device?

2. Sign the .apk 3. Install the .apk on the device 1. Change the resource in the .apk Open the .apk file with WinRAR (if that doesn’t work, rename the file extension .apk to .zip)

Is it possible to bundle a static database in an APK?

I think it's the best approach, however your data will be there twice in the apk and the db, using some more storage space. Show activity on this post. I've just started developing for Android, and was surprised to discover that bundling a static database is not easy to do.


3 Answers

I found a good example of this: Using your own SQLite database in Android applications

Basically, you export the created database as an sql-file and store it in the assets-folder. On the first program start, you import the data of the file into your final database.

I think it's the best approach, however your data will be there twice in the apk and the db, using some more storage space.

like image 50
msal Avatar answered Oct 18 '22 00:10

msal


I've just started developing for Android, and was surprised to discover that bundling a static database is not easy to do. So I did the only reasonable thing: created a library which does just that. Example usage:

import android.database.sqlite.SQLiteDatabase;
import kiwidrew.staticdb.StaticDatabase;

public class BlahBlah extends Activity {
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    SQLiteDatabase db = StaticDatabase.openDatabase(this, "assets/foobar.db");
    // Do normal database stuff with 'db'...
  }
}

You get back a standard SQLiteDatabase object, with the only restriction being that it doesn't support writing. (Obviously!)

Note that this will fail unless the database is stored in your .apk without compression. Add the sqlite database using the aapt -0 command or modify your build.xml to pass the <nocompress extension="db" /> flag to the <aapt> tag...

Get the code at http://bitbucket.org/kiwidrew/android-staticdb.

Note: I've literally just finished writing this, and have only done very basic testing so far. Bug reports would be appreciated!

like image 8
kiwidrew Avatar answered Oct 18 '22 01:10

kiwidrew


There are no any simple way to read database from assets directly. You should copy your database from assets to data folder in the first run, then when every time your app starts up, you should check database in the data folder and copy it again if the database does not exist.

These steps help you:

1) Execute these commands on your database, if android_metadata table does not exist in your database, android could not open your database.:

CREATE TABLE android_metadata(locale TEXT DEFAULT 'en_US')
INSERT INTO android_metadata VALUES('en_US')

2) Chunk your database because android does not support reading a file that more than 1 MB size from assets.

This python code chunks your database:

def chunk_file(file_name):
    input_file = open(file_name, "rb")

    chunk_counter = 0;
    while True:
        chunk = input_file.read(512 * 1024) # 512 KB
        if chunk:
            output_file_name = file_name + "." + str(chunk_counter).zfill(4)

            output_file = open(output_file_name, "wb")
            output_file.write(chunk)
            output_file.close()

            chunk_counter += 1
        else:
            break

    input_file.close()
    return

# Input: database.db
# Output: database.db.0000, database.db.0001, database.db.0002, ...
chunk_file("database.db")

Then put database.db.0000, database.db.0001, database.db.0002, ... in the assets folder.

3) Check database exists in the data folder when app starts up.

public static boolean databaseExists() {

    boolean result = false;

    SQLiteDatabase checkDB = null;

    try {
        checkDB = SQLiteDatabase.openDatabase(
                getApplicationContext().getFilesDir().getPath() + "/database.db",
                null, SQLiteDatabase.OPEN_READONLY);
        result = true;
    } catch (SQLiteException exception) {
        result = false;
    }

    if (checkDB != null) {

        checkDB.close();

    }

    return result;
}

4) If database does not exist in data folder, copy database from assets to data folder.

public static void copyDatabase() throws IOException {
    AssetManager assets = getApplicationContext().getAssets();

    // database.db.0000, database.db.0001, database.db.0002, ... --> databaseChunks.
    String[] databaseChunks = assets.list("");
    Arrays.sort(databaseChunks);

    OutputStream databaseStream = new FileOutputStream(
            getApplicationContext().getFilesDir().getPath() + "/database.db");

    for (int i = 0; i < databaseChunks.length; i++) {
        String databaseChunkName = databaseChunks[i];

        InputStream chunkStream = assets.open(databaseChunkName);

        int length;
        byte[] buffer = new byte[1024];
        while ((length = chunkStream.read(buffer)) > 0) {
            databaseStream.write(buffer, 0, length);
        }

        chunkStream.close();
    }

    databaseStream.close();

    return;
}

5) You can connect to the database now:

SQLiteDatabase database = SQLiteDatabase.openDatabase(
            getApplicationContext().getFilesDir().getPath() + "/database.db",
            null, SQLiteDatabase.OPEN_READONLY);
// ...
database.close();
like image 1
Amir Saniyan Avatar answered Oct 18 '22 02:10

Amir Saniyan