Store and retrieve Android contacts photo


Android default contacts are, basically, a database for store and retrieve phone contacts info. Here a short snippets showing a way to store and retrieve the photo of the contacts. Android contacts store photo in two format, large and thumbnail with two different way for retrieve it.



Official Android documentation report example only for retrieve contact photo. In case of larger photo version the code is basically the same but for thumbnail mode I prefer to refer to raw_contact_id instead of contact_id as official example do. This because, based to the documentation, contact_id for the same contact can change after a sink operation. On the contrary raw_contact_id should remain the same (but I'm not sure about it, if someone have better info, please, report in the comment of this post). Anyway is not so important, if you prefer to use the contact_id value get the official example code here.

public Bitmap GetContactPhoto(long RawContactID, boolean Thumbnail)
{
    ContentResolver cr = m_ActivityInstance.getContentResolver();
    Bitmap Photo = null;

    if(Thumbnail == true)
    {
        Cursor DataCur;

        DataCur = cr.query(ContactsContract.Data.CONTENT_URI,
                           new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO },
                           ContactsContract.Data.RAW_CONTACT_ID + " =? AND " + ContactsContract.Data.MIMETYPE + " =?",
                           new String[] { String.valueOf(RawContactID), ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE },
                           null
                           );

        if(DataCur != null)
        {
            if(DataCur.getCount() > 0)
            {
                DataCur.moveToFirst();
                byte[] PhotoData = DataCur.getBlob(0);
                if(PhotoData != null)
                {
                    ByteArrayInputStream BmpStream = new ByteArrayInputStream(PhotoData);
                    Photo = BitmapFactory.decodeStream(BmpStream);
                    try
                    {
                        BmpStream.close();
                    }
                    catch(IOException e)
                    {
                        Photo = null;
                    }
                }
            }
            DataCur.close();
        }
    }
    else
    {
        Uri RawContactPhotoUri = Uri.withAppendedPath(
                ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, RawContactID),
                ContactsContract.RawContacts.DisplayPhoto.CONTENT_DIRECTORY
                );

        try
        {
            AssetFileDescriptor fd = cr.openAssetFileDescriptor(RawContactPhotoUri, "r");
            InputStream os = fd.createInputStream();
            Photo = BitmapFactory.decodeStream(os);
            os.close();
            fd.close();
        }
        catch(IOException e)
        {
            Photo = null;
        }
    }

    return Photo;
}

The code for store contact photo is the following. Please note here only a single store operation was done and doesn't matter the original size of your photo, the system will automatically resize the photo in both formats, large and thumbnail, ans store each in the correct position to be retrieved with the first function here reported.

public boolean SetContactPhoto(long RawContactID, Bitmap Photo)
{
    ByteArrayOutputStream BmpStream = new ByteArrayOutputStream();
    ContentResolver cr = m_ActivityInstance.getContentResolver();
    Uri RawContactPhotoUri;

    RawContactPhotoUri = Uri.withAppendedPath(
                ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, RawContactID),
                ContactsContract.RawContacts.DisplayPhoto.CONTENT_DIRECTORY
                );

    Photo.compress(Bitmap.CompressFormat.JPEG , 100, BmpStream);

    try
    {
        AssetFileDescriptor fd = cr.openAssetFileDescriptor(RawContactPhotoUri, "rw");
        OutputStream os = fd.createOutputStream();
        os.write(BmpStream.toByteArray());
        os.close();
        fd.close();
    }
    catch(IOException e)
    {
        return false;
    }

    return true;
}

This code is working for me, however if someone know a better way or have something incorrect to report about these snippets please feel free to signal through comments.

Comments

Popular posts from this blog

Access GPIO from Linux user space

Android: adb push and read-only file system error

Tree in SQL database: The Nested Set Model