【问题标题】:Exception No photo file found for ID 0异常未找到 ID 0 的照片文件
【发布时间】:2013-03-19 10:47:05
【问题描述】:

我的应用中有一个代码可以获取联系人的 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

更新:我发现这种情况只发生在不是由设备拍摄的照片(例如从谷歌帐户接收的照片或从互联网下载的照片)。

【问题讨论】:

    标签: android android-contacts


    【解决方案1】:

    改变获取照片输入流的方式后,一切正常。

    代替:

    InputStream isPhoto = context.getContentResolver().openInputStream(photoUri);
    

    我用过:

    InputStream photoInputStream =
        Contacts.openContactPhotoInputStream(context.getContentResolver(), contactUri);
    

    注意:现在 Uri 是联系人而不是他的照片。

    【讨论】:

      【解决方案2】:

      按照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+ 时,它只能作为缩略图使用,而不能作为正常的全尺寸图片使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-29
        • 2019-06-26
        • 2012-01-06
        • 1970-01-01
        • 1970-01-01
        • 2016-12-03
        • 2019-09-29
        • 2018-02-25
        相关资源
        最近更新 更多