In my app, I use...
myFilesDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/Android/data/" + packageName + "/files");
myFilesDir.mkdirs();
This is fine and the resulting path is...
/mnt/sdcard/Android/data/com.mycompany.myApp/files
I need a SQLite DB which I want to store on the SD card so I extend SQLiteOpenHelper as follows...
public class myDbHelper extends SQLiteOpenHelper {
public myDbHelper(Context context, String name, CursorFactory factory, int version) {
// NOTE I prefix the full path of my files directory to 'name'
super(context, myFilesDir + "/" + name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
// Create tables and populate with default data...
}
}
So far so good - the first time I call getReadableDatabase()
or getWriteableDatabase()
the empty DB is created on the SD card and onCreate()
populates it.
So here's the problem - the app is in beta testing with maybe 5 or 6 people and, like me, they're running Android v2.2 and everything works fine. I have one tester, however, running v2.1 and when myDbHelper
tries to create the DB on first use, it crashes with the following...
E/AndroidRuntime( 3941): Caused by: java.lang.IllegalArgumentException: File /nand/Android/data/com.mycompany.myApp/files/myApp-DB.db3 contains a path separator
E/AndroidRuntime( 3941): at android.app.ApplicationContext.makeFilename(ApplicationContext.java:1445)
E/AndroidRuntime( 3941): at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:473)
E/AndroidRuntime( 3941): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)
E/AndroidRuntime( 3941): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
E/AndroidRuntime( 3941): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158)
The path for the files directory is an odd one ("/nand") as it's internal memory although not the phone's own internal memory - but it is the path returned by getExternalStorageDirectory()
for this device.
I can see three possible answers...
- Although acceptable on v2.2, specifying a fully qualified path for DB name isn't recommended and will fail on earlier versions
- Fully qualified paths are acceptable for SD card storage but the "/nand" path is being interpreted as 'internal' and only relative paths are acceptable in this case
- Something else which I'm missing completely
If any or all of the above apply I'd appreciate it if somebody could help with how I should approach this.