Reputation:
I'm having problems setting my ImageView
in my ListView
to a contact image. I've tried every so-called "solution" from the developer website to here on SO, but none of them seem to work.
This is my CustomAdapter class that populates my ListView
:
http://pastebin.com/ABeK9nmT
This is my activity holding the listview
:
http://pastebin.com/FcBDprfG
Its important to know that the activity holds a listview
with unmovable objects around it.
The problem when I run the code is that only the default photo registers and no contacts are shown.
When the activity is ran, LogCat shows this for each of the 6 contacts:
W/Resources(5997): Converting to string: TypedValue{t=0x12/d=0x0 a=3 r=0x7f080015}
I receive no errors whatsoever. does anyone understand what I may be doing wrong?
Please, No copy and paste coding from other SO "solutions." I've tried them all, and they were either for lower APIs, copied from another answer to get points, or missing too many pieces of data. I'm using 2.3.3 which uses Contacts.Contract
.
Upvotes: 0
Views: 1744
Reputation: 951
I would like to recommend few things and also the solution which you may try and let me know if it still fails.
1) You are using SMS custom providers for your application which may fail if user updates his OS to 4.0 or above as when I tried they dint work in them.
2) It will be better if you try querying all the custom providers not in getView() as it will speed up the process and listview.
3) I feel the problem with your code is when you are trying to fetch contact image, which is little bit typical as I implemented earlier and doesnt turns out as mentioned in blog, dont know why.
4) Now the solution flow:
Do not forget to place null checks and follow the code as mentioned, if fails let me know.
5) The Codes:
Get contact name:
/**
* Method used to fetch CONTACT NAME FOR CONTACT NUMBER
*
* @param number :: Contact Number
* @param context :: Activity context
* @return :: returns CONTACT-NAME for CONTACT NUMBER
*/
private String getContactNameFromNumber(String number, Context context)
{
String contactName = null;
Uri contactUri = null;
String[] projection = null;
String selection = null;
Cursor cursorContactId = null;
/*
* Defining URI, Projection and Selection elements
*/
contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
projection = new String[]{Contacts._ID,Contacts.DISPLAY_NAME};
selection = ContactsContract.CommonDataKinds.Phone.NUMBER + " = " + number;
/*
* Cursor iterator to fetch
* particular ID
*/
try
{
cursorContactId = context.getContentResolver().query(contactUri, projection, selection, null, null);
while (cursorContactId.moveToNext())
{
contactName = cursorContactId.getString(cursorContactId.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
cursorContactId.close();
}
if(contactName != null)
{
return contactName;
}
else
{
return null;
}
}
Get Contact ID(If name not null):
/**
* Fetching Contact from a Number
* @param number - For which specific Id is required
* @param context - current context
* @return - ID as String
*/
private String getContactIdFromNumber(String number, Context context)
{
String contactId = null;
Uri contactUri = null;
String[] projection = null;
String selection = null;
Cursor cursorContactId = null;
/*
* Defining URI, Projection and Selection elements
*/
contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
projection = new String[]{Contacts._ID};
selection = ContactsContract.CommonDataKinds.Phone.NUMBER + " = " + number;
/*
* Cursor iterator to fetch
* particular ID
*/
try
{
cursorContactId = context.getContentResolver().query(contactUri, projection, selection, null, null);
while (cursorContactId.moveToNext())
{
contactId = cursorContactId.getString(cursorContactId.getColumnIndex(ContactsContract.Contacts._ID));
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
cursorContactId.close();
}
if(contactId != null)
{
return contactId;
}
else
{
return null;
}
}
Finally load contact image(If ID not null. Pass id & photo_id same ID value. This code taken is from SO after searching various links):
/**
* Fetching contact picture from PhoneBook if available
* @param contentResolver - Current Content Resolver context
* @param id - Specific Contact Id as retrieved
* @param photo_id - Same as Contact Id
* @return - Contact Byte Array if present or null
*/
private byte[] loadContactPhoto(ContentResolver contentResolver, String id, String photo_id)
{
byte[] result = null;
byte[] photoBytes = null;
/*
* Step 1 : Directly fetching with contactId or execute Step 2
*/
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, uri);
/*
* Execute only if stream is not null
*/
if (input != null)
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
int next = input.read();
while (next > -1)
{
bos.write(next);
next = input.read();
}
bos.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
result = bos.toByteArray();
return result;
// return BitmapFactory.decodeStream(input); // Open if want to return as Bitmap
}
else
{
Log.d("PHOTO","first try failed to load photo");
}
/*
* Step 2: Image not fetched directly, fetching through traversing
*/
Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, Long.parseLong(photo_id));
Cursor cursorImageFetch = contentResolver.query(photoUri, new String[] {ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null);
try
{
if (cursorImageFetch.moveToFirst())
photoBytes = cursorImageFetch.getBlob(0);
}
catch (Exception e)
{
e.printStackTrace();
} finally {
cursorImageFetch.close();
}
if (photoBytes != null)
{
return photoBytes;
//return BitmapFactory.decodeByteArray(photoBytes,0,photoBytes.length); // Open if want to return as Bitmap
}
else
{
Log.d("PHOTO","Picture of the contact not available");
return getByteArray();
}
}
Upvotes: 1