How do i import a sqlite db file in Android? - android

In my application I can export the database db to /Android/data.... , now i want to reverse it, i want to Import it.
public boolean importDatabase() throws IOException {
close();
// Close the SQLiteOpenHelper so it will commit the created empty
// database to internal storage.
File newDb = new File(Environment.getExternalStorageDirectory(), "/Android/data/com.dreamhawk.ea/files/");
// File newDb = new File(dbPath);
File oldDb = new File(NotesDbAdapter.DB_FILEPATH);
if (newDb.exists()) {
Prefs.copyFile(newDb, oldDb);
// Access the copied database so SQLiteHelper will cache it and mark
// it as created.
getWritableDatabase().close();
return true;
}
return false;
}
This is what I've came up with so far. However, i get an
The method `close()` is undefined for the type Prefs
On close().
And I get
The method `getWritableDatabase()` is undefined for the type Prefs
On getWritableDatabase().close();
I am using this function in my Preference-class called "Prefs".
And i am thinking that i need to fetch some functions from my dbadapter, called NotesDbAdapter.
However, it wont work with , for example NotesDbAdapter.getWritableDatabase.close(); either.
Edit: I Put it in the NotesDbAdapter in SQLiteOpenHelper { }.
This removed all the errors...
Now to the next problem, i want to call this function, when a user presses a Custom Preference.
Preference restoreToDb = (Preference) findPreference("restoreFromSd");
restoreToDb.setOnPreferenceClickListener(new OnPreferenceClickListener() {
File dbPath = new File(Environment.getExternalStorageDirectory(), "/Android/data/com.dreamhawk.ea/files/");
// String dbPath = "/Android/data/com.dreamhawk.ea/files/";
public boolean onPreferenceClick(Preference arg0) {
//NotesDbAdapter.importDatabase(); <-- help here?
return true;
}
});
}
However, I can't seem to find a solution here.

Related

Android P - 'SQLite: No Such Table Error' after copying database from assets

I have a database saved in my apps assets folder and I copy the database using the below code when the app first opens.
inputStream = mContext.getAssets().open(Utils.getDatabaseName());
if(inputStream != null) {
int mFileLength = inputStream.available();
String filePath = mContext.getDatabasePath(Utils.getDatabaseName()).getAbsolutePath();
// Save the downloaded file
output = new FileOutputStream(filePath);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = inputStream.read(data)) != -1) {
total += count;
if(mFileLength != -1) {
// Publish the progress
publishProgress((int) (total * 100 / mFileLength));
}
output.write(data, 0, count);
}
return true;
}
The above code runs without problem but when you try to query the database you get an SQLite: No such table exception.
This issue only occurs in Android P, all earlier versions of Android work correctly.
Is this a known issue with Android P or has something changed?
Was having a similar issue, and solved this adding this to my SQLiteOpenHelper
#Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
db.disableWriteAheadLogging();
}
Apparently Android P sets the PRAGMA Log thing different. Still no idea if will have side effects, but seems to be working!
My issues with Android P got solved by adding
'this.close()' after this.getReadableDatabase() in createDataBase() method as below.
private void createDataBase() throws IOException {
this.getReadableDatabase();
this.close();
try {
copyDataBase();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
This issue seems to lead to a crash much more often on Android P than on previous versions, but it's not a bug on Android P itself.
The problem is that your line where you assign the value to your String filePath opens a connection to the database that remains open when you copy the file from assets.
To fix the problem, replace the line
String filePath = mContext.getDatabasePath(Utils.getDatabaseName()).getAbsolutePath();
with code to get the file path value and then close the database:
MySQLiteOpenHelper helper = new MySQLiteOpenHelper();
SQLiteDatabase database = helper.getReadableDatabase();
String filePath = database.getPath();
database.close();
And also add an inner helper class:
class MySQLiteOpenHelper extends SQLiteOpenHelper {
MySQLiteOpenHelper(Context context, String databaseName) {
super(context, databaseName, null, 2);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
I ran into a similar issue. I was copying a database but not from an asset. What I found is that the problem had nothing to do with my database file copying code at all. Nor did it have to do with files left open, not closed, flushing or syncing. My code typically overwrites an existing unopen database. What appears to be new/diffferent with Android Pie and different from previous releases of Android, is that when Android Pie creates a SQLite database, it sets journal_mode to WAL (write-ahead logging), by default. I've never used WAL mode and the SQLite docs say that journal_mode should be DELETE by default. The problem is if I overwrite an existing database file, let's call it my.db, the write-ahead log, my.db-wal, still exists and effectively "overrides" what's in the newly copied my.db file. When I opened my database, the sqlite_master table typically only contained a row for android_metadata. All the tables I was expecting were missing. My solution is to simply set journal_mode back to DELETE after opening the database, especially when creating a new database with Android Pie.
PRAGMA journal_mode=DELETE;
Perhaps WAL is better and there's probably some way to close the database so that the write-ahead log doesn't get in the way but I don't really need WAL and haven't needed it for all previous versions of Android.
Unfortunately, the accepted answer just "happens to work" in very concrete cases, but it doesn't give a consistently working advice to avoid such an error in Android 9.
Here it is:
Have single instance of SQLiteOpenHelper class in your application to access your database.
If you need to rewrite / copy the database, close the database (and close all connections to this database) using SQLiteOpenHelper.close() method of this instance AND don't use this SQLiteOpenHelper instance anymore.
After calling close(), not only all connections to the database are closed, but additional database log files are flushed to the main .sqlite file and deleted. So you have one database.sqlite file only, ready to be rewritten or copied.
After copying / rewriting etc. create a new singleton of the SQLiteOpenHelper, which getWritableDatabase() method will return new instance of the SQLite database! And use it till next time you will need your database to be copied / rewritten...
This answer helped me to figure that out: https://stackoverflow.com/a/35648781/297710
I had this problem in Android 9 in my AndStatus application https://github.com/andstatus/andstatus which has quite large suite of automated tests that consistently reproduced "SQLiteException: no such table" in Android 9 emulator before this commit:
https://github.com/andstatus/andstatus/commit/1e3ca0eee8c9fbb8f6326b72dc4c393143a70538 So if you're really curious, you can run All tests before and after this commit to see a difference.
Solution without disabling the WAL
Android 9 introduces a special mode of SQLiteDatabase called Compatibility WAL (write-ahead loggin) that allows a database to use "journal_mode=WAL" while preserving the behavior of keeping a maximum of one connection per database.
In Detail here:
https://source.android.com/devices/tech/perf/compatibility-wal
The SQLite WAL mode is explained in detail here:
https://www.sqlite.org/wal.html
As of the official docs the WAL mode adds a second database file called databasename and "-wal". So if your database is named "data.db" it is called "data-wal.db" in the same directory.
The solution is now to save and restore BOTH files (data.db and data-wal.db) on Android 9.
Afterwards it is working as in earlier versions.
I had the same thing I had an application in version 4 of android, and when updating my mobile that has android 9, then I was 2 days trying to find the error, thanks for the comments in my case I just had to add this.close ();
private void createDataBase () throws IOException {
     this.getReadableDatabase ();
     this.close ();
     try {
         copyDataBase ();
     } catch (IOException e) {
         throw new RuntimeException (e);
     }
}
ready running for all versions !!
First, thank you for posting this question. I had the same thing happen. All was working well, but then when testing against Android P Preview I was getting crashes. Here's the bug that I found for this code:
private void copyDatabase(File dbFile, String db_name) throws IOException{
InputStream is = null;
OutputStream os = null;
SQLiteDatabase db = context.openOrCreateDatabase(db_name, Context.MODE_PRIVATE, null);
db.close();
try {
is = context.getAssets().open(db_name);
os = new FileOutputStream(dbFile);
byte[] buffer = new byte[1024];
while (is.read(buffer) > 0) {
os.write(buffer);
}
} catch (IOException e) {
e.printStackTrace();
throw(e);
} finally {
try {
if (os != null) os.close();
if (is != null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The issue I ran into was this code works just fine BUT in SDK 28+ openOrCreateDatabase no longer automatically creates the android_metadata table for you. So if you do a query of "select * from TABLE" it will not find that TABLE because the query starts to look after the "first" table which should be the metadata table. I fixed this by manually adding the android_metadata table and all was well. Hope someone else finds this useful. It took forever to figure out because specific queries still worked fine.
Similar issue, only Android P device affected. All previous versions no problems.
Turned off auto restore on Android 9 devices.
We did this to troubleshoot. Would not recommend for production cases.
Auto restore was placing a copy of the database file in the data directory before the copy database function is called in the database helper. Therefore the a file.exists() returned true.
The database that was backed up from the development device was missing the table. Therefore "no table found" was in fact correct.
Here's the perfect solution for this problem:
Just override this method in your SQLiteOpenHelper class:
#Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
db.disableWriteAheadLogging();
}
}
It seems that you don't close the output stream. While it probably does not explain why the db is not really created (unless Android P added a multi MB buffer) it is a good practice to use a try-with-resource, something like :
// garantees that the data are flushed and the resources freed
try (FileOutputStream output = new FileOutputStream(filePath)) {
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = inputStream.read(data)) != -1) {
total += count;
if (mFileLength != -1) {
// Publish the progress
publishProgress((int) (total * 100 / mFileLength));
}
output.write(data, 0, count);
}
// maybe a bit overkill
output.getFD().sync();
}
In version P, the major change is WAL (Write Ahead Log). The following two steps are required.
Disable the same by the following line in config.xml in the values folder under resources.
false
Make the following change in the DBAdapter class in createDatabase method. Otherwise phones with earlier Android versions crash.
private void createDataBase() throws IOException {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.P) {
this.getWritableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
The issue occurring in Android Pie,
Solution is:
SQLiteDatabase db = this.getReadableDatabase();
if (db != null && db.isOpen())
db.close();
copyDataBase();
Simplest answer to use following line for Database file path in Android PIE and above:
DB_NAME="xyz.db";
DB_Path = "/data/data/" + BuildConfig.APPLICATION_ID + "/databases/"+DB_NAME;

How to change the default database file location of Room DataBase?

I am using RoomDB in my app. able to perform crud operations.
Actually i want to see the db file.
getDatabasePath("user.db").getAbsolutePath();
above code is giving me the directory where the db file is saves
directory is like this
/data/data/com.example.manvish.roomdb/databases/user.db
but still i am unable to access the data directory even using sudo from command prompt.
now i want to change the DB file location to some other folders in internal memory or SD card. how can i do this?
Java solution:
Grant permissions in Manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Create db (Here SofDatabase is a singleton class)
private static final String DB_NAME = "stack_overflow_db";
private static final String DB_PATH = String.format("%s/%s",
Environment.getExternalStorageDirectory().getAbsolutePath(), DB_NAME);
public static synchronized SofDatabase getInstance(Context aContext) {
if (sInstance == null) {
sInstance = Room.databaseBuilder(aContext, SofDatabase.class, DB_PATH)
.fallbackToDestructiveMigration()
.addCallback(roomCallback).build(); //adding callback from Room
}
return sInstance;
}
Callback
/**
* Get Notified once db is created
*/
private static final RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
#Override
public void onCreate(#NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
Log.i("SOF", db.getPath()); //which prints out --> I/SOF: /storage/emulated/0/stack_overflow_db
// add some jobs once db is created
}
};
To change the db location just put the path when you build the Room database, an example for a db in your folder, in the internal storage:
fun getDatabase(context: Context, scope: CoroutineScope): TestDatabase {
return INSTANCE ?: synchronized(this) {
val instance =
Room.databaseBuilder(
context.applicationContext,
TestDatabase::class.java,
Environment.getExternalStorageDirectory().absolutePath + "/yourFolder/yourdb"
).build()
INSTANCE = instance
return instance
}
}
This is a Kotlin example, if you need it in Java, just let me know.
Regards.
So guys I'm posting my solution because I got stuck for several hours on this problem and I was almost convinced that we couldn't use a database that is located elsewhere than the "/data/data" internal directory of the application with Room
The solution is however very simple. with the following code we have the IllegalArgumentException exception: "File ... contains a path separator"
private fun buildDatabase(context: Context) : RMSRoomDatabase {
val packageName: String = context.getApplicationInfo().packageName
var path = "sdcard/Android/data/$packageName/files/rms_database.sqlite"
var builder = Room.databaseBuilder(
context,
RMSRoomDatabase::class.java,
path
)
return builder.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build()
}
But by simply changing the path with an slash as the first character, everything works correctly!
var path = "/sdcard/Android/data/$packageName/files/rms_database.sqlite"
Not sure if this is what you are looking for but in my case just like #M.Yogeshwaran I needed to be able to setup an initial state of the database and work from there so I ended up doing this:
/**
* #param context
*/
public DatabaseService(Context context) {
File dst = context.getDatabasePath(DB_NAME);
dst.delete();
File src = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()+"/database.db");
try {
copy(src,dst);
} catch (IOException e) {
e.printStackTrace();
}
// Init the database singleton
db = Room.databaseBuilder(context, CrediforceDatabase.class, Constants.DB_NAME).build();
}
public static void copy(File src, File dst) throws IOException {
try (InputStream in = new FileInputStream(src)) {
try (OutputStream out = new FileOutputStream(dst)) {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
}
}
To give a bit more clarity:
DB_NAME = "database.db"
For testing purposes, I have the "database.db" that I want to "import" in my downloads folder, later on I will convert this code so instead the device pulls the initial database from the server.
the dst.delete(); is just to delete the existing database file as I was testing things out (not sure if required)
This basically translates to: Start the app > Replace the database file > build the database.
Gotta be careful with the identity_hash in the room_master_table, if this is different from what's supposed to be it's not going to work.
Also, I pulled this idea from this answer:
https://stackoverflow.com/a/50383879/2150472
Hope it helps anyone!
P.S, if what you need is just to be able to see the data and perform CRUD operations you can always use this plugging: https://github.com/amitshekhariitbhu/Android-Debug-Database

Android: remove data from database

I am using this code (android-sqlite-asset-helper) to load a database from a file place in the asset folder. This works great.
However, the processing of refreshing/upgrading the database is not simple, and I am wondering if there is a simple way to manually remove all data from the databases in the app; in order to load a new database from the asset file.
You can use simple copy file to override data in default database. Simply by overwriting default database with your new database file.
The following code work only with a file, so you need a little change here and there to make it work with asset file.
Here the method to overwrite the database file:
/**
* Copies the database file at the specified location over the current
* internal application database.
**/
public boolean importDatabase(Context context, String dbPath) throws IOException {
File OldDbFile = context.getApplicationContext().getDatabasePath(DBSchema.DATABASE_NAME);
// Close the SQLiteOpenHelper so it will commit the created empty
// database to internal storage.
close();
File newDb = new File(dbPath);
if (newDb.exists()) {
FileUtils.copyFile(new FileInputStream(newDb), new FileOutputStream(OldDbFile));
// Access the copied database so SQLiteHelper will cache it and mark
// it as created.
getWritableDatabase().close();
return true;
}
return false;
}
FileUtils class:
public class FileUtils {
/**
* Creates the specified <code>toFile</code> as a byte for byte copy of the
* <code>fromFile</code>. If <code>toFile</code> already exists, then it
* will be replaced with a copy of <code>fromFile</code>. The name and path
* of <code>toFile</code> will be that of <code>toFile</code>.<br/>
* <br/>
* <i> Note: <code>fromFile</code> and <code>toFile</code> will be closed by
* this function.</i>
*
* #param fromFile - FileInputStream for the file to copy from.
* #param toFile - FileInputStream for the file to copy to.
*/
public static void copyFile(FileInputStream fromFile, FileOutputStream toFile)
throws IOException {
FileChannel fromChannel = null;
FileChannel toChannel = null;
try {
fromChannel = fromFile.getChannel();
toChannel = toFile.getChannel();
fromChannel.transferTo(0, fromChannel.size(), toChannel);
} finally {
try {
if (fromChannel != null) {
fromChannel.close();
}
} finally {
if (toChannel != null) {
toChannel.close();
}
}
}
}
}
I really forget where I took the copyFile method :(.
There is one caveat: when user cleaning app data, the database will be back to default.
It seems to work with this in the main activity creation:
getApplicationContext().deleteDatabase("mydatabase.db");

Android: copy database from asset folder, but only get an empty file

guys, I have the problem when copying database from local assets folder to /data/data/package_name/databases directory. As I use the http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/ tutorial to do it, I can only get an empty file.
I quoted the part of copyDataBase() method and there is no difference. Every time the app start, it will create the directory and empty database. So is there any way to make the copyDataBase() work?
Thank you very much!!
Why wouldn't you copy from assets? It's perfectly normal to do so. But you can't do it in the onCreate, at that point an empty database is already created. You need to do it prior. I usually do it in an override of getWriteableDatabase, something like
public synchronized SQLiteDatabase getWritableDatabase() {
SQLiteDatabase db = null;
if (!doesDatabaseExist()) {
try {
copyDatabase();
db = super.getWritableDatabase();
} catch(Exception ex) {
Log.e("Database Log", getDatabasePath() + " failed to copy correctly. " + ex.getLocalizedMessage());
}
}
else {
db = super.getWritableDatabase();
}
return db;
}
I wouldn't copy any database form the assets-folder. If you need some standard entry's in your Database, you can add them using INSERTs in your onCreate()-method.
Update: Since this is getting down-voted for being wrong (which is kinda right) and I can't delete it, here is a little update.
I'd say it depends upon how many standard entries you want to add to your database. If it's just one or two, shipping a packed DB might not be worth it.
Anyways, some apps come with rather large databases (for example, a recipe collection). You can obviously not add all these in code.
For small test-entries, I'd still prefer simply adding them in onCreate().
For bigger databases, you should pre-populate them and ship em along with your app.
For the later to work, you'll need to copy the database file from assets/ to your app-folder. There is a nice library to handle that for you: android-sqlite-asset-helper
I don't know if it is still usefull but here is the solution for others that get here to see the awnser. The code you used, works for most phones, some older phones have different behaviour with the getReadableDatabase() function. Your problem therefore is not in the copyDataBase function but in the createDataBase function.
in createDataBase() there is the following check;
this.getReadableDatabase();
This checks if there is already a database with the provided name and if not creates an empty database such that it can be overwritten with the one in the assets folder. On newer devices this works flawlessly but there are some devices on which this doesn't work. Mainly older devices. I do not know exactly why, but it seems like the getReadableDatabase() function not only gets the database but also opens it. If you then copy the database from the assets folder over it, it still has the pointer to an empty database and you will get table does not exist errors.
So in order to make it work on all devices you should modify it to the following lines:
SQLiteDatabase db = this.getReadableDatabase();
if (db.isOpen()){
db.close();
}
Even if the database is opened in the check, it is closed thereafter and it will not give you any more trouble.
at the right above example worked for me this way:
db = super.getWritableDatabase();
db.close;
copyDatabase();
otherwise i got an IO error;
Here is the simple and convenient code which I use:
public class DataBaseImportHelper {
private DataBaseImportHelper() {}; // Avoid instantiation
/**
* Creates a empty database on the system and rewrites it with your own database.
*/
public static boolean importDataBase(Context context) {
InputStream myInput = null;
OutputStream myOutput = null;
try {
// Open local db from assets as the input stream
myInput = context.getAssets().open(DATABASE_NAME);
createEmptyDatabase(context); // See this method below
// Open the empty db as the output stream
myOutput = new FileOutputStream(getDatabaseFile(context));
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myInput.close();
myOutput.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* Check if the database already exists.
* #return true if it exists, false if it doesn't
*/
public static boolean isDatabaseExists(Context context) {
return getDatabaseFile(context).exists();
}
private static File getDatabaseFile(Context context) {
return context.getDatabasePath(DatabaseHelper.DATABASE_NAME);
}
/**
* Create an empty database into the default application database
* folder.So we are gonna be able to overwrite that database with our database
*/
private static void createEmptyDatabase(Context context) {
// use anonimous helper to create empty database
new SQLiteOpenHelper(context, DatabaseHelper.DATABASE_NAME, null, 1) {
// Methods are empty. We don`t need to override them
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
#Override
public void onCreate(SQLiteDatabase db) {
}
}.getReadableDatabase().close();
}
}
And using in code:
if(!DataBaseImportHelper.isDatabaseExists(this)){
if (!DataBaseImportHelper.importDataBase(this)){
throw new IllegalStateException("Database doesn`t exist and hasn`t been copied!");
}
}

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.
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.
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!
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();

Categories

Resources