I am trying to open a sqlite database that I created and loaded and /assets of my project. I use a class, MySQLiteHelper to open this database and to handle upgrades, etc.
In my Activity I create a new instance of MySQLiteHelper ... as I do so, it says that it can't open the database (see logcat below).
Had this working and now it stopped. Confused why I am now receiving this error ... I rolled back my changes and I still receive this error. I am thinking it has something to do with the file I am loading? Any help would be appreciated.
Class to open sqlite:
package com.sembasys....;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MySQLiteHelper extends SQLiteOpenHelper {
// The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.sembasys.metrosleepnyc/databases/";
private static String DB_NAME = "metrosleep";
private SQLiteDatabase myDataBase;
private final Context myContext;
private static final int DATABASE_VERSION = 1;
public static final String KEY_ID = "stop_id";
public static final String LINE_ID = "line_id";
public static final String STATION= "station_name";
public MySQLiteHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own
* database.
* */
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
Log.v("DB Exists", "db exists");
// By calling this method here onUpgrade will be called on a
// writeable database, but only if the version number has been
// bumped
this.getWritableDatabase();
}
dbExist = checkDataBase();
if (!dbExist) {
// By calling this method and empty database will be created into
// the default system path of your application so we are gonna be
// able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each
* time you open the application.
*
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created
* empty database in the system folder, from where it can be accessed and
* handled. This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion)
Log.v("Database Upgrade", "Database version higher than old.");
myContext.deleteDatabase(DB_NAME);
}
}
Activity where I implement the above class:
package com.sembasys....;
import com.actionbarsherlock.app.SherlockActivity;
import android.widget.SimpleCursorAdapter;
import android.annotation.TargetApi;
import android.app.ListActivity;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.support.v4.app.NavUtils;
public class ChooseRoute extends ListActivity {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Show the Up button in the action bar.
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);
MySQLiteHelper myDbHelper = new MySQLiteHelper(null);
myDbHelper = new MySQLiteHelper(this);
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
if(isNetworkAvailable()) {
setContentView(R.layout.activity_choose_route);
TextView empty = (TextView) findViewById(android.R.id.empty);
empty.setVisibility(View.VISIBLE);
SQLiteDatabase db = myDbHelper.getReadableDatabase();
String TABLE_NAME = "Stops";
Cursor cursor = db.query(true, TABLE_NAME , new String[] { MySQLiteHelper.LINE_ID, MySQLiteHelper.STATION}, null, null, null, null, null, null);
startManagingCursor(cursor);
String[] columns = new String[] { MySQLiteHelper.STATION };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.text };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.todo_row, cursor, columns, to);
setListAdapter(adapter);
registerForContextMenu(getListView());
} else {
setContentView(R.layout.no_connection);
}
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null;
}
}
And the logcat.
12-17 14:07:27.827: W/dalvikvm(23119): threadid=1: thread exiting with uncaught exception (group=0x40de8930)
12-17 14:07:27.847: E/AndroidRuntime(23119): FATAL EXCEPTION: main
12-17 14:07:27.847: E/AndroidRuntime(23119): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sembasys.metrosleepnyc/com.sembasys.metrosleepnyc.ChooseRoute}: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.app.ActivityThread.access$600(ActivityThread.java:141)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.os.Handler.dispatchMessage(Handler.java:99)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.os.Looper.loop(Looper.java:137)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.app.ActivityThread.main(ActivityThread.java:5039)
12-17 14:07:27.847: E/AndroidRuntime(23119): at java.lang.reflect.Method.invokeNative(Native Method)
12-17 14:07:27.847: E/AndroidRuntime(23119): at java.lang.reflect.Method.invoke(Method.java:511)
12-17 14:07:27.847: E/AndroidRuntime(23119): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
12-17 14:07:27.847: E/AndroidRuntime(23119): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
12-17 14:07:27.847: E/AndroidRuntime(23119): at dalvik.system.NativeStart.main(Native Method)
12-17 14:07:27.847: E/AndroidRuntime(23119): Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
12-17 14:07:27.847: E/AndroidRuntime(23119): at com.sembasys.metrosleepnyc.MySQLiteHelper.openDataBase(MySQLiteHelper.java:126)
12-17 14:07:27.847: E/AndroidRuntime(23119): at com.sembasys.metrosleepnyc.ChooseRoute.onCreate(ChooseRoute.java:36)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.app.Activity.performCreate(Activity.java:5104)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
12-17 14:07:27.847: E/AndroidRuntime(23119): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
12-17 14:07:27.847: E/AndroidRuntime(23119): ... 11 more