Question

I am trying to display a contact image in my listview and my code has worked until I discovered users on the nexus 5 couldn't see their contacts images. I did more testing and found that the issue persisted more and more in KitKat (4.4). I took the code for showing contacts from this link.Using code from Google developer website I cannot get the contact images to display.

The code is in the link. How I can get the contact image to display in KitKat and other versions?

Here is the links I have looked at in other questions.

How to query Android MediaStore Content Provider, avoiding orphaned images?

Get/pick an image from Android's built-in Gallery app programmatically

Get real path from URI, Android KitKat new storage access framework

Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT

Was it helpful?

Solution 2

I fixed the issue by changing the method below. I removed the AssetFileDescriptor and used a InputStream instead. This was in another question and works with my code.

/**
 * Decodes and scales a contact's image from a file pointed to by a Uri in the contact's data,
 * and returns the result as a Bitmap. The column that contains the Uri varies according to the
 * platform version.
 *
 * @param photoData For platforms prior to Android 3.0, provide the Contact._ID column value.
 *                  For Android 3.0 and later, provide the Contact.PHOTO_THUMBNAIL_URI value.
 * @param imageSize The desired target width and height of the output image in pixels.
 * @return A Bitmap containing the contact's image, resized to fit the provided image size. If
 * no thumbnail exists, returns null.
 */
private Bitmap loadContactPhotoThumbnail(String photoData, int imageSize) {

    // Ensures the Fragment is still added to an activity. As this method is called in a
    // background thread, there's the possibility the Fragment is no longer attached and
    // added to an activity. If so, no need to spend resources loading the contact photo.
    if (!isAdded() || getActivity() == null) {
        return null;
    }

    // Instantiates an AssetFileDescriptor. Given a content Uri pointing to an image file, the
    // ContentResolver can return an AssetFileDescriptor for the file.
    InputStream stream = null;

    // This "try" block catches an Exception if the file descriptor returned from the Contacts
    // Provider doesn't point to an existing file.
    try {
        Uri thumbUri;
        // If Android 3.0 or later, converts the Uri passed as a string to a Uri object.
        if (Utils.hasHoneycomb()) {
            thumbUri = Uri.parse(photoData);
        } else {
            // For versions prior to Android 3.0, appends the string argument to the content
            // Uri for the Contacts table.
            final Uri contactUri = Uri.withAppendedPath(Contacts.CONTENT_URI, photoData);

            // Appends the content Uri for the Contacts.Photo table to the previously
            // constructed contact Uri to yield a content URI for the thumbnail image
            thumbUri = Uri.withAppendedPath(contactUri, Photo.CONTENT_DIRECTORY);
        }
        stream = getActivity().getContentResolver().openInputStream(thumbUri);

        return BitmapFactory.decodeStream(stream);
    } catch (FileNotFoundException e) {
        // If the file pointed to by the thumbnail URI doesn't exist, or the file can't be
        // opened in "read" mode, ContentResolver.openAssetFileDescriptor throws a
        // FileNotFoundException.
        if (BuildConfig.DEBUG) {
            Log.d(TAG, "Contact photo thumbnail not found for contact " + photoData
                    + ": " + e.toString());
        }
    } finally {
        // If an AssetFileDescriptor was returned, try to close it
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                // Closing a file descriptor might cause an IOException if the file is
                // already closed. Nothing extra is needed to handle this.
            }
        }
    }

    // If the decoding failed, returns null
    return null;
}

OTHER TIPS

i do not understand completely what's the problem. is it to retrieve or is it to display ? in the following i give you a code snipped. it works on 4.4.2 down to version 3. in my case i am launching a photo app for example a gallery.

byte[] global_DATA15 = null;

retrieve the data from ContactsContract.Data.DATA15

                    Bitmap myBitMap = BitmapFactory.decodeByteArray(
                            global_DATA15, 0, global_DATA15.length);

                    ByteArrayOutputStream bytes = new ByteArrayOutputStream();

                    myBitMap.compress(Bitmap.CompressFormat.PNG, 100, bytes);

                    String path = Images.Media.insertImage(
                            myContext.getContentResolver(), myBitMap,
                            line4, "source: " + Constant.myClassName);


                    if (path != null) {
                        boolean isOK = true;
                        Uri myUri = null;
                        try {
                            myUri = Uri.parse(path);
                            convertedPath = getRealPathFromURI(myContext,
                                    myUri);
                        } catch (Exception expPhoto) {
                            isOK = false;
                            // .... do something 
                        }
                        if (isOK) {
                            Intent callPhoto = new Intent(
                                    Intent.ACTION_VIEW, myUri);
                            callPhoto.setDataAndType(myUri, "image/*");
                            startActivityForResult(callPhoto,
                                    Constant.photoCallRequestCode);
                        }

a subroutine

/**
 * returns the file path to an content uri
 * 
 * @param context
 * @param contentUri
 * @return path to picture
 */
public String getRealPathFromURI(Context context, Uri contentUri) {
    Cursor cursor = null;
    try {
        String[] proj = { MediaStore.Images.Media.DATA };
        cursor = context.getContentResolver().query(contentUri, proj, null,
                null, null);
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

maybe this helps, i am not sure.

kind regards

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top