Android, media scan doesn't generate thumbnails? - android

I have image files which don't have thumbnails. (imported from my external carmera using NFC)
I want to create thumbnails for my image picker view. (has to be fast)
At this moment, I'm not even sure "MEDIA SCAN" means "generating thumbnail" or what.
I tried to scan file using mMediaScannerConnection.scanFile(mPath, null);
onScanCompleted gets called and I try to get thumbnail using the following two version of functions.
I get null thumbnailPath for both functions, I don't get why..
private String getThumbnailPath(long imageId) {
ContentResolver cr = this.mContext.getContentResolver();
Cursor c = MediaStore.Images.Thumbnails.queryMiniThumbnail(cr, imageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
try {
if (c.moveToNext()) {
int dataId = c.getColumnIndex( Images.Thumbnails.DATA);
String strThumPath = c.getString(dataId);
Log.i("ScanTest", "strThumPath = " + strThumPath );
return strThumPath;
}
} finally {
if (c != null) c.close();
}
return null;
}
private String getThumbnailPath2( long imageId ){
// http://wikicloud.blogspot.kr/2010/10/scanfile.html
ContentResolver cr = this.mContext.getContentResolver();
Cursor c = cr.query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Thumbnails.IMAGE_ID + "= ?" , new String[]{String.valueOf(imageId)}, null);
try {
if (c.moveToNext()) {
int dataId = c.getColumnIndex( Images.Thumbnails.DATA);
String strThumPath = c.getString(dataId);
Log.i("ScanTest", "strThumPath = " + strThumPath );
return strThumPath;
}
} finally {
if (c != null) c.close();
}
return null;
}
-- edit --
Here's how I try to get thumbnails.
first create a mapping from image-id to thumbnail-path.
protected Map getThumbnailPathFromDB() {
Map result = new HashMap();
Cursor thumbCursor = null;
thumbCursor = getContentResolver().query(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
null,
null,
null, null);
if (thumbCursor.moveToFirst()) {
do {
String path = thumbCursor.getString(thumbCursor
.getColumnIndex(MediaStore.MediaColumns.DATA));
long imageId = thumbCursor.getLong(thumbCursor
.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID));
result.put(new Long(imageId), path);
} while(thumbCursor.moveToNext());
}
thumbCursor.close();
return result;
next I iterate all images and try to find thumbnails from the mapping I created above
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(
Images.Media.EXTERNAL_CONTENT_URI, null,
null, null, Images.ImageColumns.DATE_MODIFIED + " DESC");
//thumbnailPathList is the mapping I created above, imageId is the id of image obtained from the cursor
String thumbnailPath = thumbnailPathList.get(new Long(imageId));
// thumbnailPath are occasionally null here!,
I tested my code on about 10 devices.
They all have images which I can't find thumbnails for.

Related

Android - Search contacts with different formats of number

In my application I try to search a contact using the phonenumber. The phonenumber I am searching with is always in the same format ('123456789' for example).
But the following code retrieves not all contacts I expected.
The main issue might be the different format of phonenumbers in my phone: some contacts are saved with '+12 345 6789', the other with '0123 456789'.
Although I tried ContactsContract.PhoneLookup.NORMALIZED_NUMBER my code retrieves only the contacts saved with phonenumbers in the '123456789'-format.
private String getContactDetails(Context context, String number) {
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup._ID,
ContactsContract.PhoneLookup.LOOKUP_KEY};
int len = number.length();
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number.substring(len-7)));
String selection = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
selection = ContactsContract.PhoneLookup.NORMALIZED_NUMBER + " LIKE %" + number.substring(len-7) + "%";
}
Cursor cursor = context.getContentResolver().query(contactUri, projection, selection, null, null);
String name = null;
if(cursor != null) {
if (cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
cursor.close();
}
return name;
}
Don't use both PhoneLookup.CONTENT_FILTER_URI with selection, CONTENT_FILTER_URIs are used to search for data using the URI itself, and should not get any selection.
The PhoneLookup.NORMALIZED_NUMBER column is for getting the result back in an e164 format, not for querying.
Try this:
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode("123456789"));
String[] projection = new String[] { PhoneLookup.NUMBER, PhoneLookup.NORMALIZED_NUMBER };
Cursor c = getContentResolver().query(uri, projection, null, null, null);
if (c != null) {
if (c.moveToFirst()) {
String number = c.getString(0);
String e164_number = c.getString(1);
Log.d(TAG, "number=" + number + ", e164=" + e164_number);
} else {
Log.d(TAG, "couldn't find number");
}
}
c.close();

Android - Get gallery images Samsung S4/S5

I'm working on a custom image gallery for my application but I got a serious issue under Samsung Galaxy S4 and S5. The following code works great on HTC and Xperia devices but not at all on Samsung ones.
Basically, the pathes are always null on these devices.
Here is the code I made.
In big lines, it returns a list of categories containing a name and a list of images. The aim is to provide a folder based gallery like the native one.
Should you have any idea why it fails on Samsung galaxy ?
Thanks for your help.
public List<Category> getCategories()
{
Map<String, Category> map = new HashMap<String, Category>();
String[] projection = new String[] {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
};
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, MediaStore.Images.Media.DATE_TAKEN + " DESC");
if (cursor == null) return;
if (cur.moveToFirst())
{
Category category = null;
long id = 0L;
String bucket = null;;
int idColumn = cur.getColumnIndex(MediaStore.Images.Media._ID);
int bucketColumn = cur.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
do
{
id = cur.getLong(idColumn);
bucket = cur.getString(bucketColumn);
if (map.get(bucket) == null)
{
category = new Category(bucket);
map.put(bucket, category);
}
category = map.get(bucket);
category.addImage( idToImage(id) );
}
while (cur.moveToNext());
}
return map.values().toArray();
}
private Image idToImage(long id)
{
Image image = new Image();
image.setThumbnail( getThumbnail(id) );
image.setImage( getImage(id) );
return image;
}
private String getThumbnail(long id)
{
String path = null;
Cursor cursor = MediaStore.Images.Thumbnails.queryMiniThumbnail(getContentResolver(), id, MediaStore.Images.Thumbnails.MINI_KIND, null);
if( cursor != null && cursor.getCount() > 0 )
{
cursor.moveToFirst();
path = cursor.getString( cursor.getColumnIndex( MediaStore.Images.Thumbnails.DATA ) );
cursor.close();
}
return path;
}
private String getImage(long id)
{
String path = null;
String[] projection = {MediaStore.Images.Media.DATA};
String where = MediaStore.Images.Media._ID + " = " + id;
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, where, null, null);
int dataColumn = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
if( cursor != null && cursor.getCount() > 0 )
{
cursor.moveToFirst();
path = cursor.getString(dataColumn);
}
return path;
}
It will work
/**
* Get actual file path from gallery
*/
public String getPath(Uri uri, Context ctx) {
String[] projection = {MediaStore.Images.Media.DATA};
String result;
Cursor cursor = ctx.getContentResolver().query(uri, projection, null, null, null);
if (cursor == null) {
return null;
}
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
cursor.close();
return result;
}

Get contact photo by URI [duplicate]

Alright, I'm just trying to learn about using Contact information, but I'm a bit stuck. I would like to be able to display a picture for the contact. Using the following code that I have, how would I be able to put the photo for the contact in the ImageView in contact_entry?
ListView contacts_list = (ListView) findViewById(R.id.contacts_list);
// Gets the URI of the db
Uri uri = ContactsContract.Contacts.CONTENT_URI;
// What to grab from the db
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_ID
};
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Cursor cursor = managedQuery(uri, projection, null, null, sortOrder);
String[] fields = new String[] {
ContactsContract.Data.DISPLAY_NAME
};
int[] values = {
R.id.contactEntryText
};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.contact_entry, cursor,
fields, values);
contacts_list.setAdapter(adapter);
contact_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="54px">
<ImageView
android:id="#+id/contactPhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_contact_picture_3"/>
<TextView
android:text="#+id/contactEntryText"
android:id="#+id/contactEntryText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Probably this will help you(contact is identified by getId()):
/**
* #return the photo URI
*/
public Uri getPhotoUri() {
try {
Cursor cur = this.ctx.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID + "=" + this.getId() + " AND "
+ ContactsContract.Data.MIMETYPE + "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'", null,
null);
if (cur != null) {
if (!cur.moveToFirst()) {
return null; // no photo
}
} else {
return null; // error in cursor process
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long
.parseLong(getId()));
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
}
Usage is:
Uri u = objItem.getPhotoUri();
if (u != null) {
mPhotoView.setImageURI(u);
} else {
mPhotoView.setImageResource(R.drawable.ic_contact_picture_2);
}
Android documentation says, that we should do it in this way.
public Bitmap openPhoto(long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = getContentResolver().query(photoUri,
new String[] {ContactsContract.Contacts.Photo.PHOTO}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
if (data != null) {
return BitmapFactory.decodeStream(new ByteArrayInputStream(data));
}
}
} finally {
cursor.close();
}
return null;
}
For contactId you can use:
public static long getContactIDFromNumber(String contactNumber, Context context) {
String UriContactNumber = Uri.encode(contactNumber);
long phoneContactID = new Random().nextInt();
Cursor contactLookupCursor = context.getContentResolver().query(Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, UriContactNumber),
new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID}, null, null, null);
while (contactLookupCursor.moveToNext()) {
phoneContactID = contactLookupCursor.getLong(contactLookupCursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
contactLookupCursor.close();
return phoneContactID;
}
Source: https://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html
Don't know why but this works on 2.2 and 4.1:
Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, Long.parseLong(photoId));
imageView.setImageURI(photoUri);
The photo Uri has the following form: content://com.android.contacts/data/3345, where the number is the photoId.
This code will take an image from a contact and then will display in your imageView, it is so easy and it works perfect, in this case I am getting image from a contact and display if, if there is still query then post a comment
ImageView profile = (ImageView)findViewById(R.id.imageView1);
Uri my_contact_Uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(Contact_Id));
InputStream photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), my_contact_Uri);
BufferedInputStream buf = new BufferedInputStream(photo_stream);
Bitmap my_btmp = BitmapFactory.decodeStream(buf);
profile.setImageBitmap(my_btmp);
According to Android Developers' documentation:
A read-only sub-directory of a single contact that contains the contact's primary photo. The photo may be stored in up to two ways - the default "photo" is a thumbnail-sized image stored directly in the data row, while the "display photo", if present, is a larger version stored as a file.
https://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo
You can use the following method to get thumbnail version of contact photo:
#Nullable
public Bitmap getContactPhotoThumbnail(Context context, long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), contactUri);
return BitmapFactory.decodeStream(is);
}
You can use the following method to the full sized contact photo:
#Nullable
public Bitmap getContactPhoto(Context context, long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
Uri displayPhotoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
try {
AssetFileDescriptor fd =
context.getContentResolver().openAssetFileDescriptor(displayPhotoUri, "r");
return BitmapFactory.decodeStream(fd.createInputStream());
} catch (IOException e) {
return null;
}
}
For future readers, loading all contacts with images takes too much time and memory if you load the images with full size. From experience, on Nexus 5 it takes up to 3 seconds to load ~500 contacts. Because of this intensity, we need to avoid fetching contacts in UI thread.
This is mainly because the thumbnail photos are in an other table, which forces us to query more. If you don't need to load any image, it takes ~400ms in the case mentioned above.
I have created a gist that fetches all contacts, with their respective thumbnail references in ~500-700ms for 500 contacts;
https://gist.github.com/bugraoral/a4d36d79621455fa3dd860ff994ae796
The key point is to query and get all thumbnail references once, load them to memory, and use the memory for querying images of contacts individually.
You need to use permission like this in your manifest file
<uses-permission android:name="android.permission.READ_CONTACTS" />
I know it is a very old question but so are some of the answers here as few things here have now been deprecated. As the question showed up in searches while I was looking for similar solution, I though I will add my two cents here...
I have created a simple contacts list with their names and photos from ContactsContract. Please check my answer at...
https://stackoverflow.com/a/37710199/1209544
Here is the method to get all the contacts, if a contact has image it will load image in the imageview else no image will be shown in the imageview.
#SuppressLint("Range") public static void readContacts(Context context) {
if (context == null)
return;
ContentResolver contentResolver = context.getContentResolver();
if (contentResolver == null)
return;
String[] fieldListProjection = {
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts.PHOTO_URI
,ContactsContract.Contacts.STARRED
};
String sort = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " ASC";
Cursor phones = contentResolver
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI
, fieldListProjection, null, null, sort);
HashSet<String> normalizedNumbersAlreadyFound = new HashSet<>();
if (phones != null && phones.getCount() > 0) {
while (phones.moveToNext()) {
String normalizedNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
if (Integer.parseInt(phones.getString(phones.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
if (normalizedNumbersAlreadyFound.add(normalizedNumber)) {
int id = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
int fav = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.STARRED));
boolean isFav;
isFav= fav == 1;
String uri = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if(uri!=null){
contactList.add(new FavContact(id,isFav,uri,name,phoneNumber));
}
else{
contactList.add(new FavContact(id,isFav,name,phoneNumber));
}
}
}
}
phones.close();
}
}
In Adapter (onBindViewHolder)
if(obj.getImage()==null){
//Image not found then load any random image (whatever you like)
Picasso.get().load(R.drawable.ic_circle_fav_no_dp).fit().into(holder.img_contact);
}
else{
//Here it will load contact image in the imageview.
Bitmap bp;
try {
bp = MediaStore.Images.Media
.getBitmap(context.getContentResolver(),
Uri.parse(obj.getImage()));
Glide.with(context).load(bp).centerInside().into(holder.img_contact);
} catch (IOException e) {
e.printStackTrace();
Picasso.get().load(R.drawable.ic_circle_fav_no_dp).fit().into(holder.img_contact);
}
}

Get contact details from contact id in Android

I want to get several contact details from a contact list view. I have this code:
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long id) {
//HERE I WANT TO GET CONTACT DETAILS FROM THE ID PARAMETER
Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, Uri.encode(id));
Cursor c = getContentResolver().query(lookupUri, new String[]{Contacts.DISPLAY_NAME}, null,null,null);
try {
c.moveToFirst();
String displayName = c.getString(0);
} finally {
c.close();
}
}
But I get this exception: IllegalArgumentException, Invalid lookup id (when I call query method from cursor).
So I dont know how to get a valid lookup id from the item list.
Any idea? thanks!
Here id means, A contact id for which you want to fetch the contact details,
The simply code for getting phone number for a particular contact id is like,
// Build the Uri to query to table
Uri myPhoneUri = Uri.withAppendedPath(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, id);
// Query the table
Cursor phoneCursor = managedQuery(
myPhoneUri, null, null, null, null);
// Get the phone numbers from the contact
for (phoneCursor.moveToFirst(); !phoneCursor.isAfterLast(); phoneCursor.moveToNext()) {
// Get a phone number
String phoneNumber = phoneCursor.getString(phoneCursor
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
sb.append("Phone: " + phoneNumber + "\n");
}
}
So, from your question I have to doubt for id parameter which are you sing in your uri just clear that, Also in my example the id is string type...
Hope you will understand it.
Update: Uri.encode(id) instead of just pass id in string format.
Thanks..
Because managedQuery is deprecated you can also use
Cursor phoneCursor = getContentResolver().query(myPhoneUri, null, null, null, null);
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
int columnIndex = arg2.getColumnIndex(ContactsContract.Contacts._ID);
private void retriveContactImage(ImageView imageView, int columnIndex) {
Bitmap photo = null;
try {
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(),
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.valueOf(columnIndex)));
if (inputStream != null) {
photo = BitmapFactory.decodeStream(inputStream);
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
imageView.setImageBitmap(photo);
}
private ArrayList<String> retrieveContactNumbers(TextView textView, long contactId) {
ArrayList<String> phoneNum = new ArrayList<String>();
Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { contactId + "" }, null);
if (cursor.getCount() >= 1) {
while (cursor.moveToNext()) {
// store the numbers in an array
String str = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (str != null && str.trim().length() > 0) {
phoneNum.add(str);
}
}
}
cursor.close();
textView.setText(phoneNum.get(0));
return phoneNum;
}
private void retrieveContactName(TextView textView, long contactId) {
String contactName = null;
Cursor cursor = context.getContentResolver().query(Contacts.CONTENT_URI, new String[] { ContactsContract.Contacts.DISPLAY_NAME },
ContactsContract.Contacts._ID + " = ?", new String[] { String.valueOf(contactId) }, null);
if (cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
cursor.close();
textView.setText(contactName);
}

Getting a Photo from a Contact

Alright, I'm just trying to learn about using Contact information, but I'm a bit stuck. I would like to be able to display a picture for the contact. Using the following code that I have, how would I be able to put the photo for the contact in the ImageView in contact_entry?
ListView contacts_list = (ListView) findViewById(R.id.contacts_list);
// Gets the URI of the db
Uri uri = ContactsContract.Contacts.CONTENT_URI;
// What to grab from the db
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_ID
};
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Cursor cursor = managedQuery(uri, projection, null, null, sortOrder);
String[] fields = new String[] {
ContactsContract.Data.DISPLAY_NAME
};
int[] values = {
R.id.contactEntryText
};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.contact_entry, cursor,
fields, values);
contacts_list.setAdapter(adapter);
contact_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="54px">
<ImageView
android:id="#+id/contactPhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_contact_picture_3"/>
<TextView
android:text="#+id/contactEntryText"
android:id="#+id/contactEntryText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Probably this will help you(contact is identified by getId()):
/**
* #return the photo URI
*/
public Uri getPhotoUri() {
try {
Cursor cur = this.ctx.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID + "=" + this.getId() + " AND "
+ ContactsContract.Data.MIMETYPE + "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'", null,
null);
if (cur != null) {
if (!cur.moveToFirst()) {
return null; // no photo
}
} else {
return null; // error in cursor process
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long
.parseLong(getId()));
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
}
Usage is:
Uri u = objItem.getPhotoUri();
if (u != null) {
mPhotoView.setImageURI(u);
} else {
mPhotoView.setImageResource(R.drawable.ic_contact_picture_2);
}
Android documentation says, that we should do it in this way.
public Bitmap openPhoto(long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = getContentResolver().query(photoUri,
new String[] {ContactsContract.Contacts.Photo.PHOTO}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
if (data != null) {
return BitmapFactory.decodeStream(new ByteArrayInputStream(data));
}
}
} finally {
cursor.close();
}
return null;
}
For contactId you can use:
public static long getContactIDFromNumber(String contactNumber, Context context) {
String UriContactNumber = Uri.encode(contactNumber);
long phoneContactID = new Random().nextInt();
Cursor contactLookupCursor = context.getContentResolver().query(Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, UriContactNumber),
new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID}, null, null, null);
while (contactLookupCursor.moveToNext()) {
phoneContactID = contactLookupCursor.getLong(contactLookupCursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
contactLookupCursor.close();
return phoneContactID;
}
Source: https://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html
Don't know why but this works on 2.2 and 4.1:
Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, Long.parseLong(photoId));
imageView.setImageURI(photoUri);
The photo Uri has the following form: content://com.android.contacts/data/3345, where the number is the photoId.
This code will take an image from a contact and then will display in your imageView, it is so easy and it works perfect, in this case I am getting image from a contact and display if, if there is still query then post a comment
ImageView profile = (ImageView)findViewById(R.id.imageView1);
Uri my_contact_Uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(Contact_Id));
InputStream photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), my_contact_Uri);
BufferedInputStream buf = new BufferedInputStream(photo_stream);
Bitmap my_btmp = BitmapFactory.decodeStream(buf);
profile.setImageBitmap(my_btmp);
According to Android Developers' documentation:
A read-only sub-directory of a single contact that contains the contact's primary photo. The photo may be stored in up to two ways - the default "photo" is a thumbnail-sized image stored directly in the data row, while the "display photo", if present, is a larger version stored as a file.
https://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo
You can use the following method to get thumbnail version of contact photo:
#Nullable
public Bitmap getContactPhotoThumbnail(Context context, long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), contactUri);
return BitmapFactory.decodeStream(is);
}
You can use the following method to the full sized contact photo:
#Nullable
public Bitmap getContactPhoto(Context context, long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
Uri displayPhotoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
try {
AssetFileDescriptor fd =
context.getContentResolver().openAssetFileDescriptor(displayPhotoUri, "r");
return BitmapFactory.decodeStream(fd.createInputStream());
} catch (IOException e) {
return null;
}
}
For future readers, loading all contacts with images takes too much time and memory if you load the images with full size. From experience, on Nexus 5 it takes up to 3 seconds to load ~500 contacts. Because of this intensity, we need to avoid fetching contacts in UI thread.
This is mainly because the thumbnail photos are in an other table, which forces us to query more. If you don't need to load any image, it takes ~400ms in the case mentioned above.
I have created a gist that fetches all contacts, with their respective thumbnail references in ~500-700ms for 500 contacts;
https://gist.github.com/bugraoral/a4d36d79621455fa3dd860ff994ae796
The key point is to query and get all thumbnail references once, load them to memory, and use the memory for querying images of contacts individually.
You need to use permission like this in your manifest file
<uses-permission android:name="android.permission.READ_CONTACTS" />
I know it is a very old question but so are some of the answers here as few things here have now been deprecated. As the question showed up in searches while I was looking for similar solution, I though I will add my two cents here...
I have created a simple contacts list with their names and photos from ContactsContract. Please check my answer at...
https://stackoverflow.com/a/37710199/1209544
Here is the method to get all the contacts, if a contact has image it will load image in the imageview else no image will be shown in the imageview.
#SuppressLint("Range") public static void readContacts(Context context) {
if (context == null)
return;
ContentResolver contentResolver = context.getContentResolver();
if (contentResolver == null)
return;
String[] fieldListProjection = {
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts.PHOTO_URI
,ContactsContract.Contacts.STARRED
};
String sort = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " ASC";
Cursor phones = contentResolver
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI
, fieldListProjection, null, null, sort);
HashSet<String> normalizedNumbersAlreadyFound = new HashSet<>();
if (phones != null && phones.getCount() > 0) {
while (phones.moveToNext()) {
String normalizedNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
if (Integer.parseInt(phones.getString(phones.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
if (normalizedNumbersAlreadyFound.add(normalizedNumber)) {
int id = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
int fav = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.STARRED));
boolean isFav;
isFav= fav == 1;
String uri = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if(uri!=null){
contactList.add(new FavContact(id,isFav,uri,name,phoneNumber));
}
else{
contactList.add(new FavContact(id,isFav,name,phoneNumber));
}
}
}
}
phones.close();
}
}
In Adapter (onBindViewHolder)
if(obj.getImage()==null){
//Image not found then load any random image (whatever you like)
Picasso.get().load(R.drawable.ic_circle_fav_no_dp).fit().into(holder.img_contact);
}
else{
//Here it will load contact image in the imageview.
Bitmap bp;
try {
bp = MediaStore.Images.Media
.getBitmap(context.getContentResolver(),
Uri.parse(obj.getImage()));
Glide.with(context).load(bp).centerInside().into(holder.img_contact);
} catch (IOException e) {
e.printStackTrace();
Picasso.get().load(R.drawable.ic_circle_fav_no_dp).fit().into(holder.img_contact);
}
}

Categories

Resources