The way to use SQLCipher for Android application can sometimes take time and is associated with many search in web for fixes or answers to your problems. May be you will be more often in stackoverflow.com to fix some errors and searching for answers.
To find the right version to install or to be sure if your database is encrypted is also associated with many web search. During the development you will be also not able to see the database file and open it with some SQLite Browser programs, that is because your application resources folder will not be displayed in the internal device storage until you root your device or deploy the application. I present a solution in Part 3 of this tutorial and how to access the SQLite /SQLCipher database in the development mode.
Some web resources or tutorials are also old so if you are developing apps in 2015 you will take some times to find the right answers. One of the common problems can you fix them when you use the latest version of SQLCipher.
I will summarize my searches in this tutorial and give the version that i’m using .
Let’s start with the different versions number:
– SQLCipher for Android : community- 3.2.0 download from : https://www.zetetic.net/sqlcipher/open-source/
– SDK that i’m using:
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />
– Tested with Samsung S5 Galaxy with Android 4.4.2
I have follow the Tutorial presented in https://www.zetetic.net/sqlcipher/sqlcipher-for-android/ but the problem was that developers want always to separate the different code logic . So i’m not sure if some developers like to create the database or tables within the activity using the InitializeSQLCipher() method.
The First SQLite tutorials have always treat the Database Handler in a separated class. This concept should always be available, so that we can separate the activity from creating the database routine. The Database name , password and the different CRUD operation still be available in the Database handler class.
Let’s start switching to use the SQLCipher within the Database Handler class. In this tutorial i will create a user table where it will be possible to login in the offline mode. The password is also hashed in the database.
I use the different database classes in a separate package : package de.webandappsolution.Database . You have to rename it with your package name and check if all dependency packages are properly imported.
package de.webandappsolution.Database; import de.webandappsolution.Database.TableDefintion.TableUser; import android.content.ContentValues; import android.content.Context; import android.util.Log; import android.database.Cursor; import net.sqlcipher.database.SQLiteDatabase; import net.sqlcipher.database.SQLiteOpenHelper; public class DatabaseHandler extends SQLiteOpenHelper { private static final int DATABASE_VERSION = 1; private static final String DATABASE_NAME = "WebAndAppManager.db"; private static final String DB_PASSWD = "YOUR_SECRET_KEY_HERE"; public String CREATE_USER_TABLE = "CREATE TABLE " + TableUser.DB_USER_TABLE + "(" + TableUser.USER_ID + " TEXT," + TableUser.USER_NAME + " TEXT," + TableUser.USER_EMAIL + " TEXT," + TableUser.USER_PASSWORD + " TEXT" + ")"; public DatabaseHandler(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); Log.d("DatabaseHandler", "DatabaseHandler: Database created"); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_USER_TABLE); Log.d("DatabaseHandler", "DatabaseHandler: Table User created"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TableUser.DB_USER_TABLE); // Create tables again onCreate(db); } }
The TableDefintion class is also defined in the same package:
package de.webandappsolution.Database; import android.provider.BaseColumns; public class TableDefintion { public TableDefintion(){} public static abstract class TableUser implements BaseColumns { public static final String DB_USER_TABLE = "user"; public static final String USER_ID = "id"; public static final String USER_NAME = "name"; public static final String USER_EMAIL = "email"; public static final String USER_PASSWORD = "password"; } }
Now we have to define the user class with the different getter and setter.
package de.webandappsolution.Database; public class User { //private variables String _id; String _name; String _email; String _passwordhash; // constructor addUser() public User(String id, String name, String email,String passwordhash,){ this._id = id; this._name = name; this._email = email; this._passwordhash = passwordhash; } // getting ID public String getID(){ return this._id; } // setting id public void setID(String id){ this._id = id; } // getting name public String getName(){ return this._name; } // setting name public void setName(String name){ this._name = name; } // getting email public String getEmail(){ return this._email; } // setting email public void setEmail(String email){ this._email = email; } // getting passwordhash public String getPasswordhash(){ return this._passwordhash; } // setting passwordhash public void setPasswordhash(String passwordhash){ this._passwordhash = passwordhash; } }
The final folder structure is presented in the next snapshot:
In Part2 we will call our database handler from the activity and creating and getting user information.
go to Part2 : SQLCipher for Android Tutorial, encrypt and backup SQLite database[Part2]