Получение фотографии из контакта
Хорошо, я просто пытаюсь узнать об использовании контактной информации, но я немного застрял. Я хотел бы иметь возможность отображать картинку для контакта. Используя следующий код, который у меня есть, как я смогу поместить фотографию для контакта в ImageView в 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>
10 ответов
Возможно, это поможет вам (контакт идентифицирован 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);
}
Использование это:
Uri u = objItem.getPhotoUri();
if (u != null) {
mPhotoView.setImageURI(u);
} else {
mPhotoView.setImageResource(R.drawable.ic_contact_picture_2);
}
Документация Android гласит, что мы должны делать это таким образом.
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;
}
За contactId
ты можешь использовать:
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;
}
Источник: https://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html
Не знаю почему, но это работает на 2.2 и 4.1:
Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, Long.parseLong(photoId));
imageView.setImageURI(photoUri);
Фотография Uri имеет следующий вид: content: //com.android.contacts/data/3345, где номером является photoId.
Согласно документации разработчиков Android:
Доступный только для чтения подкаталог одного контакта, который содержит основную фотографию контакта. Фотография может быть сохранена двумя способами: "фотография" по умолчанию - это изображение размером с миниатюру, хранящееся непосредственно в строке данных, в то время как "отображаемая фотография" - это увеличенная версия, сохраненная в виде файла.
https://developer.android.com/reference/android/provider/ContactsContract.Contacts.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);
}
Вы можете использовать следующий метод для полноразмерной фотографии контакта:
@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;
}
}
Этот код будет брать изображение из контакта, а затем будет отображаться в вашем imageView, это так просто и работает отлично, в этом случае я получаю изображение из контакта и отображаю, если, если еще есть запрос, то оставьте комментарий
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);
Для будущих читателей загрузка всех контактов с изображениями занимает слишком много времени и памяти, если вы загружаете изображения в полный размер. По опыту, на Nexus 5 загрузка до 500 контактов занимает до 3 секунд. Из-за этой интенсивности нам нужно избегать выборки контактов в потоке пользовательского интерфейса.
Это главным образом потому, что миниатюры фотографий находятся в другой таблице, что заставляет нас запрашивать больше. Если вам не нужно загружать какое-либо изображение, в указанном выше случае это займет ~400 мс.
Я создал суть, которая выбирает все контакты с соответствующими ссылками на миниатюры в ~500-700 мс для 500 контактов;
https://gist.github.com/bugraoral/a4d36d79621455fa3dd860ff994ae796
Ключевым моментом является запрос и получение всех миниатюрных ссылок один раз, загрузка их в память и использование памяти для индивидуального запроса изображений контактов.
Вы должны использовать разрешение, как это в вашем файле манифеста
<uses-permission android:name="android.permission.READ_CONTACTS" />
Я знаю, что это очень старый вопрос, но некоторые ответы здесь так же мало, потому что некоторые вещи здесь уже устарели. Поскольку вопрос обнаружился в поисках, когда я искал подобное решение, я, хотя, я добавлю свои два цента здесь...
Я создал простой список контактов с их именами и фотографиями из ContactsContract. Пожалуйста, проверьте мой ответ на... /questions/39946244/izobrazheniya-v-simplecursoradapter/39946246#39946246
Вот способ получить все контакты: если у контакта есть изображение, он загрузит изображение в просмотре изображений, иначе изображение не будет отображаться в просмотре изображений.
@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();
}
}
В адаптере (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);
}
}
Вот рабочий код:-
public static Bitmap retrieveContactPhoto(Context context, String number) {
ContentResolver contentResolver = context.getContentResolver();
String contactId = null;
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID};
Cursor cursor =
contentResolver.query(
uri,
projection,
null,
null,
null);
if (cursor != null) {
while (cursor.moveToNext()) {
contactId = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
cursor.close();
}
Bitmap photo = BitmapFactory.decodeResource(context.getResources(),
R.drawable.about_icon_email);
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
cursor = context.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;
}
Надеюсь, это поможет вам