According to various answers here and in the web extending Application and it\'s inherited method getDatabasePath() would allow to set the database storage path from the standar
Well, i guess you cannot do that. If anyone knows a way, please tell us how.
So when you are calling
mySqliteOpenHelper.getReadableDatabase();
It should all be ok as if we look at the implementation we see that:
String path = mContext.getDatabasePath(mName).getPath();
All good. But if we take a look few lines up:
return getWritableDatabase();
So it is actually calling another method, and if it fails, only then it procedes to use getDatabasePath().
If wee look at the implementation of getWritableDatabase - we can clearly see that it does not use getDatabasePath but instead:
db = mContext.openOrCreateDatabase(mName, 0, mFactory);
This brings us to see how openOrCreateDatabase is implemented for that we'll take a look at ContextImpl.java
if (name.charAt(0) == File.separatorChar) {
String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
dir = new File(dirPath);
name = name.substring(name.lastIndexOf(File.separatorChar));
f = new File(dir, name);
} else {
dir = getDatabasesDir();
f = makeFilename(dir, name);
}
So we can see that this helper method validateFilePath returns File if it gets a full path (like /some/truly/full/path) or tries to concat getDatabasesDir() with filename. getDatabasesDir() implementation uses getDataDirFile() which is public and maybe in theory could be overwritten .. but you would have to check.
Currently i see two solutions:
1) If you don't need write access force sqlite db into readonly mode, getWritableDatabase will fail and getDatabasePath will get called
2) Pass in full path into SQLiteOpenHelper constructor, and make sure db is writable, something like:
public class MyDbOpenHelper extends SQLiteOpenHelper {
public MyDbOpenHelper(final Context context) {
super(context, Environment.getExternalStorageDirectory()
+ "/path/to/database/on/sdcard/database.sqlite", null, 1);
}
This truly makes no sense to me, but looking at android sources (at least 2.3.1) it seems this is the way it is implemented.