jeudi 2 avril 2015

android app sometimes crashes due to unable to open database file (code 14)

I am using a pre-build sqlite database, and I saved it in the assets folder.


My app sometimes crashes, but sometimes it doesn't. Mostly it crashes when I try to query data from DB for the 2nd or 3rd time in the same fragment. If I query only for once it doesn't crash.



04-02 09:42:55.759 2938-2938/com.example.user10.sample E/SQLiteLog﹕ (14) cannot open file at line 30191 of [00bb9c9ce4]
04-02 09:42:55.759 2938-2938/com.example.user10.sample E/SQLiteLog﹕ (14) os_unix.c:30191: (24) open(/data/data/com.example.user10.sample/databases/sample.sqlite-journal) -
04-02 09:42:55.759 2938-2938/com.example.user10.sample E/SQLiteLog﹕ (14) cannot open file at line 30191 of [00bb9c9ce4]
04-02 09:42:55.759 2938-2938/com.example.user10.sample E/SQLiteLog﹕ (14) os_unix.c:30191: (24) open(/data/data/com.example.user10.sample/databases/sample.sqlite-journal) -
04-02 09:42:55.759 2938-2938/com.example.user10.sample E/SQLiteLog﹕ (14) statement aborts at 46: [SELECT Event2.EventId, Title, Abstract, Description, Image, ReferentFirstName, ReferentLastName, ReferentEmail, ReferentPhone, ReferentMobile, Vote, CompanyId, GpsCoordinates, Address,
04-02 09:42:55.759 2938-2938/com.example.user10.sample E/SQLiteConnection﹕ startPos 283 > actual rows 0
04-02 09:42:55.759 2938-2938/com.example.user10.sample E/SQLiteQuery﹕ exception: unable to open database file (code 14); query: SELECT Event2.EventId, Title, Abstract, Description, Image, ReferentFirstName, ReferentLastName, ReferentEmail, ReferentPhone, ReferentMobile, Vote, CompanyId, GpsCoordinates, Address, City, Province, Images.ImageData FROM (EventSpot2 INNER JOIN Event2 on Event2.EventId = EventSpot2.EventId) LEFT JOIN Images ON Images.ImagePath = Event2.Image
04-02 09:42:55.759 2938-2938/com.example.user10.sample D/AndroidRuntime﹕ Shutting down VM
04-02 09:42:55.769 2938-2938/com.example.user10.sample W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xb0d53b20)
04-02 09:42:55.769 2938-2938/com.example.user10.sample E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.user10.sample, PID: 2938
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:845)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:152)
at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
at android.database.AbstractCursor.moveToNext(AbstractCursor.java:245)
at com.example.user10.sample.MapEvent$6.onClick(MapEvent.java:553)
at android.view.View.performClick(View.java:4438)
at android.widget.CompoundButton.performClick(CompoundButton.java:100)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)


And this is my dbhelper:



public class ExternalDbOpenHelper extends SQLiteOpenHelper {

//Path to the device folder with databases
public static String DB_PATH;

//Database file name
public static String DB_NAME;
public SQLiteDatabase database;
public final Context context;

public SQLiteDatabase getDb() {
return database;
}

public ExternalDbOpenHelper(Context context, String databaseName) {
super(context, databaseName, null, 1);
this.context = context;
//Write a full path to the databases of your application
if (Build.VERSION.SDK_INT >= 17){
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
}else {
String packageName = context.getPackageName();
DB_PATH = String.format("//data//data//%s//databases//", packageName);
}

DB_NAME = databaseName;
openDataBase();
}

//This piece of code will create a database if it’s not yet created
public void createDataBase() {
boolean dbExist = checkDataBase();
if (!dbExist) {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
Log.e(this.getClass().toString(), "Copying error");
throw new Error("Error copying database!");
}
} else {
Log.i(this.getClass().toString(), "Database already exists");
}
}

//Performing a database existence check
private boolean checkDataBase() {
SQLiteDatabase checkDb = null;
// File dbFile = new File(DB_PATH + DB_NAME);
File dbFile = new File(context.getDatabasePath(DB_NAME).getPath());
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();

}

//Method for copying the database
private void copyDataBase() throws IOException {
//Open a stream for reading from our ready-made database
//The stream source is located in the assets
InputStream externalDbStream = context.getAssets().open(DB_NAME);

//Path to the created empty database on your Android device
String outFileName = DB_PATH + DB_NAME;

//Now create a stream for writing the database byte by byte
OutputStream localDbStream = new FileOutputStream(outFileName);

//Copying the database
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = externalDbStream.read(buffer)) > 0) {
localDbStream.write(buffer, 0, bytesRead);
}
//Don’t forget to close the streams
localDbStream.close();
externalDbStream.close();
}

public SQLiteDatabase openDataBase() throws SQLException {
String path = DB_PATH + DB_NAME;
if (database == null) {
createDataBase();
database = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READWRITE);
}
return database;
}

@Override
public synchronized void close() {
if (database != null) {
database.close();
}
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}


Hope you could help me. Thank you.


Aucun commentaire:

Enregistrer un commentaire