在我的Android应用程序(Android 4+)中,我想从联系人中选择一个电话号码和相应的个人资料照片。通过文档和SO问题后,如果尝试了许多建议和不同的方法。我唯一能够可靠地工作的是下面的草图。
我的问题是关于方法 getContactPhoto 。为什么有必要从列 ContactsContract.Contacts.PHOTO_THUMBNAIL_URI 中存储的字符串值中删除 " / photo" ?如果我不这样做,应用程序将崩溃(如果我没有抓住异常)。我没有看到任何文件记录" / phone" 必须被删除(只是试错),并且可以想象返回的URI不需要手动修补。它似乎在某些Android 4,5和7设备上运行正常,但我想了解为什么这是必需的。
private void selectPhoneContact() {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
if (intent.resolveActivity(getPackageManager()) != null)
startActivityForResult(intent, usePhone ? ACTIVITY_RESULT_PICK_PHONE_CONTACT : ACTIVITY_RESULT_PICK_EMAIL_CONTACT);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
case ACTIVITY_RESULT_PICK_PHONE_CONTACT:
Uri contactUri = data.getData();
if (contactUri != null) {
try {
String[] projection = new String[]{ContactsContract.Contacts._ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Contacts.PHOTO_THUMBNAIL_URI};
Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
String phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(valueColumn));
Bitmap profileImage = getContactPhoto(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI)));
}
}
finally {
cursor.close();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
break;
}
}
private Bitmap getContactPhoto(String thumbnailUri) throw IOException {
if (thumbnailUri == null)
return null;
if (thumbnailUri.endsWith("/photo"))
thumbnailUri = thumbnailUri.substring(0, thumbnailUri.length() - 6); // remove "/photo"
Uri photoUri = Uri.parse(thumbnailUri);
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), photoUri);
if (inputStream == null)
return null;
try {
return BitmapFactory.decodeStream(inputStream);
}
finally {
inputStream.close();
}
}
正如pskink所建议的,我根据SimpleCursorAdapter如何在ImageView中加载位图创建了一个替代方法。这基本上归结为getContactPhoto2,如下所示。这也行得通,我会改用它。
private Bitmap getContactPhoto2(String thumbnailUri) throws Exception {
InputStream stream = null;
try {
stream = getContentResolver().openInputStream(Uri.parse(thumbnailUri));
Bitmap bm = BitmapFactory.decodeResourceStream(getResources(), null, stream, null, null);
if (bm != null)
Log.d("Contacts photo", String.format("Bitmap: %d x %d", bm.getWidth(), bm.getHeight()));
return bm;
} finally {
if (stream != null)
stream.close();
}
}