Skip to content

using sqlcipher database across multiple activities? #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
silosnowdash opened this issue Feb 14, 2013 · 9 comments
Closed

using sqlcipher database across multiple activities? #90

silosnowdash opened this issue Feb 14, 2013 · 9 comments

Comments

@silosnowdash
Copy link

Is this possible? I tried using the application context (instead of the activity context) for initializing the database, but regardless of which context I use, everytime that I move onto the second activity my SQLiteOpenHelper creates the tables all over again when it initializes... So the database isn't persisting between activities...

I haven't found anything on Google about using it across activities - does anyone know how this might be achieved?

@developernotes
Copy link
Member

Hi mjguse,

You certainly can use SQLCipher for Android across multiple activities. An example of what you can do is make your subclass to net.sqlcipher.database.SQLiteOpenHelper a singleton providing a static getInstance() method. You can also provide your SQLiteOpenHelper constructor the shared instance of your Application subclass for a reference to the Context.

@silosnowdash
Copy link
Author

Hey There -

I know you closed this but I may have found a bug. The problem I was having wasn't with the application context at all, it was actually with the name I was using for my database. I was trying to use "FCPokerSun.db" as the name, and for some reason using this particular name creates a non-persisting database with sqlcipher, which does not persist between activities or even between closing/restarting the application.

This database name DOES however work properly with just regular sqlite. I tried other 10 character database names with sqlcipher, along with mixing uppercase/lowercase and they all worked... so I'm totally baffled why "FCPokerSun.db" does not and wonder if there are other name combinations that don't... This kept me busy for 6 hours so I don't know if it's a bug but if there's a naming convention for sqlcipher database names that deviates from regular sqlite it may be beneficial to document that somewhere.. anyway thanks for your help.

@developernotes
Copy link
Member

Hi mjguse,

I tested out your database name on an application I work on which uses SQLCipher for Android, there were no issue using that database name when closing and restarting the application.

You might want to verify your application behavior with a debugger to watch exactly what is occurring. Are you properly updating the version of the database when either onCreate or onUpgrade are called within your SQLiteOpenHelper subclass?

@silosnowdash
Copy link
Author

Hey there - Thanks very much for letting me know the problem is on my end. I had used that DB name in past with just regular sqlite and I suppose some remnant must have carried over. Thanks again, have a great day!

@silosnowdash
Copy link
Author

Hey there -

I found the problem!!

When I initialize sqlcipher and I feed it the same database name:

File databaseFile = context.getDatabasePath("pizza.db");

as I feed the constructor for my SQLiteOpenHelper:

DatabaseHelper(Context c) {
super(c, "pizza.db", null, 1);
}

The database then recreates every time that I create a new SQLiteOpenHelper (i.e. closing/restarting the application)... In other words, you need to use separate database names for the initialization function and the SQLiteOpenHelper... I suspect the first database contains keys for encryption... Anyway very sorry to waste your time, I didn't see anything in the documentation that explained this, but glad to finally have it working.

@developernotes
Copy link
Member

Hi mjguse,

There is nothing wrong with passing the same name of the database to the constructor of the SQLiteOpenHelper subclass, that in fact should stay they same. You should to review what is occurring in your onCreate and onUpgrade methods.

@silosnowdash
Copy link
Author

Hi there -

Really? I have breakpoints in my onCreate method, and if I use the same database for both methods ("pizza.db" as shown below), then everytime that I run the application and create a new DBAdapter in the main activity, the sqliteOpenHelper calls onCreate (which just creates the tables over again, but this means data isn't persisting after the app has been closed)...

However - if I use a different database name for sqliteOpenHelper, it totally works as expected... the first time I run the application it creates two databases ("pizza.db" and whatever), encrypts them both, and the next time I run the application onCreate is not called... Do you see anything at quick glance that I'm doing which could be causing this?

public class DBAdapter {

private final Context context;  
private DatabaseHelper helper;
private SQLiteDatabase db;

public DBAdapter(Context c) {
    this.context = c;

    SQLiteDatabase.loadLibs(context);
    File databaseFile = context.getDatabasePath("pizza.db");
    databaseFile.mkdirs();
    databaseFile.delete();
    db = SQLiteDatabase.openOrCreateDatabase(databaseFile, "test123", null);
    db.close();
}

private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper(Context c) {
        super(c, "pizza.db", null, 1);
    }


    public void onCreate(SQLiteDatabase db) {
        //create our master tables
        db.execSQL(MySQLConstants.TB_CHAR_CREATE);
        etc... I just create a few more tables here...
    }


    public void onUpgrade(SQLiteDatabase db, int oldVer, int newVer) {
        db.execSQL("DROP TABLE IF EXISTS "+ MySQLConstants.TB_CHAR);
        etc...
        onCreate(db);

    }
}

public DBAdapter open() throws SQLException {

    helper = new DatabaseHelper(context);
        db = helper.getWritableDatabase("testing123");

    System.gc();
    return this;
}

}

@developernotes
Copy link
Member

Hi mjguse,

The issue is that you are calling InitializeSQLCipher inside your constructor, and your InitializeSQLCipher is deleting the database file every time. So every time you create a new DBAdapter it deletes the file.

@silosnowdash
Copy link
Author

aHA!! Thanks a ton!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants