SQLCipher for Android Tutorial, encrypt and backup SQLite database[Part3]

In Part1 , we have prepared the Database Handler Class, the User TableDefintion Class where other Tables can be also defined.
The User class ensures reading and writing data from the database.

In Part2  of this tutorial we have use the business logic to create and getting some user information from the database.

In this part, we will try to get and view the SQLite database file from the device and decrypt it using SQLiteManager for windows.

During the development you will be also not able to see the database file and open it with some SQLite Browser software, that is because your application resource folder will not be displayed in the internal device storage until you root your device or deploy the application. But there exist a way how to copy the database from the internal device to the external sdcard and from the sdcard we will be able to copy the database file to the Desktop and open it using SQLiteManager.

Hier is the copy code. We can placed anywhere in the Activity, but after creating the Database. More information  in Part 2.


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import android.os.Environment;
import android.util.Log;
import android.os.Environment;

 try {
    File sd = Environment.getExternalStorageDirectory();
    File data = Environment.getDataDirectory();

    if (sd.canWrite()) {
       	 Log.d("DatabaseHandler", "DatabaseHandler: can write in sd");
        //Replace with YOUR_PACKAGE_NAME and YOUR_DB_NAME
        String currentDBPath = "//data//{YOUR_PACKAGE_NAME}//databases//{YOUR_DB_NAME}.db";
       //Replace with YOUR_FOLDER_PATH and TARGET_DB_NAME in the SD card
        String copieDBPath = "/{YOUR_FOLDER_PATH}/{TARGET_DB_NAME}.db";
        File currentDB = new File(data, currentDBPath);
        File copieDB = new File(sd, copieDBPath);
        if (currentDB.exists()) {
       	  Log.d("DatabaseHandler", "DatabaseHandler: DB exist");
    	  @SuppressWarnings("resource")
	  FileChannel src = new FileInputStream(currentDB).getChannel();
    	  @SuppressWarnings("resource")
	  FileChannel dst = new FileOutputStream(copieDB).getChannel();
    	  dst.transferFrom(src, 0, src.size());
    	  src.close();
    	  dst.close();
    	}
    }
    } catch  (Exception e) {
        e.printStackTrace();
    }

After launching the application on the device, you will find the copied database in the defined copieDBPath.

Please note that  DB Browser for SQLite 3.5.0  software is not supporting SQLCipher decryption for Windows until i write this tutorial.

We will use SQLiteManager that support SQLCipher decryption.

Copie or move the database to your desktop and download the SQLiteManager for windows.

After executing the software open the database file, the SQLiteManager will ask you to give the database password. The Password is defined in the DatabaseHandler class

private static final String DB_PASSWD = "YOUR_SECRET_KEY_HERE";

SQLiteManager_DatabaseKey

You will be able now to see your decrypted database data.
SQLiteManager_Database

Fixes:
if you get one of this errors:
dalvikvm E ERROR: couldn't find native method
dalvikvm E Requested: Lnet/sqlcipher/database/SQLiteDatabase;.native_getDbLookaside

Be sure that you are using the latest SQLCipher for Android
and you have the ZIP file icudt46l.zip in the assets folder.

SQLCipher for Android Tutorial, encrypt and backup SQLite database[Part2]

In Part 1 of this tutorial , we have prepared the Database Handler Class, the TableDefintion Class  where other Tables can be also defined.
The User class ensures reading and writing user data from the database.

In this part we will use the available business logic to create and getting some user information.
I will just give the database code snapshot used in the activity that you have to implemented in your activity, Please read the comment inside.

import de.webandappsolution.Database.DatabaseHandler;
import de.webandappsolution.Database.User;
import de.webandappsolution.Database.TableDefintion.TableUser;

import android.database.Cursor;
import net.sqlcipher.database.SQLiteDatabase;

//Now inside your method , create the DatabaseHandler class instance
SQLiteDatabase.loadLibs(this);
DatabaseHandler db = new DatabaseHandler(this);

// you have to set the ID,NAME,EMAIL and password.
//TIPP: The user password can you hashed before. Maybe using md5 function.
db.addUser(new User(ID,NAME, EMAIL, PASSWORD));

Log.d("DatabaseHandler", "DatabaseHandler: User is created");

we need the addUser() Method. This can be extended in the DatabaseHandler class:

//add this code in the DatabaseHandler class:
//.....
 public void addUser(User user) {
        SQLiteDatabase db = this.getWritableDatabase(DB_PASSWD);

        ContentValues values = new ContentValues();
        values.put(TableUser.USER_ID, user.getID());
        values.put(TableUser.USER_NAME, user.getName());
        values.put(TableUser.USER_EMAIL, user.getEmail());
        values.put(TableUser.USER_PASSWORD, user.getPasswordhash());

        // Inserting Row
        db.insert(TableUser.DB_USER_TABLE, null, values);

        Log.d("DatabaseHandler", "DatabaseHandler: User created");
        db.close(); // Closing database connection

    }

I will prefer to write the different user operation (CRUD) in another class like userOperationHandler.java. so that the DatabaseHandler class can only create and update the database and tables. But this is not a part of this tutorial.

Now the user should be available in the database. If we want to pick up the user data, we can add some code in the same or another activity.We will go throw all the rows in the user database table and we will compare the given email address from the view  with this one saved in the USER_EMAIL column in the database table:

//add this code to your activity:
// you have to pass the email addreess string before. Let say from the view:
EditText emailInput = (EditText) findViewById(R.id.email);
String email = emailInput.getText().toString().trim();

 SQLiteDatabase.loadLibs(this);
 DatabaseHandler db = new DatabaseHandler(this);
 Cursor cursor = db.getUser(db);
 cursor.moveToFirst();
 boolean loginstatus = false;
do
 {
    if( email.equals(cursor.getString(2)) ) {
       loginstatus = true;
    }
  }while(cursor.moveToNext());

  if(loginstatus){
     Log.d("DatabaseHandler", "DatabaseHandler: Email address found");

  }else{
      Log.d("DatabaseHandler", "DatabaseHandler: Email address not found");
  }

Now we have to add the getUser() method inside the DatabaseHandler class.
Note: getString(2) is the second selected value from the query. The index is in the columns String below

     public Cursor getUser(DatabaseHandler databasehandler){
    	SQLiteDatabase db = this.getReadableDatabase(DB_PASSWD);

        //Note:getString(0) == TableUser.USER_ID and getString(2) == TableUser.USER_EMAIL
    	String[] columns =  {TableUser.USER_ID,TableUser.USER_NAME,TableUser.USER_EMAIL};

    	Cursor cursor = db.query(TableUser.DB_USER_TABLE , columns, null, null, null, null, null);

    	return cursor;
    }

In the addUser() and the getUser() method we give always the Database Password to decrypt the requested data . The DB_PASSWD String is defined in the variable definition in the DatabaseHandler class.

In Part3 we will try to get and view the SQLite database from the device and decrypt it using SQLiteManager for windows.
go to Part3 : SQLCipher for Android Tutorial, encrypt and backup SQLite database[Part3]

SQLCipher for Android Tutorial, encrypt and backup SQLite database[Part1]

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:

database_Structure

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]

PushBots-to-PHP: send the Device RegistrationID using HttpPostRequest

Sometimes you will need the Android client device RegistrationID  to send individual Push Notification to the client device. Using the PushBots Library it will be easy to get the RegistrationID and send it using the  HttpPost Request. 

There are many Tutorials, showing how to use the PushBots Library to send push notification to your Android Application.

In our case, we have a registration or login Android Activity, that require to send also the device RegistrationID  to your Server. In this demo we will use a PHP Server application. It allow to receive the Post variables and save it in your e.g MySQL database.

Let say you have an account in PushBots and the standard push Notification example is working.

In your Activity just add the device RegistrationID to your HttpPost Request using following code:

import com.pushbots.push.Pushbots;
...
 // add your data
 List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
 nameValuePairs.add(new BasicNameValuePair("username", username));
 nameValuePairs.add(new BasicNameValuePair("deviceRegistrationID", Pushbots.getInstance().getSharedPrefs().getRegistrationID()));

httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);

Sending your HttpPost Request to the Server, in our Exapmle a PHP Server, You can get the data as following:

<?php
if($_POST){
 echo '{"user": [{"username": '.$_POST['username'].', "deviceRegistrationID": '.$_POST['deviceRegistrationID'].'}]}';
}
?>

Now you will be able to save the “deviceRegistrationID” in the Database. If you need to send push Notification to this device, you will need first to download the PushBots Library . Just create a test.php script and add this data:

<?php 	 
// Push The notification with parameters 
require_once('PushBots.class.php'); 
$pb = new PushBots();  
$appID = 'XXXXXXXXXXXXXXXXXXXXXXXXX';//Application ID : from your PushBots dashboard infos. 
appSecret = 'XXXXXXXXXXXXXXXXXXXXXXXXX'; //Application Secret : from your PushBots dashboard infos. 
//Add the device RegistrationID here ($_POST['deviceRegistrationID']) 
$MyDevice ="YYYYYYYYYYYYYYYYYYYYYYYYYY"; 
$pb->App($appID, $appSecret);
// Notification Settings
$pb->AlertOne("Your Message here");
$pb->PlatformOne("1"); //1 :for Android
$pb->TokenOne($MyDevice);

//Push to Single Device
$pb->PushOne();
?>

Here can you find the Application ID and the Application Secret from the PushBots Application Dashboard:
PushBots_dashboard

How to show icons in ActionBar overflow menu

we have started with “How to change the Backgound and Text color of AppCompat Light DarkActionBar Theme” . Sometimes you want to add icons in the android app overflow menu. Here is the final result:

Screenshot_2014-12-12-21-54-17

Sometimes it is not enough to define the icon in you activity xml file located in res/menu:

In some cases this will not have any effect to display the icon beside the item title.

Let we start to download the Action Bar Icon Pack from the following Android download link: https://developer.android.com/design/downloads/index.html#action-bar-icon-pack.

You can also create your own icons, just respect the different devices display format:

  • drawable-mdpi: 32 x 32 px
  • drawable-hdpi :  48 x 48 px
  • drawable-xhdpi 64 x 64 px
  • drawable-xxhdpi 96 x 96 px

After dowloading the zip file, just unziped and search for the “Action Bar Icons”  folder.  You have to choice which icons folder  you want to use in your theme.  You have two folders: the Holo Light and the  Holo Dark .

Next step is to search for the icon that you want to use for the overflow title. In our example we will use the “06_social_add_person” icons.

Just copy the different folders inside your project workspace (/res folder).

Now you have all icons available:

icon_action_person

Your activity xml should now have following entry’s:

You have to specify the title in /res/values/strings.xml :

The orderInCategory is just to ensure the item sequence in the overflow menu. We start the profile menu with the “0” position.

So, lets add some standard java code to be able to display the menu icons. Add followig code to your Activity located in /src/YourActivity.java

@Override
	 public boolean onMenuOpened(int featureId, Menu menu)
	 {
	     if(featureId == Window.FEATURE_ACTION_BAR && menu != null){
	         if(menu.getClass().getSimpleName().equals("MenuBuilder")){
	             try{
	                 Method m = menu.getClass().getDeclaredMethod(
	                     "setOptionalIconsVisible", Boolean.TYPE);
	                 m.setAccessible(true);
	                 m.invoke(menu, true);
	             }
	             catch(NoSuchMethodException e){
                         //write in the LogCat 
	                 Log.e(TAG, "onMenuOpened", e);
	             }
	             catch(Exception e){
	                 throw new RuntimeException(e);
	             }
	         }
	     }
	     return super.onMenuOpened(featureId, menu);
	 }

Eclipse ADT will suggest to import the necessary classes, in this case:

import java.lang.reflect.Method;
import android.view.Window;
import android.util.Log;

That’s all !

How to change the Backgound and Text color of AppCompat Light DarkActionBar Theme

Here is a simple way how to change the background and text color on the Android AppCompat Light DarkActionBar.
Here is the final result:
AndroidActionBar

Let say your app has following name :<MyTheme>

and you are using the Andoird 3.0 version.
In  res/AndoidManifest.xml you will have following code:

1. Add following code in the res/values/styles.xml file:

2. Create the color definition file under: res/values/colors.xml and add following code:

That’s  all.

In the next tutorial we will see  How to show icons in ActionBar overflow menu