Получение фотографии из контакта - PullRequest
31 голосов
/ 18 августа 2010

Хорошо, я просто пытаюсь научиться использовать контактную информацию, но я немного застрял. Я хотел бы иметь возможность отображать картинку для контакта. Используя следующий код, который у меня есть, как я смогу поместить фотографию для контакта в 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>

Ответы [ 9 ]

54 голосов
/ 18 августа 2010

Возможно, это поможет вам (контакт идентифицирован 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);
}
15 голосов
/ 19 апреля 2014

Документация 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

13 голосов
/ 29 августа 2012

Не знаю почему, но это работает на 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, где номер - это фотоидентификатор.

4 голосов
/ 10 ноября 2012

Этот код будет брать изображение из контакта, а затем будет отображаться в вашем 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);                      
3 голосов
/ 10 мая 2016

Для будущих читателей загрузка всех контактов с изображениями занимает слишком много времени и памяти, если вы загружаете изображения в полный размер. По опыту, на Nexus 5 загрузка до 500 контактов занимает до 3 секунд. Из-за этой интенсивности нам нужно избегать выборки контактов в потоке пользовательского интерфейса.

Это в основном потому, что миниатюрные фотографии находятся в другой таблице, что заставляет нас запрашивать больше. Если вам не нужно загружать какое-либо изображение, в указанном выше случае это займет ~ 400 мс.

Я создал гист, извлекающий все контакты с соответствующими ссылками на миниатюры в ~ 500-700 мс для 500 контактов;

https://gist.github.com/bugraoral/a4d36d79621455fa3dd860ff994ae796

Ключевым моментом является запрос и получение всех миниатюрных ссылок один раз, загрузка их в память и использование памяти для индивидуального запроса изображений контактов.

1 голос
/ 12 ноября 2015

Вам нужно использовать подобное разрешение в файле манифеста

 <uses-permission android:name="android.permission.READ_CONTACTS" /> 
0 голосов
/ 12 сентября 2018

Согласно документации разработчиков 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;
    }
}
0 голосов
/ 11 июня 2018

Вот рабочий код: -

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;
   }

Надеюсь, это поможет вам

0 голосов
/ 08 июня 2016

Я знаю, что это очень старый вопрос, но и некоторые ответы здесь, так как некоторые вещи здесь уже устарели.Поскольку этот вопрос обнаружился в поиске, когда я искал похожее решение, я добавил свои два цента здесь ...

Я создал простой список контактов с их именами и фотографиями из ContactsContract.Пожалуйста, проверьте мой ответ на ... https://stackoverflow.com/a/37710199/1209544

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...