Android: SQLCipher v3.5.9: Problem opening database when service is auto recreated


#1

Hello People…!

I am performing database updation in Android background service after every 5 minutes in background.
When user swips out the task from recent app, leaving database open as task is still being performed,
service is abruptly closed and restarted (used START_STICKY flag to autorestart the service).
When app again tries to open database in background service it gives following error.:

    net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master;
    at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
    at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
    at net.sqlcipher.database.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
    at net.sqlcipher.database.SQLiteProgram.<init>(SQLiteProgram.java:89)
    at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:48)
    at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:60)
    at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1867)
    at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1785)
    at net.sqlcipher.database.SQLiteDatabase.keyDatabase(SQLiteDatabase.java:2486)
    at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2415)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1149)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1041)
    at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:249)
    at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:214)
    at mobicule.edelwiss.edelweisscficore.storage.DBHelper.getReadableDB(DBHelper.java:352)
    at mobicule.edelwiss.edelweisscficore.storage.DBHelper.getObjectFromDynamicTable(DBHelper.java:425)
    at com.edelweiss.avcgeo.storage.DBHelper.getAllErrorRecord(DBHelper.java:186)
    at com.edelweiss.avcgeo.service.SyncIntentService.submitErrorRecord(SyncIntentService.java:263)
    at com.edelweiss.avcgeo.service.SyncIntentService.handleActionDataUpload(SyncIntentService.java:242)
    at com.edelweiss.avcgeo.service.SyncIntentService.onHandleIntent(SyncIntentService.java:212)
    at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.os.HandlerThread.run(HandlerThread.java:61)

I tried overriding onTaskRemoved() method in service to close database before task removal.
But it seems, service recreation takes place at the moment user ends the task whereas onTaskRemoved() is called when all tasks in older service(which is ended by user) are ended.

I am using synchronized singletone mechanism to get db reference to avoid problem due to multithreading, but as the new service will be running in the background eventhough older is not ended yet(android service behavior), multithreading problem remains in picture.
.
I can’t use foreground service to restrict it’s recreation as my app requirements says so.

I need better approach for handling things, please suggest.
Any help will be appreciated.