Programatically adding contacts with photo using Contacts Provider in Android – Example

September 25, 2012
By

In this article, we will create an Android application which allows a user to add new contacts along with photo to the Android’s Contact Manager. Android’s Contacts Content Provider API is used to add the contacts to the Contact Manager.

This article is an extension to the article “Adding contacts programatically using Contacts Provider in Android – Example

This application is developed in Eclipse ( 4.2.0 ) with ADT plugin ( 20.0.3 ) and Android SDK ( R20.0.3 ).


1. Create a new Android application project namely “ContactsAddWithPhoto”

Create a new Android application Project

Figure 1 : Create a new Android application Project


2. Design application launcher icon

Design application launcher icon

Figure 2 : Design application launcher icon


3. Create a blank activity to define the class MainActivity

Create a blank activity

Figure 3 : Create a blank activity


4. Enter MainActivity details

Enter MainActivity Details

Figure 4 : Enter MainActivity Details


5. Delete Android’s backward compatibility support library from this project, if exists

By default Eclipse ( 4.2.0) adds Android Support Library to  Android application project. For this application, we don’t need to use this support library. So the library file libs/android-support-v4.jar may be removed manually via ProjectExplorer by simply right click on the file and then clicking the menu item “delete”.


6. Update the file res/values/strings.xml


<resources>
    <string name="app_name">ContactsAddWithPhoto</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">Add Contacts with Photo</string>

    <string name="hnt_et_name">Display Name</string>
    <string name="hnt_et_mobile">Mobile Phone</string>
    <string name="str_photo">Photo</string>
    <string name="str_btn_add">Add Contact</string>
    <string name="str_btn_list">Contacts List</string>
</resources>


7. Update the file res/values/styles.xml

<resources>
    <style name="AppTheme" parent="android:Theme" />
</resources>

8. Update the file res/values-v11/styles.xml

<resources>
    <style name="AppTheme" parent="android:Theme.Holo" />
</resources>

9. Update the file res/values-v14/styles.xml


<resources>
    <style name="AppTheme" parent="android:Theme.Holo" />
</resources>

10.Update the layout file res/layout/activity_main.xml


<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <EditText
            android:id="@+id/et_name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:inputType="textCapWords"
            android:hint="@string/hnt_et_name" />

        <EditText
            android:id="@+id/et_mobile"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:inputType="phone"
            android:layout_below="@id/et_name"
            android:hint="@string/hnt_et_mobile" />

        <ImageButton
            android:id="@+id/ib_photo"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:scaleType="fitCenter"
            android:layout_centerHorizontal="true"
            android:contentDescription="@string/str_photo"
            android:src="@android:drawable/picture_frame"
            android:layout_below="@id/et_mobile" />

        <Button
            android:id="@+id/btn_add"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/ib_photo"
            android:text="@string/str_btn_add" />

        <Button
            android:id="@+id/btn_list"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/btn_add"
            android:text="@string/str_btn_list" />

    </RelativeLayout>
</ScrollView>

11. Update the class MainActivity in the file src/in/wptrafficanalyzer/contactsaddwithphoto/MainActivity.java


package in.wptrafficanalyzer.contactsaddwithphoto;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.RawContacts;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;

public class MainActivity extends Activity {
    private final int PICK_PHOTO = 1;

    Bitmap mBitmap;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Defining OnClick listener for the photo
        OnClickListener photoClickListener = new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType("image/*");
                startActivityForResult(intent, PICK_PHOTO);
            }
        };

        // Defining OnClick listener for the Add Contact Button
        OnClickListener addClickListener = new OnClickListener() {

            @Override
            public void onClick(View v) {

                // Getting reference to Name EditText
                EditText etName = (EditText) findViewById(R.id.et_name);

                // Getting reference to Mobile EditText
                EditText etMobile = (EditText) findViewById(R.id.et_mobile);

                ArrayList<ContentProviderOperation> ops =
                        new ArrayList<ContentProviderOperation>();

                int rawContactID = ops.size();

                // Adding insert operation to operations list
                // to insert a new raw contact in the table ContactsContract.RawContacts
                ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                        .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
                        .withValue(RawContacts.ACCOUNT_NAME, null)
                        .build());

                // Adding insert operation to operations list
                // to insert display name in the table ContactsContract.Data
                ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
                        .withValue(ContactsContract.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
                        .withValue(StructuredName.DISPLAY_NAME, etName.getText().toString())
                        .build());

                // Adding insert operation to operations list
                // to insert Mobile Number in the table ContactsContract.Data
                ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
                        .withValue(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
                        .withValue(Phone.NUMBER, etMobile.getText().toString())
                        .withValue(Phone.TYPE, CommonDataKinds.Phone.TYPE_MOBILE)
                        .build());

                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                if(mBitmap!=null){    // If an image is selected successfully
                    mBitmap.compress(Bitmap.CompressFormat.PNG , 75, stream);

                    // Adding insert operation to operations list
                    // to insert Photo in the table ContactsContract.Data
                    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
                            .withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
                            .withValue(ContactsContract.Data.MIMETYPE,Photo.CONTENT_ITEM_TYPE)
                            .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO,stream.toByteArray())
                            .build());

                    try {
                        stream.flush();
                    }catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                try{
                    // Executing all the insert operations as a single database transaction
                    getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
                    Toast.makeText(getBaseContext(), "Contact is successfully added", Toast.LENGTH_SHORT).show();
                }catch (RemoteException e) {
                    e.printStackTrace();
                }catch (OperationApplicationException e) {
                    e.printStackTrace();
                }
            }
        };

        // Creating a button click listener for the "Add Contact" button
        OnClickListener contactsClickListener = new OnClickListener() {

            @Override
            public void onClick(View v) {
                // Creating an intent to open Android's Contacts List
                Intent contacts = new Intent(Intent.ACTION_VIEW,ContactsContract.Contacts.CONTENT_URI);

                // Starting the activity
                startActivity(contacts);
             }
        };

         // Getting reference to ImageView
        ImageButton ibPhoto = (ImageButton) findViewById(R.id.ib_photo);

        // Getting Reference to Add Contact Button
        Button btnAdd = (Button) findViewById(R.id.btn_add);

        // Getting Reference to Contact List Button
        Button btnList = (Button) findViewById(R.id.btn_list);

        // Setting OnClick Listener for the photo
        ibPhoto.setOnClickListener(photoClickListener);

        // Setting OnClick Listener of the Add Contact button
        btnAdd.setOnClickListener(addClickListener);

        // Setting OnClick Listener for the Contacts List button
        btnList.setOnClickListener(contactsClickListener);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch(requestCode) {
            case PICK_PHOTO:
                if(resultCode == RESULT_OK){
                    // Getting the uri of the picked photo
                    Uri selectedImage = data.getData();

                    InputStream imageStream = null;
                    try {
                        // Getting InputStream of the selected image
                        imageStream = getContentResolver().openInputStream(selectedImage);
                    } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }

                // Creating bitmap of the selected image from its inputstream
                mBitmap = BitmapFactory.decodeStream(imageStream);

                // Getting reference to ImageView
                ImageButton ibPhoto = (ImageButton) findViewById(R.id.ib_photo);

                // Setting Bitmap to ImageButton
                ibPhoto.setImageBitmap(mBitmap);
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

12. Update the file AndroidManifest.xml to provide the necessary permissions

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.wptrafficanalyzer.contactsaddwithphoto"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="5"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

13. Screenshots of the application

Picking up an image from Android's Gallery

Figure 5 : Picking up an image from Android's Gallery

Creating a contact with the photo picked up from Gallery

Figure 6 : Creating a contact with the photo picked up from Android's Gallery

Viewing the above created contact in Android's Contact Manager

Figure 7 : Viewing the above created contact in Android's Contact Manager


14. Download


15. Reference

http://developer.android.com/guide/index.html


How to hire me?

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in

You can hire me on hourly basis or on project basis for Android applications development.

For hiring me, please mail your requirements to info@wptrafficanalyzer.in.

My other blogs
store4js.blogspot.com


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: ,

9 Responses to Programatically adding contacts with photo using Contacts Provider in Android – Example

  1. rajalakshmi on December 20, 2012 at 5:48 pm

    Hi, Your code is excellent. Its working fine. Let me know how to get native contact id after inserting the contact

  2. comp on February 1, 2013 at 8:19 pm

    hey!
    I am not able to add the contact after choosing the photo.
    it works fine without selecting the pic. could you please tell me what the problem is?
    Also, since the ‘Contact list’ directs you to the app in android,which shows all contacts in phone, if want to show only the contacts from this app and not all the the contacts in the phone, how do i do that?

  3. daffabs on February 18, 2013 at 1:00 am

    Hi! May I ask what is wrong with these two codes and how to fix it:

    .withValue(Phone.TIMES_CONTACTED,
    etTimesContacted.getText().toString())

    .withValue(Phone.TYPE, Phone.TYPE_MOBILE)

    AND

    .withValue(Phone.LAST_TIME_CONTACTED, etLastTimeContacted.getText().toString())

    .withValue(Phone.TYPE, Phone.TYPE_MOBILE)

    thank you for your code it helps me alot and also thank you in advance for your answer

  4. Deepankar Baghel on May 2, 2013 at 4:15 pm

    Nice tutorial…working great…Keep this good work it help people a lot.Thanks

  5. Sankaran on May 13, 2013 at 10:48 am

    Hi sir, i want to list contacts with checkbox and after that want to handle selected items .. can anyone help me thank you..

  6. Saravanan on February 4, 2015 at 6:09 pm

    Hi Sir,

    Update the contact with Account Name and Type with Settings.UNGROUPED_VISIBLE
    (like whatsapp shows in contact)

    Thanks

  7. Binil S on November 18, 2015 at 11:52 am

    Thanks for your code. But when I try to add contacts with photo it is not adding.Without any photo the contact is addding successfully.

  8. Jossa Saul on March 14, 2016 at 7:54 pm

    Hi Sir. I’ve seen your tutorial and tried it. I’m having a problem in this line of code
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
    }
    }
    the error is the “activity_main”. How is that?

  9. Josh Mangsat on March 14, 2016 at 7:55 pm

    Hi Sir. I’ve seen your tutorial and tried it. I’m having a problem in this line of code
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
    }
    }
    the error is the “activity_main”. How is that?

Leave a Reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner