I’m just really new to Android programming in general and by no means a professional so I hope you can help me.
I was able to encrypt and export database after reading the documentation. However, I am unsuccessful in doing the following:
- Re-opening the database after exporting a copy of it
- Loading a saved copy
This is how I built the database:
public static SampleDatabase sampleDatabase; public static synchronized SampleDatabase getInstance(Context context) { if (sampleDatabase == null) { final byte[] passphrase = SQLiteDatabase.getBytes("userEnteredPassphrase".toCharArray()); final SupportFactory factory = new SupportFactory(passphrase, null, false); sampleDatabase = Room.databaseBuilder(context.getApplicationContext(), SampleDatabase.class, "sample_database.db") .openHelperFactory(factory) .build(); } return sampleDatabase; }
In my ActivityMain, I implemented the following:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);// import android.database.sqlite.* has been replaced by net.sqlcipher.database.* SQLiteDatabase.loadLibs(this); // other lines such as initializations of views, etc.
}
This is how I implemented an export / saving of the encrypted database:
private void copyDatabase() {
System.out.println("is db instance open? " + SampleDatabase.getInstance(getApplicationContext()).isOpen());
// at this point, this returns: is db instance open? true
SampleDatabase.getInstance(getApplicationContext()).close();
File dbfile = getDatabasePath("sample_database.db");
File sdir = new File(getFilesDir(),"dbsavefolder");
String sfpath = sdir.getPath() + File.separator + "sample_database.db";
if (!sdir.exists()) {
sdir.mkdirs();
}
File savefile = new File(sfpath);
try {
savefile.createNewFile();
int buffersize = 8 * 1024;
byte[] buffer = new byte[buffersize];
int bytes_read = buffersize;
OutputStream savedb = new FileOutputStream(sfpath);
InputStream indb = new FileInputStream(dbfile);
while ((bytes_read = indb.read(buffer,0,buffersize)) > 0) {
savedb.write(buffer,0,bytes_read);
}
savedb.flush();
indb.close();
savedb.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("is db instance open? " + SampleDatabase.getInstance(getApplicationContext()).isOpen());
// now this returns: is db instance open? false
SQLiteDatabase.openOrCreateDatabase(dbfile, "userEnteredPassphrase", null);
System.out.println("is db instance open? " + SampleDatabase.getInstance(getApplicationContext()).isOpen());
// this still returns: is db instance open? false
}
I thought that if I implemented
SQLiteDatabase.openOrCreateDatabase(dbfile, “userEnteredPassphrase”, null);
The expression
SampleDatabase.getInstance(getApplicationContext()).isOpen())
will return true. But it still returned false. Why is this the case? Is there a mistake in my implementation/use of SQLCipher?
Lastly, I implemented the loading of a database file by doing something like this:
private void loadDatabase() {
SampleDatabase.getInstance(getApplicationContext()).close();
try {
// dGolez 2021-02-21-1407 todo this file is encrypted so somehow the contents must also be passed after decrytion
copy(new File(getFilesDir(),"dbsavefolder/sample_database.db"), this.getDatabasePath("sample_database.db"));
} catch (IOException e) {
e.printStackTrace();
}
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(i);
System.exit(0);
}
My intention in the above method is to replace the prior database located in the main database location / getDatabasePath(), from the one saved using getFilesDir(),“dbsavefolder/sample_database.db”.
How do I proceed to do it?
Thank you! This is a great tool for someone like me who just learned Android programming a few months ago.