Edit: I tried this on my phone and it works, can anyone tell me why it does not work on an emulator?
I am trying to open a database on android, but it is throwing an "Database file could not be opened" Exception. In the debugger, it seems that the error is occurring on the line mDb = mDbHelper.getWritableDatabase();
My code is as follows:
package com.track.map;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBAdapter {
protected static final String DATABASE_NAME = "data";
protected static final int DATABASE_VERSION = 1;
//database tables
//track table
protected static final String TRACK_TABLE = "tracks";
protected static final String TRACK_ID = "_id";
protected static final String TRACK_DATE_TIME_START = "date_time_start";
protected static final String TRACK_DATE_TIME_END = "date_time_end";
//tables create
protected static final String TRACK_TABLE_CREATE =
"create table " + TRACK_TABLE + " ("
+ TRACK_ID + " integet promary key not null, "
+ TRACK_DATE_TIME_START + " text not null, "
+ TRACK_DATE_TIME_END + " text not null);";
protected DatabaseHelper mDbHelper;
protected SQLiteDatabase mDb;
protected final Context mContext;
public DBAdapter(Context context) {
mContext = context;
}
public DBAdapter open() throws android.database.SQLException {
mDbHelper = new DatabaseHelper(mContext);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDb.close();
}
protected static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TRACK_TABLE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onCreate(db); //for now just recreate the database
}
}
}
and
package com.track.map;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
private DBAdapter db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DBAdapter(this);
db.open();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Does anyone know what the problem is?
EDIT:
The logcat is:
03-24 11:43:42.022: I/Database(758): sqlite returned: error code = 14, msg = cannot open file at source line 25467
03-24 11:43:42.022: E/Database(758): sqlite3_open_v2("/data/data/com.track.map/databases/data", &handle, 6, NULL) failed
03-24 11:43:42.032: D/AndroidRuntime(758): Shutting down VM
03-24 11:43:42.032: W/dalvikvm(758): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
03-24 11:43:42.062: E/AndroidRuntime(758): FATAL EXCEPTION: main
03-24 11:43:42.062: E/AndroidRuntime(758): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.track.map/com.track.map.MainActivity}: android.database.sqlite.SQLiteException: unable to open database file
03-24 11:43:42.062: E/AndroidRuntime(758): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.os.Handler.dispatchMessage(Handler.java:99)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.os.Looper.loop(Looper.java:123)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.app.ActivityThread.main(ActivityThread.java:4627)
03-24 11:43:42.062: E/AndroidRuntime(758): at java.lang.reflect.Method.invokeNative(Native Method)
03-24 11:43:42.062: E/AndroidRuntime(758): at java.lang.reflect.Method.invoke(Method.java:521)
03-24 11:43:42.062: E/AndroidRuntime(758): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-24 11:43:42.062: E/AndroidRuntime(758): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-24 11:43:42.062: E/AndroidRuntime(758): at dalvik.system.NativeStart.main(Native Method)
03-24 11:43:42.062: E/AndroidRuntime(758): Caused by: android.database.sqlite.SQLiteException: unable to open database file
03-24 11:43:42.062: E/AndroidRuntime(758): at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1812)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
03-24 11:43:42.062: E/AndroidRuntime(758): at com.track.map.DBAdapter.open(DBAdapter.java:37)
03-24 11:43:42.062: E/AndroidRuntime(758): at com.track.map.MainActivity.onCreate(MainActivity.java:17)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-24 11:43:42.062: E/AndroidRuntime(758): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-24 11:43:42.062: E/AndroidRuntime(758): ... 11 more
This may be a little late, but hope this helps for whoever gets this problem (since I can't find a definitive solution around).
I think I know the reason for this cause (at least for my case). Looking in the DDMS --> File Explorer, you'd realize that the Database Folder (/data/data//databases/
) does not exist, which is why the application cannot create the database file in that non-existent folder. If you can create a databases folder in some manner, you can avoid this problem.
Because I'm lazy, I just used the /data/data//files/
folder when I'm in Emulator mode. You can get the files dir using this:
context.getFilesDir().getPath()
This worked beautifully for me in the Emulator.
Hope this helps someone.
In case you want to see some code:
String dbFilename = "example.db";
try
{
File databaseFile = getDatabasePath(dbFilename);
SQLiteDatabase _db = SQLiteDatabase.openOrCreateDatabase(databaseFile);
} catch (Exception e)
{
String databasePath = getFilesDir().getPath() + "/" + dbFilename;
File databaseFile = new File(databasePath);
_db = SQLiteDatabase.openOrCreateDatabase(databaseFile);
}
I tried logging into Facebook (my app has FB integration) on the Emulator and /databases folder appeared after that (and persisted). Not sure what happened, but it's possible to create that folder somehow. Something for another expert around here to shed light on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With