例外找不到ID 0的照片文件

时间:2013-03-19 10:47:06

标签: android android-contacts

我的应用中有一个代码可以获取联系人的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帐户收到的照片或从互联网上下载的照片)。

2 个答案:

答案 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+时,它只会以缩略图形式提供,而不是普通的全尺寸图片。