androidsqlcipherandroid-6.0.1-marshmallow

SqlCipher: Could not open database on Android 6.0.1


Previously I was using just SQLite and never had a problem, I just change to SQLCipher and on devices with versions 7, 8, 8.1, 9 its working fine, just with Android 6.0.1 I have the following error:

net.sqlcipher.database.SQLiteException: error code 14: Could not open database
    at net.sqlcipher.database.SQLiteDatabase.dbopen(Native Method)
    at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2575)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1243)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1210)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1182)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1131)
    at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1332)
    at android.xdl.dripapp_opencv.DB.DBSettings.InitializeDatabase(DBSettings.java:41)
    at android.xdl.dripapp_opencv.MainActivity.onCreate(MainActivity.java:109)
    at android.app.Activity.performCreate(Activity.java:6262)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1125)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2462)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2569) 
    at android.app.ActivityThread.access$900(ActivityThread.java:150) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1399) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:168) 
    at android.app.ActivityThread.main(ActivityThread.java:5885) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 

I'm using the following method to create the database, it's being called on onCreate method of my MainActivity:

DBSettings

public void InitializeDatabase(){
    SQLiteDatabase.loadLibs(_ctx);

    String databasePath = _ctx.getDatabasePath(DATABASE_FILE_NAME).getPath();

    SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databasePath, DATABASE_PASS, null);

    database.execSQL(CREATE_PATIENT_RECORDS_TABLE);
    database.execSQL(CREATE_SESSION_RECORDS_TABLE);


    database.close();
}

I have the following permission on Manifest:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

I've even tried to ask for that permission at runtime as other answers says, but did not work, I got the dialog, after I accept the permission the same error appears.

I've tried to use not the path but the file, I got the same error:

File databaseFile = getDatabasePath(DATABASE_FILE_NAME);
SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databaseFile, DATABASE_PASS, null);

I've tried to use mkdir as the documentation site for SQLCipher says, but nothing.

File databaseFile = getDatabasePath(DATABASE_FILE_NAME);
databaseFile.mkdirs();

I'm using this version of SQLCipher:

implementation 'net.zetetic:android-database-sqlcipher:4.2.0@aar'

Solution

  • Digging into the SqlCipher Tests Project after running all test successfully on my 6.0.1 devices, found out the way the say on the documentation and the way the implemented is different.

    What is working now is:

    databaseFile.getParentFile().mkdirs();
    

    Instead of:

    databaseFile.mkdirs();