Search This Blog

Friday, December 18, 2009

WhitePage Application_Adding a new contact in Android 2.0

Actually i was gonna talk about HTML parsing mechanism which i used for my Whitepages application,but i thought it wouldn't be such a good idea to talk about it on this weblog since it has nothing to do with android and I just did it to fulfill my curiosity. the only thing we need to know is how to make our query which in this case was a simple GET query and then identify how data is wrapped inside HTML tags which can be easily done thanks to FireBug plugin, the rest will be some effort to figure out a good algorithm to extract data from HTML document as efficient as possible...
What i would like to talk about in this post is Contacts in android and how to add a new Contact to Android's Contact List. Initially i thought it was gonna be a simple thing to do but i gotta admit it, it was the first time i felt
a bit confused since I started android development. what happened was i wanted to write a piece of code to add a new contact when user selects one of our application menu options, I went to Android developers website(like i usually do) to find some clues on how to do that... as you might have already noticed there are some examples in Content Providers section about how to work with Contacts using People class, good, i was pretty sure that i got it... but when i started coding,Eclipse warned me that People class was deprecated... Beautiful!!!so what am i supposed to do if i shouldn't use People class, I was thinking with myself... having a look at People class documentation I found out that it's been replaced by a totally different mechanism and we should use another class called ContractsContact to interact with Contacts...
one of the things that struck me was the fact that there are more than two dozens classes and interfaces in android.provider package marked as deprecated and a completely different approach has been introduced for interacting with contracts since API level 5. this new API gives you a great level of flexibility and extensibility but as we all know everything has a price, if you want a flexible and extensible framework, no worries, but it comes with a bit more complexity, and I think it could be why they still prefer to stick with People class examples... ;)
Fair enough, here is the code that i used in our application to add a new Contact according to what user has already selected :



try{


ArrayList op_list = new ArrayList();
int backRefIndex = 0;
op_list.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, null)
.withValue(RawContacts.ACCOUNT_NAME, null)
.build());

op_list.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, backRefIndex)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME, this.selectedItem.getName())
.build());

op_list.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, backRefIndex)
.withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE)
.withValue(StructuredPostal.FORMATTED_ADDRESS, this.selectedItem.getAddress())
.build());

op_list.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, backRefIndex)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, this.selectedItem.getPhone())
.withValue(Phone.TYPE, Phone.TYPE_HOME)
.withValue(Phone.LABEL, "")
.build());

ContentProviderResult[] result = getContentResolver().applyBatch(ContactsContract.AUTHORITY, op_list);


}catch(OperationApplicationException exp){

exp.printStackTrace();

}catch(RemoteException exp){

exp.printStackTrace();
}



dont freak out ;) , although it might seem quite different than what you are familiar with, it's mostly because i used Batch insert technique and ContentProviderOperation.Builder class which have been introduced in API level 5.
you can still use getContentResolver().insert() and ContentValue objects but it is recommended to use new batch technique over traditional insert and update method.
what is important here is that you first need to create a RawContact and then use its ID to add some data like name, phone number and address, in traditional method you would need to insert a RawContact, get its ID and then use that ID in subsequent operations, I used withValueBackReference() method here which has been provided for handling these sort of cases when you are using batch technique.
You can find some good information about this whole thing in Data class documentation.








5 comments:

Anonymous said...

Thank you so much!

I've been googling for hours to find a way to add contacts "the new way". This works like a gem!

Anonymous said...

Very nice post. Short and clear.
Its difficult to find a working tutorial
with the ContentProviderOperation in the web...

puneeth khanna sakshi said...

Thank you bro ... its very usefull to me ..

Prabhakar said...

Hello Amir,

Your posting has solved my problem of adding a new Contact.

Thanks for the post.
Keep Blogging.

Anonymous said...

When we create contact using this code then it working fine for single contact.
But when we create multiple contact with same fields then first contact override with second contact.
But if we create multiple contacts with same fields from emulator then it create multiple contacts not override with each other.