Android 从联系人获取照片
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3509178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting a Photo from a Contact
提问by Chiggins
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?
好的,我只是想了解如何使用联系信息,但我有点卡住了。我希望能够显示联系人的图片。使用我拥有的以下代码,我如何才能将联系人的照片放在 contact_entry 的 ImageView 中?
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
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>
回答by Pentium10
Probably this will help you(contact is identified by getId()
):
可能这会对您有所帮助(联系人由 标识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);
}
回答by Andrii Kovalchuk
Android documentation says, that we should do it in this way.
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;
}
For contactId
you can use:
因为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;
}
Source: https://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html
来源:https: //developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html
回答by AlikElzin-kilaka
Don't know why but this works on 2.2 and 4.1:
不知道为什么,但这适用于 2.2 和 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.
照片 Uri 具有以下形式:content://com.android.contacts/data/3345,其中数字是 photoId。
回答by Pir Fahim Shah
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 中,它非常简单且效果很好,在这种情况下,我从联系人获取图像并显示,如果仍有查询,则发表评论
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);
回答by Tousif Osman
According to Android Developers' documentation:
根据 Android 开发人员的文档:
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
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;
}
}
回答by bugraoral
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.
对于未来的读者,如果加载完整大小的图像,加载所有联系人的图像会花费太多时间和内存。根据经验,在 Nexus 5 上加载约 500 个联系人最多需要 3 秒。由于这种强度,我们需要避免在 UI 线程中获取联系人。
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.
这主要是因为缩略图照片在另一个表中,这迫使我们查询更多。如果您不需要加载任何图像,则在上述情况下大约需要 400 毫秒。
I have created a gist that fetches all contacts, with their respective thumbnail references in ~500-700ms for 500 contacts;
我创建了一个获取所有联系人的要点,并在大约 500-700 毫秒内为 500 个联系人提供了各自的缩略图参考;
https://gist.github.com/bugraoral/a4d36d79621455fa3dd860ff994ae796
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.
关键是一次查询并获取所有缩略图引用,将它们加载到内存中,并使用内存单独查询联系人的图像。
回答by iman kazemayni
You need to use permission like this in your manifest file
您需要在清单文件中使用这样的权限
<uses-permission android:name="android.permission.READ_CONTACTS" />
回答by Nashe
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
我创建了一个简单的联系人列表,其中包含来自 ContactsContract 的姓名和照片。请检查我的答案... https://stackoverflow.com/a/37710199/1209544