我的应用中有一个代码可以获取联系人的URI,然后通过尝试打开照片的输入流来验证联系人是否有照片,获取照片的URI并对其进行解码。
很少,我得到一个奇怪的例外,即URI不存在。我得到了一个不存在的照片文件的URI。
获取照片URI:
// Get Uri to the contact
Uri contact = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,
c.getInt(c.getColumnIndex(PhoneLookup._ID)));
// Get input stream of the photo
InputStream is = Contacts.openContactPhotoInputStream(context.getContentResolver(), contact);
// If no input stream (then there is no photo of contact), return 'null' instead of photo Uri
if (is == null) {
Log.d(TAG, "No photo");
return;
}
// Get display photo Uri of the contact
Uri photoUri = Uri.withAppendedPath(contact, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
此时,当联系人没有照片时,is
会获得null
并返回。但很少,photoUri
获得content://com.android.contacts/contacts/303/display_photo
。
现在解码它(在其他功能中):
InputStream isPhoto = context.getContentResolver().openInputStream(photoUri);
从这一行抛出的异常是:
java.io.FileNotFoundException: No photo file found for ID 0
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:617)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:717)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:614)
at android.content.ContentResolver.openInputStream(ContentResolver.java:449)
at com.app.android.utils.ImageUtils.decodeBitmapFromPhotoUri(ImageUtils.java:39)
...
内容解析器如何为不存在的照片(联系人存在且没有照片)提供URI,而不是返回null
?
更新:我发现只有设备未拍摄的照片才会发生(例如从Google帐户收到的照片或从互联网上下载的照片)。
答案 0 :(得分:3)
更改获取照片输入流的方式后,所有工作。
而不是:
InputStream isPhoto = context.getContentResolver().openInputStream(photoUri);
我用过:
InputStream photoInputStream =
Contacts.openContactPhotoInputStream(context.getContentResolver(), contactUri);
注意:现在Uri是联系人而不是他的照片。
答案 1 :(得分:0)
在关注ContactsContract.Contacts.Photo的示例时,我遇到了与尝试使用openDisplayPhoto
时相同的异常:
public InputStream openDisplayPhoto(long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,
contactId);
Uri displayPhotoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo
.DISPLAY_PHOTO);
try {
AssetFileDescriptor fd =
getContentResolver().openAssetFileDescriptor(displayPhotoUri, "r");
return fd.createInputStream();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
使用openPhoto
(实际上是缩略图)时,它工作正常:
public InputStream 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 new ByteArrayInputStream(data);
}
}
} finally {
cursor.close();
}
return null;
}
事实上,当联系人图片来自Google+时,它只会以缩略图形式提供,而不是普通的全尺寸图片。