Thursday 13 September 2012

Using database for objects (db4o) in android part-1

Mapping object paradigm to relational paradigm is very hectic job for programmer and intensive for processor. As mobile development move to object oriented paradigm, we need object based database where we can directly store/retrieve/update and delete objects without first converting them to relational table entities.

Fortunately we have db4o, which was released just after first release of android. db4o is database for objects. when we say "objects" this means objects are not converted to relational tables at any stage (neither by programmer nor by framework). db4o is fast, has small footprint and low processing overhead. You can read about performance comparison with other mobile databases  here.

In this post I'll explain:
  1. How to setup db4o to use in android project using eclipse. and
  2. How to perform CRUD operations on simple objects.

In order to setup db4o for your project, download latest version db4o library, extract the zip and put db4o-all.jar in your lib folder and update java build path.


Lets say we have custom class, Contact.java:

public class Contact {

    private String name;

    private String number;

    int age;

    boolean member;

    public Contact() {

        // default constructor

        name = null;

        number = null;

        age = 0;

        member = false;

    }

    public Contact(String name, String number, int age, boolean member) {

        this.name = name;

        this.number = number;

        this.age = age;

        this.member = member;

    }

    public String getNumber() {

        return number;

    }

    public void setNumber(String number) {

        this.number = number;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public boolean isMember() {

        return member;

    }

    public void setMember(boolean member) {

        this.member = member;

    }


    public void setName(String name) {

        this.name = name;

    }


    public String getName() {

        return name;

    }


    public String toString() {


        return name + "/" + number + "/" + Integer.toString(age) + "/"

                + Boolean.toString(member);

    }


}



Now lets start working with db40, first open the database:

ObjectContainer db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), DATABASE_PATH);



ObjectContainer is the db4o type which hold the database reference. We will use this reference to call all db4o methods for CRUD. There various options we can set using configuration, for the time being lets just use the default configuration Db4oEmbedded.newConfiguration().

Once database is open, we can store, retrieve update and delete objects:
  • Inserting objects:
    • store(Object o) method of ObjectContainer is used to insert new objects in database. e.g
           
 Contact con= new Contact("sohail", "111", 10, true);
 db.store(con);
 db.commit();
         

  • Querying objects:
    • There are two methods we can use to retrieve stored objects, these are: 
      • queryByExample(Object o) and
      • native query
In this tutorial, I'll use queryByExample which is simple and understand  for  beginners.

queryByExample takes and object and retrieve object/s similar to object supplied in arguments. In order to get all objects, we need to pass a dummy object whose all fields are set to null/0.

For example to get all objects where age=10,

 

Contact c=new Contact(null,null,10,true);

ObjectSet list=db.queryByExample(c);

this will return a list of all objects where age=10.

To fetch all objects of type Contact:

Contact t= new Contact();

ObjectSet list= db.queryByExample(t);



this will return all the objects of type Contact, Note that default constructor initializing all the fields to null and zeros. This is necessary to fetch all object. ObjectSet is db4o type which can be think of list of objects.


  • Updating objects:
    • In order to update an object, we need to first query that object and then we can update it using store method. e.g to update object where name= sohail
 

Object q=new Object();

q.setName("sohail);

ObjectSet result= db.queryByExample(q);



if(result.hasNext())

{

    Contact c= (Contact) result.next();

    //update age,number

    c.setAge(33);

   c.setNumber("444444444"); 

  db.store(c);



}

 

what we are doing here is to find the object where name=sohail, if found (result.hasNext) then update it.

  • Deleting Objects:
    • like updating, in order to delete objects we need to first query that object and bring it into memory, then we can use delete() method to delete.e.g deleting object where contact name=sohail
 

Contact n=new Contact();

n.setName("sohail");

ObjectSet result= db.queryByExample(n);



if(result.hasNext())

{

     Contact d=(Contact) result.next(); 

     db.delete(d);

}


Thats all. QueryByExample is simple however it has some limitations, we will discuss native queries in next tutorial which use the semantic of programming language, give more control and are recommended.


Full source:
package sohail.aziz.db4oexample;
import java.util.ArrayList;
import android.util.Log;
import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;

public class DbHelperQBE {

    String dbpath;
    ObjectContainer db;

    boolean OpenDb(String name) {

        if (name != null) {

            db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), name);

            return true;

        }

        return false;

    }


    void CloseDb() {

        db.close();

    }

    void emptyDb(){
   
        ObjectSet result= db.queryByExample(new Object());
    
        while(result.hasNext()){

               db.delete(result.next());   

        }
     

    }


    void StoreContact(Contact con) {

        db.store(con);

        db.commit();

        Log.d("sohail", "object stored");

    }

    Contact getContactByName(String name) {

       // define

        Contact obj = new Contact();

        obj.setName(name);

        ObjectSet result = db.queryByExample(obj);


        if (result.hasNext()) {

            return (Contact) result.next();

        }

        return null;

    }

    Contact getContact(Contact con) {

        ObjectSet result = db.queryByExample(con);


        if (result.hasNext()) {

            return (Contact) result.next();

        } else

            return null;

    }


    ArrayList<Contact> getAllContacts() {


        ArrayList<Contact> list = new ArrayList<Contact>();

        Contact proto = new Contact();

        ObjectSet<Contact> result = db.queryByExample(proto);


        while (result.hasNext()) {

            list.add(result.next());

        }

        return list;

    }

    boolean updateObject(Contact ObjTo, Contact ObjFrom) {



        Contact found = null;

        ObjectSet<Contact> result = db.queryByExample(ObjTo);

        if (result.hasNext()) { // if found

            found = result.next();

            found.setAge(ObjFrom.getAge()); // shallow copy just replay to, to From.

            found.setMember(ObjFrom.isMember());

            found.setName(ObjFrom.getName());

            found.setNumber(ObjFrom.getNumber());

            db.store(found);

            db.commit();

            return true;

        }

        return false;

    }

    boolean deleteObject(Contact p) {

        Contact found = null;
        ObjectSet<Contact> result = db.queryByExample(p);

        if (result.hasNext()) {

            found = result.next();
            db.delete(found);

            return true;

        } else {

            return false;

        }

    }

}


Tuesday 31 July 2012

Convenient Logger for android

Logging is an important technique of debugging during application development. Android provide Log class for logging different log-level messages. However in order to easily filter the log messages (in Logcat) and directly pinpointing the location of log message is a bit tricky (with default Log class).

I have implemented my own Log class primarily:
  • To set one application TAG (for ease of filtering).
  • To make logging enable/disable for development and release version.
  • and to print classname:function name:line no with log message like __FILE__,__FUNC__ and __LINE__ macros in C.


public class Log {



    private static boolean enableLog = true;

    private static String TAG = "YourAppTag";


 public static void i(Object... objects) {

        if (enableLog) {

            android.util.Log.i(TAG, toString(objects));

        }

    }
 public static void d(Object... objects) {

        if (enableLog) {



            String fullClassName = Thread.currentThread().getStackTrace()[3]

                    .getClassName();

            String className = fullClassName.substring(fullClassName

                    .lastIndexOf(".") + 1);

            String methodName = Thread.currentThread().getStackTrace()[3]

                    .getMethodName();

            int lineNumber = Thread.currentThread().getStackTrace()[3]

                    .getLineNumber();

            String finalMessage = className + "." + methodName + "():Line:"

                    + lineNumber + ":" + toString(objects);



            android.util.Log.d(TAG, finalMessage);

        }

    }



public static void e(Object... objects) {

        if (enableLog) {

            android.util.Log.e(TAG, toString(objects));

        }

    }

public static void w(Object... objects) {

        if (enableLog) {

            android.util.Log.w(TAG, toString(objects));

        }

    }


private static String toString(Object... objects) {

        StringBuilder sb = new StringBuilder();

        for (Object o : objects) {

            sb.append(o);

        }

        return sb.toString();

    }

}


Thursday 21 June 2012

Application Class: Application-wide data sharing #android

There are cases when we need to share same data to all application components and we want anyone to be able to update that data. Example of this use-case can be application settings e.g shared preferences.

Application class instance is initiated before any other component and remained there till the application terminate. You can think of application class as parent of all other application component (activities, services and broadcast receivers).

We can use application class as a global space available for all application components.We can get application object with getApplication() and call its public methods and variables where ever we like.

Lets see how can we create application class and use it:

1- Create new java class lets say MyApplication and extend it from Application

public class MyApplication extends Application {

int myGlobal;

@Override
public void onTerminate() {
// TODO Auto-generated method stub 
super.onTerminate();

@Override
public void onCreate() {

// TODO Auto-generated method stub super.onCreate();

myGlobal=0;

Log.d("sohail","MyApplication created, calling initSingleton");
}

public int getGlobal {

// TODO Auto-generated method stub
return myGlobal;
}

public void setGlobal(int in){

myGlobal=in;

} 

}

2. Set application name = MyApplication in manifest.xml. like


<application

android:icon="@drawable/ic_launcher"

android:label="@string/app_name" 

android:name=".MyApplication"

> 
..... 
..... 

</application> 
3- Now we can set and get our Global variable from any activity, service or broacast receiver like:

MyApplication appObj= (MyApplication) getApplication(); 

appObj.setGlobal(123);

appObj.getGlobal();


There are various useful methods which can be override in application class e.g

onConfigurationChanged() : called when device configuration changes while this application is running.

 onLowMemory(): "called when system is going in low memory and applications may get killed". We can override this function to release application resources and gracefully terminate the application before system terminate it.

Application class is good place for application centric data sharing, however normal intents should be used to pass data between application components and one should not abuse this space to make android a procedural language.

Note: Android application are not actually terminated when user close/exit the app (calling finish()), rather android System push the application on stack and decides itself when to actually terminate (kill process) the application. So Do not rely on application OnCreate and OnTerminate methods to initialize or de-initialize any variables. If application is not actually terminated by System, neither OnTerminate will be called nor OnCreate (on Second launch).

Monday 18 June 2012

Scheduling activities, services and broadcasts #Android

AlarmManager comes into play when we need to schedule different task in some future time/date or we need to execute some task repeatedly. AlarmManager is android service provided for scheduling purposes. We can use AlarmManager to start activities/services and to send broadcast in some future date/time. Activities, Services or broadcasts registered with AlarmManager will be executed no matter your application is running or not. You can also make AlarmManager to wake up the device (if in sleep state) on given schedule.

In order to registered application components (activities, services and broadcasts) with AlarmManager, we need to obtain a Pending Intent  of an Intent and the use this Intent to  register with AlarmManager. The difference between Pending Intent and normal Intent is that "they are launched with the your application permissions rather than the one who is launching them".

Below is the comparison of pendingInent and normal Inents for starting activities, services and broadcasts:

PendingInent.getActivity =~ startActivity (Inent)
PendingInent.getService =~ startService(Intent)
PendingInent.getBroadcast =~ sendBroadcast(Inent)

Lets say we want to launch an activity called MyActivity after 5 seconds of the current time. We will:

  • Create an Intent of the activity we want to launch.
  • Obtain a PendingIntent of this Intent.Registered this pending intent with AlarmManager.
 
Intent i = new Intent(getApplicationContext(), MyActivity.class);
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),3333,i,
PendingIntent.FLAG_CANCEL_CURRENT);
 


Lets quickly explain the getActivity arguments, first one is context, second one is
optional number (lets say identification number, fourth one is the intent we want to launch and the last one is again optional flag (in this case we are telling the system that if this intent (3333) is already running cancel it and run again.

  • Registered it with alarmmanager,

 
//getting current time and add 5 seconds in it 
Calendar cal = Calendar.getInstance(); 
cal.add(Calendar.SECOND, 5); 
//registering our pending intent with alarmmanager 
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);
 

First argument of am is the flag telling the system what to do, in this case we are telling the system that wake up the system if its in sleep state while launching the intent on this particular time.
In order to start service or send broadcast we only need to create pending intent
these and pass to alarmmanager, e.g lets say we have service called MyService


 
Intent ii = new Intent(getApplicationContext(), MyService.class);
PendingIntent pii = PendingIntent.getService(getApplicationContext(), 2222, ii,
PendingIntent.FLAG_CANCEL_CURRENT);
 

and for broadcast

 
Intent i= new Intent(); 
i.setAction("my.action"); //the name which we will specify in our receiver 
i.putExtra("counter",234); PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(),
1111, i,PendingIntent.FLAG_CANCEL_CURRENT);
 


Thats for today. Have a question ? ask!

Monday 28 May 2012

Broadcast Receiver: Two ways to implement part-2

In the previous tutorial, we discussed how to implement/register broadcast receiver inside an activity. Broadcast receiver is a standalone application component which means it will continue running even when other application component are not running. That's why we unregister broadcast receiver in onPause on the activity.

Second way of using broadcast receiver is to register it inside manifest.xml. When registered (and not unregistered) broadcast receiver exists as long as application exists. There could be many use cases of using broadcast receiver this way. These could be waiting for specific event to occur and start/stop other application component upon the occurrence of that event, initiate network communication or communicate with contentprovider . . .etc.

This is pretty simple to implement. We need to register it using receiver tag in manifest.xml and define its intent-filter (same as we did in activity).



<receiver
      android:name=".IndependentReceiver"  >
     <intent-filter>
         <action android:name="sohail.aziz.r2" />
      </intent-filter>
 </receiver>


Lets define the broadcast receiver itself:



public class IndependentReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        
        int recval = intent.getIntExtra("counter", 0);
        Log.d("sohail", "independentreceiver: broadcast received with counter="+recval);
        
    }

}


Now we can send broadcast to this receiver with action sohail.aziz.r2  e.g
  
  Intent in = new Intent();
  in.setAction("sohail.aziz.r2");
  in.putExtra("counter", 202);
  Log.d("sohail", "onHandleIntent: sending broadcast");
  sendBroadcast(in);



Notice that as we are not unregistered this receiver, so it will continue running throughout the application life.
Browse and Download source BroadcastExample.

Friday 25 May 2012

Broadcast Receiver: Two ways to implement part-1

I got confused while learning about the broadcast receiver after browsing around the web. Some people register it inside activities while other register it in manifest. The purpose of this tutorial is to explain both ways and the use-cases when to use which implementation.

Broadcast receiver is an application component like activity and service. Its sole aim is to listen for broadcast for which it is registered (through intent-filters). Broadcast receiver can receive broadcast from android system, other applications and from inside the application. Read more about broadcast receivers at developer.android.

We can register receiver in manifest.xml or inside an Activity. We should use define and register broadcast receiver inside activity if we want perform action related to activity (e.g updating UI). We should define it in standalone class otherwise.

No matter what your use-case is, Lets see how to implement these two ways. Lets say we have BroadcastExampleActivity and a receiver inside it called Myreceiver:



public class BroadcastExampleActivity extends Activity {
    /** Called when the activity is first created. */
    private Myreceiver reMyreceive;
    private IntentFilter filter;
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        unregisterReceiver(reMyreceive);
     }
     @Override
     protected void onResume() {
        // TODO Auto-generated method stub
         super.onResume();
        
          registerReceiver(reMyreceive, filter);
     } 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Log.d("sohail", "onCreate called");
       
        reMyreceive=new Myreceiver();
       
       //typo mistake 
       //Edited after pointing out by a reader, thanks 
       // IntentFilter filter=new IntentFilter("sohail.aziz");

        filter=new IntentFilter("sohail.aziz");         
       
        Intent i= new Intent(this,MyIntentService.class);
        Log.d("sohail", "starting MyIntentservice");
        startService(i);
    }
    
    public class Myreceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            
            Log.d("sohail", "MyReceiver: broadcast received");
        }
        
    }
} 



Note that while implementing inside activity, receiver should be registered in OnResume() and unregistered in OnPause() in order to "cut down unnecessary system overhead- developer.android". [Otherwise your receiver will continue running even when activity get paused! check example in updated source]. Intenfilter("sohail.aziz") is the action name for which this receiver is listening. Broadcast sender must set the action name for intended recipient. Lets define MyIntentservice which will send the broadcast.



public class MyIntentService extends IntentService{

    public MyIntentService() {
        super("MyIntentService");
        // TODO Auto-generated constructor stub
        
        Log.d("sohail","Myintentservice constructor");
    }

    @Override
    protected void onHandleIntent(Intent arg0) {
        // TODO Auto-generated method stub
        
        Log.d("sohail", "onHandle intent called");
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        Intent in= new Intent();
        in.setAction("sohail.aziz");
        Log.d("sohail", "onHandleIntent: sending broadcast");
        sendBroadcast(in);
     
    
    }

}



Notice that we are sending broadcast here with action "sohail.aziz", this is the same action name for which we set intentfilter in our broadcast receiver. Now when broadcast is sent by sendBroadcast, Myreceiver onReceive will be called and intent will be passed to it. You can pass anything via intent. This way we don't need to register receiver inside manifest.xml as it has become a sub component of the activity.

Second method: Broadcast Receiver: Two ways to implement part-2


Wednesday 23 May 2012

A complete Contentprovider



MyContentProvider
Much have been written about contentproviders and there are various tutorials and examples available. I walk through many of those tutorials during my learning of custom contentprovider. However none of those tutorial gave me complete and clean implementation details.
Aim of this post is to show you a complete [all necessary function implementation] and clean [well organized code for better understading] custom contentprovider.

A contentprovider is primarily designed to use for data sharing between different application. A contentprovider provide a transparent interface for structured data storage. A contentProvider  could be implemented with many different backends like SQLite, file storage or network storage. This tutorial addresses the implementation details of contentProvider implemented with SQLite database.
             

 
Lets start with an example. We have a Category class e.g
public class Category{ 
  String name;
 String status; 
}
We want to insert and get these fields in contentprovider. For this will create a content discriptor for our content provider. Lets say it Mycontentdiscriptor:


public class MyContentDescriptor {

    public static final String AUTHORITY = "sohail.aziz.mycontentprovider";
    private static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
    public static final UriMatcher URI_MATCHER = buildUriMatcher();

    private static UriMatcher buildUriMatcher() {

        // TODO Auto-generated method stub

        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

        // have to add tables uri here

        final String authority = AUTHORITY;

        //adding category Uris

        matcher.addURI(authority, Categories.CAT_PATH, Categories.CAT_PATH_TOKEN);

        matcher.addURI(authority, Categories.CAT_PATH_FOR_ID,Categories.CAT_PATH_FOR_ID_TOKEN);
     
        return matcher;

    }
    public static class Categories {

        // an identifying name for entity

        public static final String TABLE_NAME = "categories/"; 
        // the toke value are used to register path in matcher (see above)
        public static final String CAT_PATH = "categories";
        public static final int CAT_PATH_TOKEN = 100;

        public static final String CAT_PATH_FOR_ID = "categories/#";
        public static final int CAT_PATH_FOR_ID_TOKEN = 200;

        public static final Uri CONTENT_URI = BASE_URI.buildUpon()
                .appendPath(CAT_PATH).build();

        public static class Cols {
            public static final String cat_id = BaseColumns._ID;
            public static final String key_2_catname="name";
            public static final String key_3_catstatus="status";

        }
    }
}

Lets discuss the above code.
Authority: A content provider must have an Authority. Authority string must be included in manifext.xml file in order to use contentprovider. You can define it as you like.
UriMatcher : A uri matcher is used to match the URI's. Uri could be of a table or speceific row (record). For example in our case category table uri is:

content://sohail.aziz.mycontentprovider/categories


while uri for particular record in categories table could be: 


  content://sohail.aziz.mycontentprovider/categories/1



we defined two constants for these two different URI types in order to differentiate while querying.
Cols class is defining the fields of our Category object. First field of every table should be _ID. As its expected while binding to listView.

So far we were defining our content, lets create actual SQLite database to be used as backend with our contentprovider:

public class MyDatabase extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "mydatabase.db";
    private static final int DATABASE_VERSION = 1;

    // custom constructor
    public MyDatabase(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub

        // creating tables categories
        db.execSQL("CREATE TABLE " + MyContentDescriptor.Categories.TABLE_NAME+ " ( "+
                 MyContentDescriptor.Categories.Cols.cat_id+ " INTEGER PRIMARY KEY AUTOINCREMENT,"+
                 MyContentDescriptor.Categories.Cols.key_2_catname    + " TEXT NOT NULL," +
                 MyContentDescriptor.Categories.Cols.key_3_catstatus + " TEXT," +
                "UNIQUE (" + 
                MyContentDescriptor.Categories.Cols.cat_id + 
            ") ON CONFLICT REPLACE)"
                );

    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
         if(oldVersion < newVersion){
                db.execSQL("DROP TABLE IF EXISTS " + MyContentDescriptor.Categories.TABLE_NAME);

            }
    }
}

Here we defined out database name and write sql query for the creation of Categories table. (its not created yet).

Now come to the ContentProvider: We will use both of the above classes in our content provider. You can put all this code in Contentprovider class but its better to keep these separate for organization and readability. Lets create our contentprovider e.g MyContentprovider:


public class MyContentProvider extends ContentProvider {

    private MyDatabase mydb;
    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        Context ctx = getContext();
        mydb = new MyDatabase(ctx);
        return (mydb == null) ? false : true;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
         SQLiteDatabase db = mydb.getWritableDatabase();
         int token = MyContentDescriptor.URI_MATCHER.match(uri);
         int count=0;
        
         switch(token){
         case MyContentDescriptor.Categories.CAT_PATH_TOKEN:
            count= db.delete(MyContentDescriptor.Categories.TABLE_NAME, selection, selectionArgs);
             break;
         }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
  
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub // returning self defined mime types
        // to be used by other applications if any
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub

        Log.d("sohail", "inside insert");
        SQLiteDatabase db = mydb.getWritableDatabase();

        int token = MyContentDescriptor.URI_MATCHER.match(uri);
        switch (token) {
        case MyContentDescriptor.Categories.CAT_PATH_TOKEN: // uri is of
                                                            // categories table
            Log.d("sohail", "matched uri is CAT_PATH_TOKEN:" + uri.toString());
            long id = db.insert(MyContentDescriptor.Categories.TABLE_NAME,
                    null, values);
            // notifying change to content observers
            getContext().getContentResolver().notifyChange(uri, null);
            return MyContentDescriptor.Categories.CONTENT_URI.buildUpon()
                    .appendPath(String.valueOf(id)).build();

        default:
            throw new UnsupportedOperationException("URI: " + uri
                    + " not supported.");
        }
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        Log.d("sohail", "query called");
        SQLiteDatabase db = mydb.getReadableDatabase();
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        Cursor c;
        int token = MyContentDescriptor.URI_MATCHER.match(uri);

        switch (token) {

        case MyContentDescriptor.Categories.CAT_PATH_TOKEN:
            Log.d("sohail", "matched uri is CAT_PATH_TOKEN:" + uri.toString());
            queryBuilder.setTables(MyContentDescriptor.Categories.TABLE_NAME);
            c = queryBuilder.query(db, projection, selection, selectionArgs,
                    null, null, sortOrder);
            return c;

        case MyContentDescriptor.Categories.CAT_PATH_FOR_ID_TOKEN:
            Log.d("sohail", "matched uri is CAT_PATH_TOKEN:" + uri.toString());
            queryBuilder.setTables(MyContentDescriptor.Categories.TABLE_NAME);
            queryBuilder.appendWhere(MyContentDescriptor.Categories.Cols.cat_id
                    + "=" + uri.getLastPathSegment());
            c = queryBuilder.query(db, projection, selection, selectionArgs,
                    null, null, sortOrder);
            return c;

       default:
            Log.d("sohail", "no URI MATCHED");
            return null;
        }

    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
         SQLiteDatabase db = mydb.getWritableDatabase();
         int token = MyContentDescriptor.URI_MATCHER.match(uri);
         int count=0;
        
         switch(token){
         case MyContentDescriptor.Categories.CAT_PATH_TOKEN:
            count= db.update(MyContentDescriptor.Categories.TABLE_NAME,values, selection, selectionArgs);
             break;
            }
        
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
        
    }

}

Mycontentprovider is exented from contentprovider and its methods: Insert,query,delete,update getType needs to be implemented. We create a database db in onCreate. This object is used in insert,query update and delete methods. Uri matcher is used to match the requested URI and on the basis of this uri, query is executed on particular table. (there could be more than one table). db.insert, db.update and db.delete are all sqlite funcitons. SQLite queryBuilder is used to query the specific table as indicated in URI. Results of the query are returned in Cursor object (which in-turn is used to populate UI e.g listView). On each insertion, new id of the inserted row is appended in URI and returned e.g after insertion of 3rth record the returned URI will be:

     content://sohail.aziz.mycontentprovider/categories/3



this URI can be used to query the 3rd record (row) in categories table. Notice one thing that after insert, delete and update operation
getContext().getContentResolver().notifyChange(uri, null); is called. This notifies the content observers that the particular table has been modified. Thats all for the implementation of the contentprovider. Lets see how can we use it in our activity. Lets say we have two edit text and a check box named etID, etName and cbStatus.
private void InsertRecords() {
  // TODO Auto-generated method stub
  ContentValues conval=new ContentValues();
  conval.put(MyContentDescriptor.Categories.Cols.key_1_catid, etID.getText().toString() );
  conval.put(MyContentDescriptor.Categories.Cols.key_2_catname, etNAME.getText().toString());
  
  String stat;
  if(cbStatus.isChecked())
   stat="true";
  else
   stat="false";
  
  conval.put(MyContentDescriptor.Categories.Cols.key_3_catstatus,stat);
  recent_uri=getContentResolver().insert(MyContentDescriptor.Categories.CONTENT_URI, conval);
  Log.d("sohail","returned uri="+recent_uri);
  //showRecords();
  
 }
private void showRecords() {
  // TODO Auto-generated method stub
  
   cur= this.getContentResolver().query(MyContentDescriptor.Categories.CONTENT_URI, null, null,null, null);
  
  String[] colums=new String[]{MyContentDescriptor.Categories.Cols.key_1_catid,MyContentDescriptor.Categories.Cols.key_2_catname};
  //adapter= new SimpleCursorAdapter(this,android.l)
   int[] to = new int[] { R.id.tvID, R.id.tvNAME };
   
   adapter = new SimpleCursorAdapter(this, R.layout.list_item, cur, colums, to);

   listview.setAdapter(adapter);
  
   
 } 
private void deleteAll() {
  // TODO Auto-generated method stub
  getContentResolver().delete(MyContentDescriptor.Categories.CONTENT_URI, null, null);
 }
private void showRecent() {
  // TODO Auto-generated method stub
  Cursor cur2= this.getContentResolver().query(recent_uri, null, null,null, null);
  adapter.changeCursor(cur2);  
  
 }
private void showchecked() {
  // TODO Auto-generated method stub
  boolean status=true;
  String colname=MyContentDescriptor.Categories.Cols.key_3_catstatus;
  Uri uri= MyContentDescriptor.Categories.CONTENT_URI;
  String selection= MyContentDescriptor.Categories.Cols.key_3_catstatus+"=?";
  Cursor cur3=getContentResolver().query(uri, null,selection, new String[]{"true"}, null);
  Log.d("sohail",cur3.toString());
  
  adapter.changeCursor(cur3);
  
  
  } 

Functions Description:
Insert: to insert new record.
showRecords: to show all records of categories table.
showRecent: to show the recently inserted record.
showChecked:to show all records where status=true.
deleteAll: to delete all records from categories table.

Browse and download source
MyContentProviderExample.

*Update* : Content provider does not provide synchronization by default, which means there can be synchronization issues if content provider is accessed (insert/update) from many threads/apps at once. However Sqlite does provide the synchronization. You need not to do anything if your ContentProvider is backed by Sqlite database. For detail explanation read SQLite, ContentProviders, and Thread Safety.

Tuesday 22 May 2012

https hijacking! How to protect yourself?

Sorry for being late, I was out of the town for few days. Lets start from where we left. As we discussed in previous post, People surfing the web even over https connections are not safe. In today’s post I’d explain how we can protect ourselves from potential https hijacking with little security consciousness.
All major browsers (IE, Firefox, Chrome, Opera) come with the major certificate authorities certificates (CAs) pre-installed. You can view these certificate authorities i.e for firefox some versions:go to
Edit -> Preferences -> Advanced -> Encryption -> View Certificates -> Authorities.
This means your browser already trust VeriSign, DigiNotar, Thawte etc and any website having its certificate signed by these CAs is considered safe and trusted (because CA only issued certificates after verifying their identity). Thats why all well-know websites get certificates from these CAs e.g google from Thawte, twitter from VeriSign etc. We can assume that whenever there is https certificate from untrusted CA there are more chances that this could be a hijacked connection or the website it-self is a malicious website.
Now what we can do as security conscious e-user is: to simply reject no-secure untrusted https connections. This is the best and ONLY way to protect yourself in cyber world.
So how can we identify whether the site’s certificate is trusted or not ? Very simple, All major web-browsers show a security warning whenever we visit a (https enabled) website with untrusted certificate (whose issuer is not in our (browser) CA list). What we should do is, not continue surfing that particular website. Here is how firefox shows warning whenever we visit untrusted site.



checking the details shows you the reason for untrust e.g issuer not trusted other reasons could be “certificate expire”



You can check the certificate itself and its issuer by clicking add exception:



Get the certificate and check its issuer.



DON’T confirm security exception, this will cause that certificate a trusted one and your browser won’t complain any more.
Note: I deliberately delete thawte SSL CA from browser CA list in order to produce these warnings. imo.im is not malicious :)

https:// Are you really protected ?

Myth: If I am using https:// enabled site, all my communication is secure and no one can intercept and understand in-between.
This is a very popular myth. As technology gets-into our lives, we start relying on it. We use internet not only on PCs and desktops but also on Tablets and Mobiles. We use it for our daily lives, for simple ordinary search to social e-gatherings, for simple email to online banking. It has become an important media for our daily mundane tasks.
As we are using it:
  • Is it really secure?
  • Can we use it without the sacrificing our privacy?
  • Can we be confident about the confidentiality of our personal information?
  • Are we really protected against e-theft?
Military and defense organizations all over the world, employs various means to secure their communications.I am writing this for the general public. For those,who are not as important as Top Military Officers but they do care about their PRIVACY:
  • For those who want their privacy be respected while online.
  • For those who want their usernames/passwords to be secret.
  • For those who are conscious about their e-transactions.
There is no doubt that https:// has become de-facto standard for secure web browsing. Its used by all security sensitive web sites. You can see it working while using gmail, hotmail, yahoo etc. It do provide a mechanism for encrypted communication between user’s browser and website.You can read more about the functionality of https in my previous article https:// what it is?
Today I’ll try to explain the scenarios when an https:// enabled communications be intercepted and understood.First of all there should be no doubt that your communication with a website can be intercepted. It can be intercepted at your local LAN, at your ISP, and at any location between you and the website. However eavesdropper(interceptor) will not be able to get anything out of it as everything is encrypted with strong enough algorithm.
Now come to the point. Then, how https:// can be insecure?I my last tutorial about functionality of https://, I have talked about the certificates. Which are used to encrypt everything between website and web browser. Now lets see how an eavesdropper can intercept and decrypt your communications:




Lets explain the steps quickly:
  1. User request a website e.g www.gmail.com
  2. Attacker is in-between, let the request go to gmail
  3. gmail respond with its certificate, attacker keep that certificate, send user his/her own certificate
  4. User browser shows a warning to accept certificate
  5. If user accept, all communication between user and attacker will be encrypted but with ATTACKER’s certificate
  6. Attacker decrypt the traffic and encrypt again with google’s certificate and forward the request to google
  7. This way attacker just encrypt and decrypt between user and google (site) which is transparent to both user and google site.
Have a question? ask!
Very soon, Next post: how to protect yourself from https:// hijacking.

https:// what it is ?

Https is way of securing http(web) traffic. There are many versions of establishing encrypted http connection but we will discuss here only the simplest one, used by most of the web sites running on https. Examples of these can by encrypted.google.com , gmail.com etc. Whenever there is an https (encrypted connection) you will notice https:// in the address bar of the browser.


There are two main purpose of generally used https:


  1.  Privacy: Providing encrypted traffic between client application (web browser) and the server application (web server) so that  no one can understand the content if he/she intercepts in-between.
  2. Authenticity: Guaranteeing the user that he/she is  connected with the genuine web server (no the fake one) .  




Lets understand how is this achieved in web browser-to-website communication.


Every well know web applications/web sites/ email applications get a SSL certificates from well known Certificate Authorities(CA) These certificate authorities are companies who issue Certificates after verifying the presented identity of the website's company. This information may include the address,emails,national id cards,phone no and other information of the site owner. In other words Certificate authorities certify that the web site is valid/genuine and its identity is verified.


There are many well known (trusted) Certificate Authorities (CA) like VeriSign Inc, DigiNotar, thawte, Inc etc. All web-browser come shipped with the certificates of these CAs.


No lets see what happens when web-browser request a https enabled website e.g gmail.com:
  1.  Client web browser send request to gmail.com on plain http.
  2. gmail.com replied with the its ssl-certificate and ask for secure connection (https).
  3.  Client web browser checks whether the issuer of this certificate exists in my list of trusted CAs.
  4.  If issuer is there , https connection established otherwise user is presented with the security warning (firefox).




Once the https connection is established, all the traffic from client (browser) to server (website) is encrypted and cannot be read/understood if intercepted in between. And user has guarantee that he/she is connected with the genuine website (no fake).


PS: You can check the list of CAs in your browser, in firefox , go to edit->Prefrences or tools->Prefrences  then Advanced->Encryption->View Certificates there you can see the list of trusted Certificates and Certificate Authorities.

Thursday 26 April 2012

LocalBroadcastManager: Intra application message passing

Using Broadcast receivers is good practice if you want to send and receive data between different applications. However its not good at all if you are using them for communication internal to application.


There are many reasons for NOT using broadcast:
  1.  A broadcast is sent system-wide, so this is not performance efficient.
  2.  When we use broadcast receiver and sender, any other application can send and receives broadcast messages to and from our application. This can be a serious security thread for our application.


Read more about security issues and configuration of broadcast at developer.android
Instead of using normal broadcast we should use Local broadcast for sending and receiving in-app messages between activities and services. Local broadcast is included in android 3.0 and is provided as support package v4 for early release development. For setting up support library read developer.android


ResultReceiver can be used to return data back to activity. Here is a simple IntentService: Providing data back to Activity #android .However by ResultRceiver, we can only return data to that specific activity which started the service.


To send data/intent application-wide, LocalBroadcasts should be used. LocalBroadcastManager is used to send and receive local broadcast. Lets start with a simple example. We have a simple IntentService say MyIntentService:

package sohail.aziz.mylocalbroadcast;

import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

public class MyIntentService extends IntentService{

//ACTION should include application package convention, just to show that this can
//be any string
    public static final String ACTION="mycustomactionstring";
    
    public MyIntentService() {
        super("MyIntentService");
        // TODO Auto-generated constructor stub
       Log.d("sohail","service started");
    }

    @Override
    protected void onHandleIntent(Intent arg0) {
        // TODO Auto-generated method stub
        
        Log.d("sohail","onHandleIntent called");
        Intent in=new Intent(ACTION);  //you can put anything in it with putExtra
        Log.d("sohail","sending broadcast");
        LocalBroadcastManager.getInstance(this).sendBroadcast(in);
        
        
    }

}


A simple IntentService which sends local broadcast application-wide. Lets receive this in activity.
package sohail.aziz.mylocalbroadcast;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MylocalbroadcastExampleActivity extends Activity implements OnClickListener{
    /** Called when the activity is first created. */
       
    TextView tv;
    Button bt;
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        
        LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
    }
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        
        IntentFilter iff= new IntentFilter(MyIntentService.ACTION);
        LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, iff);
    }
    
    private BroadcastReceiver onNotice= new BroadcastReceiver() {
        
        @Override
        public void onReceive(Context context, Intent intent) {
            // intent can contain anydata
            Log.d("sohail","onReceive called");
            tv.setText("Broadcast received !");
        
        }
    };
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tv=(TextView)findViewById(R.id.tvResults);
        
        bt= (Button)findViewById(R.id.btStart);
        bt.setOnClickListener(this);
        
    }
    @Override
    public void onClick(View v) {
        
        if(v.getId()==R.id.btStart){
            
            Log.d("sohail","starting service");
            Intent i= new Intent(this, MyIntentService.class);
            startService(i);
        }
    }
}

Here we are registering broadcast receiver onNotice as LocalBroadcast Receiver. Intent-filter is defined with ACTION defined in MyIntentService.


You just need to define service in AndroidManifest.xml:
 <service
 android:name=".MyIntentService" 
 ></service>

and thats it !
 
Browse and download source MyLocalbroadcastManager.

Sunday 22 April 2012

IntentService: Providing data back to Activity #android

It is advisable to use thread/asynTask or Service to handle long running task such as file I/O, internet access etc. IntentService is simple, easy to use and take care of many hectic tasks for You.Read more about IntentService at
developer.android . A simple use case of the topic can be:
  1. Your activity send a web request to IntentService to process.
  2.  Your IntentService execute that request using DefaultHttpClient.
  3.  And Return results (whatever, true,false list of objects/records etc) back to the calling activity.
Now the task is to return the results back to the activity. There are two options available either we can use Broadcast receiver or ResultReceiver.
  • Broadcast should be used if you want to send data/notifications across applications, whenever you send broadcast its sent system wide read more about broadcast receivers at developer.android.
  •  Result receiver is an interface you implement and pass it to the intentService through putExtra. IntentService then fetch this object and call its receiver.send function to send anything (in bundle) to calling activity[who started the intentservice]. Result receiver has preference over broadcast receivers if your all communication is internal to your application.

Lets start, First we need to have our own receiver class extended from ResultReceiver and containing Receiver Interface. Lets say its MyResultReceiver:

package sohail.aziz.service;

import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;

public class MyResultReceiver extends ResultReceiver {

    private Receiver mReceiver;

    public MyResultReceiver(Handler handler) {
        super(handler);
        // TODO Auto-generated constructor stub
    }

    public interface Receiver {
        public void onReceiveResult(int resultCode, Bundle resultData);

    }

    public void setReceiver(Receiver receiver) {
        mReceiver = receiver;
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {

        if (mReceiver != null) {
            mReceiver.onReceiveResult(resultCode, resultData);
        }
    }

}



Now we implements Receiver interface [defined in MyResultReceiver] in our Activity. Lets say this LoginActivity :

package sohail.aziz.view;
import sohail.aziz.service.MyResultReceiver;
import sohail.aziz.service.MyIntentService;
import sohail.aziz.service.MyResultReceiver.Receiver;


public class LoginActivity extends Activity implements OnClickListener,Receiver {
        Button btLogin;   
        Public MyResultReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);

        btLogin = (Button) findViewById(R.id.btLogin);
        mReceiver = new MyResultReceiver(new Handler());

        mReceiver.setReceiver(this);
        btLogin.setOnClickListener(this);
        
    }

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
                 
             if(arg0.getId()==R.id.btLogin){
                  Intent i = new Intent(this, MyIntentService.class);
                  i.putExtra("nameTag","sohail" );
                  i.putExtra("receiverTag", mReceiver);
                  startService(i);
               
              }


    }
    
    @Override
    public void onReceiveResult(int resultCode, Bundle resultData) {
        // TODO Auto-generated method stub
        
                 Log.d("sohail","received result from Service="+resultData.getString("ServiceTag"));

    }
}




And here is the MyService class :

import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.Log;

public class MyIntentService extends IntentService {

    
    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // TODO Auto-generated method stub

        
        ResultReceiver rec = intent.getParcelableExtra("receiverTag");
                String recName= intent.getString("nameTag");
                Log.d("sohail","received name="+recName);

        Log.d("sohail","sending data back to activity");

                Bundle b= new Bundle();
                b.putString("ServiceTag","aziz");
        rec.send(0, b);
    }

}



Whenever we call startService , intentService is started if its not been running, and if its already running it put our (new)request in a queue and execute it when it finishes running request. When we call rec.send() , onReceiveResult is called and the value we passed in bundle is received in the activity.


Is it helpful for you?

Wednesday 18 April 2012

Custom adapter for ListView #android beginners

PRE:You must be familiar with simple list view/spinner and simpleAdapter.
 
By default listView only accepts a simple adapter with array of strings. However listView control be customized as you wish. Take a look of various listView use cases The world of listView Google I/O.

We can add custom controls like TextViews, buttons, images etc and make them clickable individually or as a whole. The use case can be a custom class fields you want to display in single row.



To make a listView OUR listView, We need to:
  1.  Create a main xml layout file with a ListView control placed in.
  2.  Create an xml layout which will be used to display one row of the list.
  3.  Create a custom adapter class extended from baseAdapter, and overrid its getView method

So lets define our main layout main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/contactsListViewMain"
      />
        
 </LinearLayout>

 and another layout which will be used to display one row of listView, say rowitem.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <TextView
        android:id="@+id/contactname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:background="@color/FloralWhite"        
        android:textColor="@color/Black"
        />
    <TextView
        android:id="@+id/contactnum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/LightYellow"
        android:textColor="@color/Gray"
        />
</LinearLayout>


Lets say we want to display Contact Name and Number as one record in listView. A simple Contact class can be:

public class Contact {
         private String contactName;
        private String contactNum;

        Contact(String name,String num){
            this.contactName=name;
            this.contactNum=num;
        }
        public String getContactName() {
            return contactName;
        }
        public void setContactName(String contactName) {
            this.contactName = contactName;
        }

        public String getContactNum() {
            return contactNum;
        }
        public void setContactNum(String contactNum) {
            this.contactNum = contactName;
        }

}

Now the interesting part here we will bind the contact class fields with the rowitem.xml controls. Lets make OUR adapter

public class ContactAdapter extends BaseAdapter{

    Context mycontext;
    ArrayList<Contact> contactsList;
    LayoutInflater mInflater;
    
     public ContactAdapter(Context context, ArrayList<Contact> list) {
          
         this.mycontext=context;
         contactsList = list;
         mInflater = LayoutInflater.from(context);
        
     }
    
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        ContactViewHolder viewHolder;
        
        if(convertView==null){
        
            convertView= mInflater.inflate(R.layout.rowitem, parent,false);
            
            viewHolder= new ContactViewHolder();
            viewHolder.name= (TextView) convertView.findViewById(R.id.contactname);
            viewHolder.number=(TextView)convertView.findViewById(R.id.contactnum);
            convertView.setTag(viewHolder);
        }
        else
        {
            viewHolder=(ContactViewHolder) convertView.getTag();
        }
        
        Contact cont=(Contact) contactsList.get(position);
        
        viewHolder.name.setText(cont.getContactName());
        viewHolder.number.setText(cont.getContactNum());
        
        return convertView; 
        
    }

    
static class ContactViewHolder{
    
    TextView name;
    TextView number;
}


@Override
public int getCount() {
    // TODO Auto-generated method stub
    //return 0;
    
    return contactsList.size();
}


@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    //return null;
    return contactsList.get(position);
}


@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}
    
    
}

Note: Note that rowitem.xml is inflated in getView and these controls are populated with the contact object's fields. We can place as many controls in rowitem.xml and in any order/layout we want and bind them with our custom object's fields.


Next we just need to create a list of custom objects [Contact] and create our adapter and set this adapter to listView. Lets say we want to display list on our starting Activity's onCreate method:

 setContentView(R.layout.main);

///creating a sample list of contacts with name and number
 ArrayList<Contact> list = new ArrayList<Contact>();
  list.add(new Contact("sohail", "11111"));
  list.add(new Contact("aziz", "122222"));
  list.add(new Contact("hassan", "33333333"));

//listView control
ListView mylistview= (ListView)findViewById(R.id.contactsListViewMain);

//here we are creating our custom adapter defined above
ContactAdapter contadapter= new ContactAdapter(this, list);

//setting listView adapter
mylistview.setAdapter(contadapter);


Thats it! One row of listView will show two items , name and number. You can change their font, color, style, alignment etc.


Download complete source contactEmail.


 Is it helpful ? Your feedback is welcomed.