Squonk Squonk - 1 month ago 13
Android Question

SQLiteOpenHelper problem with fully qualified DB path name

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...


  1. Although acceptable on v2.2, specifying a fully qualified path for DB name isn't recommended and will fail on earlier versions

  2. 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

  3. 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.

Thanks.

Answer

Historically, you have not been able to use paths with SQLiteOpenHelper. It only worked on simple filenames. I had not realized that they relaxed that restriction in Android 2.2.

If you wish to use databases on the SD card, and you wish to support Android 2.1 and earlier, you cannot use SQLiteOpenHelper.

Sorry!

Comments