【问题标题】:How do I load a contact Photo?如何加载联系人照片?
【发布时间】:2011-01-23 22:11:06
【问题描述】:

我在 Android 中加载联系人的照片时遇到问题。我已经用谷歌搜索了答案,但到目前为止都是空的。有没有人有查询联系人,然后加载照片的例子?

所以,给定一个 contactUri,它来自一个名为 using 的 Activity 结果

startActivityForResult(new Intent(Intent.ACTION_PICK,ContactsContract.CommonDataKinds.Phone.CONTENT_URI),PICK_CONTACT_REQUEST) 

是:

content://com.android.contacts/data/1557

loadContact(..) 工作正常。但是,当我调用 getPhoto(...) 方法时,我得到了照片 InputStream 的空值。这也令人困惑,因为 URI 值不同。 contactPhotoUri 的计算结果为:

content://com.android.contacts/contacts/1557

请参阅下面代码中的内联 cmets。

 class ContactAccessor {

    /**
     * Retrieves the contact information.
     */
    public ContactInfo loadContact(ContentResolver contentResolver, Uri contactUri) {

        //contactUri --> content://com.android.contacts/data/1557

        ContactInfo contactInfo = new ContactInfo();

        // Load the display name for the specified person
        Cursor cursor = contentResolver.query(contactUri,
                                            new String[]{Contacts._ID, 
                                                         Contacts.DISPLAY_NAME, 
                                                         Phone.NUMBER,
                                                         Contacts.PHOTO_ID}, null, null, null);
        try {
            if (cursor.moveToFirst()) {
                contactInfo.setId(cursor.getLong(0));
                contactInfo.setDisplayName(cursor.getString(1));
                contactInfo.setPhoneNumber(cursor.getString(2));
            }
        } finally {
            cursor.close();
        }        
        return contactInfo;  // <-- returns info for contact
    }

    public Bitmap getPhoto(ContentResolver contentResolver, Long contactId) {
        Uri contactPhotoUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);

        // contactPhotoUri --> content://com.android.contacts/contacts/1557

        InputStream photoDataStream = Contacts.openContactPhotoInputStream(contentResolver,contactPhotoUri); // <-- always null
        Bitmap photo = BitmapFactory.decodeStream(photoDataStream);
        return photo;
    }

    public class ContactInfo {

        private long id;
        private String displayName;
        private String phoneNumber;
        private Uri photoUri;

        public void setDisplayName(String displayName) {
            this.displayName = displayName;
        }

        public String getDisplayName() {
            return displayName;
        }

        public void setPhoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
        }

        public String getPhoneNumber() {
            return phoneNumber;
        }

        public Uri getPhotoUri() {
            return this.photoUri;
        }

        public void setPhotoUri(Uri photoUri) {
            this.photoUri = photoUri;
        }

        public long getId() {
            return this.id;
        }

        public void setId(long id) {
            this.id = id;
        }

    }
}

很明显,我在这里做错了,但我似乎无法弄清楚问题所在。谢谢。

【问题讨论】:

  • 那么没有像样的解决方案吗?如果联系人使用 Facebook 照片,我们是 SOL?
  • 我找不到从 Facebook 加载照片的方法。我不知道它在 Froyo 是否发生了变化。
  • 从光标读取后你为什么不使用 Contacts.PHOTO_ID ?

标签: android contactscontract


【解决方案1】:

这对我有用:

public static Bitmap loadContactPhoto(ContentResolver cr, long  id) {
    Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
    InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
    if (input == null) {
        return null;
    }
    return BitmapFactory.decodeStream(input);
}

【讨论】:

  • 人们一直说替代方法有效。但我还没有看到任何在库存设备上的作品(我认为 HTC 的同步适配器工作方式不同)。谁能确认同时拥有 Google 联系人和 Facebook 联系人(但只有 facebook 联系人有照片)的用户可以让照片出现在只有 Facebook 应用同步适配器的手机上?
  • 嘿 .. 在函数中你传递了 id .. 是 Photo id 还是 Contact Id ?
  • 这个方法应该在返回之前调用input.close()
  • 效果很好!太棒了。
【解决方案2】:

扫描了显示缩略图问题的许多问题和答案后,我想我会发布我对这个特殊难题的解决方案,因为我只能找到几个完全有效的解决方案,而没有一个为懒惰的人提供好的罐装解决方案开发商。

下面的类接受一个 Context、QuickContactBadge 和一个电话号码,如果指定的电话号码有可用的图像,则会将本地存储的图像附加到徽章。

课程如下:

public final class QuickContactHelper {

private static final String[] PHOTO_ID_PROJECTION = new String[] {
    ContactsContract.Contacts.PHOTO_ID
};

private static final String[] PHOTO_BITMAP_PROJECTION = new String[] {
    ContactsContract.CommonDataKinds.Photo.PHOTO
};

private final QuickContactBadge badge;

private final String phoneNumber;

private final ContentResolver contentResolver;

public QuickContactHelper(final Context context, final QuickContactBadge badge, final String phoneNumber) {

    this.badge = badge;
    this.phoneNumber = phoneNumber;
    contentResolver = context.getContentResolver();

}

public void addThumbnail() {

    final Integer thumbnailId = fetchThumbnailId();
    if (thumbnailId != null) {
        final Bitmap thumbnail = fetchThumbnail(thumbnailId);
        if (thumbnail != null) {
            badge.setImageBitmap(thumbnail);
        }
    }

}

private Integer fetchThumbnailId() {

    final Uri uri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
    final Cursor cursor = contentResolver.query(uri, PHOTO_ID_PROJECTION, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");

    try {
        Integer thumbnailId = null;
        if (cursor.moveToFirst()) {
            thumbnailId = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
        }
        return thumbnailId;
    }
    finally {
        cursor.close();
    }

}

final Bitmap fetchThumbnail(final int thumbnailId) {

    final Uri uri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, thumbnailId);
    final Cursor cursor = contentResolver.query(uri, PHOTO_BITMAP_PROJECTION, null, null, null);

    try {
        Bitmap thumbnail = null;
        if (cursor.moveToFirst()) {
            final byte[] thumbnailBytes = cursor.getBlob(0);
            if (thumbnailBytes != null) {
                thumbnail = BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length);
            }
        }
        return thumbnail;
    }
    finally {
        cursor.close();
    }

}

}

下面是 Activity 中的一个典型用例:

String phoneNumber = "...";
QuickContactBadge badge = (QuickContactBadge) view.findViewById(R.id.friend);
new QuickContactHelper(this, badge, phoneNumber).addThumbnail();

在片段中会略有不同:

String phoneNumber = "...";
QuickContactBadge badge = (QuickContactBadge) view.findViewById(R.id.friend);
new QuickContactHelper(getActivity(), badge, phoneNumber).addThumbnail();

现在有一些方法可以提高效率 - 例如,如果您要呈现消息时间线,您希望为给定电话号码的每个徽章实例重复使用相同的位图对象,而不是不断创建新的帮助程序类实例并重新检索位图——但我在这里的目的是发布一个解决方案,为了清晰起见,该解决方案被精简到绝对最小值,同时提供一个完整且可用的解决方案。此解决方案已在 Andriod 4.0 上构建和测试,并且也在 4.1 上进行了测试。

【讨论】:

    【解决方案3】:

    经过大量调试之夜,我发现最好的方法是使用contact id,如果失败,则使用photo id

    public static Bitmap loadContactPhoto(ContentResolver cr, long  id,long photo_id) 
    {
    
        Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
        InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
        if (input != null) 
        {
            return BitmapFactory.decodeStream(input);
        }
        else
        {
            Log.d("PHOTO","first try failed to load photo");
    
        }
    
        byte[] photoBytes = null;
    
        Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, photo_id);
    
        Cursor c = cr.query(photoUri, new String[] {ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null);
    
        try 
        {
            if (c.moveToFirst()) 
                photoBytes = c.getBlob(0);
    
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
    
        } finally {
    
            c.close();
        }           
    
        if (photoBytes != null)
            return BitmapFactory.decodeByteArray(photoBytes,0,photoBytes.length);
        else
            Log.d("PHOTO","second try also failed");
        return null;
    }
    

    在模拟器和 Nexus S 设备上测试的代码似乎可以工作。

    【讨论】:

    • 这是我发现的唯一一段可以实际处理各种照片的代码。 +1 更新:不幸的是,它不适用于运行最新 Gingerbread Stock rom 的三星 Galaxy S2。 ://
    • 停止使用 ICS 和 JellyBean,这是我唯一能够运行的例程。不过,将检查它在 Gingerbread 中是如何工作的,看看是否有办法让它在任何地方都能工作。
    【解决方案4】:

    伙计们,我花了很多时间试图弄清楚这一点。这是我创建的一种方法,可以通过电话号码(无破折号)为您获取您的 Facebook 照片。当然,您可以进行相应的修改:

        public Bitmap getFacebookPhoto(String phoneNumber) {
        Uri phoneUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
        Uri photoUri = null;
        ContentResolver cr = this.getContentResolver();
        Cursor contact = cr.query(phoneUri,
                new String[] { ContactsContract.Contacts._ID }, null, null, null);
    
        if (contact.moveToFirst()) {
            long userId = contact.getLong(contact.getColumnIndex(ContactsContract.Contacts._ID));
            photoUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, userId);
    
        }
        else {
            Bitmap defaultPhoto = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_report_image);
            return defaultPhoto;
        }
        if (photoUri != null) {
            InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(
                    cr, photoUri);
            if (input != null) {
                return BitmapFactory.decodeStream(input);
            }
        } else {
            Bitmap defaultPhoto = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_report_image);
            return defaultPhoto;
        }
        Bitmap defaultPhoto = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_report_image);
        return defaultPhoto;
    }
    

    【讨论】:

    • 我试过你的代码,但它在我的 HTC Sensation (Sense 3.0) 上不起作用。恕我直言,我认为您的代码也只是获取contactId,然后将其提供给openContactPhotoInputStream - 它与@wrongmissle 的代码没有什么不同。事实上,两种解决方案的结果在我的手机上是相同的
    • 这适用于我的 HTC Desire HD。但是,如果我有一个超过 261 个联系人的联系人数组,它会强制关闭。我正在循环抛出一个数组: photoarray[a] = getFacebookPhoto(storage[a][0]);其中 [a][0] 是电话号码。所以如果 storage.length>261,它会强制关闭。有任何想法吗?数组声明为 photoarray = new Bitmap[storage.length];
    • @erdomester 这可能是因为它需要很长时间,并且您的应用程序似乎阻塞了 CPU。您应该在后台线程中执行此操作,这不会阻塞主/UI 线程!
    • 非常感谢。做得好。这项工作在我的 HTC Sensation(或金字塔大声笑)中。
    【解决方案5】:

    这些方法都不适合我。起作用的是:

    String[] projection = new String[] {
                    ContactsContract.Contacts.PHOTO_ID,                 ///< the correct ID for photo retrieval in loadLocalContactPhotoBytes()
    //              ContactsContract.Contacts._ID,
                    ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.NUMBER,
    //              ContactsContract.CommonDataKinds.Photo.PHOTO
            };
    
            ContentResolver cr = ctx.getContentResolver();
    
            Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    //      Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,
                    //              new String[] {RawContacts._ID, RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_NAME},
                    //              new String[] {Contacts._ID},
                    projection, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
    
    ....
    

    //上面的“光标”作为下面的参数传递

        private byte[] loadLocalContactPhotoBytes(ContentResolver cr, Cursor cursor, byte[] defaultPhotoBytes)
        {
            byte[] photoBytes = null;// = cursor.getBlob(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO));
    
    //      int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
    //      Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
    //      Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
            Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, id);
    
            Cursor c = cr.query(photoUri, new String[] {ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null);
    
            try 
            {
                if (c.moveToFirst()) 
                    photoBytes = c.getBlob(0);
    
            } catch (Exception e) {
                // TODO: handle exception
                Log.w(_TAG, e.toString());
    
            } finally {
    
                c.close();
            }           
    
            photoBytes = photoBytes == null ? defaultPhotoBytes : photoBytes;
            return photoBytes;
        }
    

    【讨论】:

      【解决方案6】:

      只是为了好玩,我将这里的大部分答案复制到一个班级中,看看他们中的任何一个能否成功获得 Facebook 缩略图。他们没有....但是,这就是我所做的,也许是为了避免你做同样的事情。

      为了方便,它会在对话框中显示结果。

      请注意 - 它没有经过优化,您需要捕获错误并关闭光标等

      启动联系人选择器意图:

      private static final int SELECT_CONTACT = 1468;
      
      Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
      contactPickerIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
      
      try {
          startActivityForResult(contactPickerIntent, SELECT_CONTACT);
      } catch (ActivityNotFoundException e) {
          e.printStackTrace();
      }
      

      回调:

      @Override
          public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
              super.onActivityResult(requestCode, resultCode, data);
      
          if (data != null && resultCode == Activity.RESULT_OK) {
      
              switch (requestCode) {
      
              case SELECT_CONTACT:
      
                  Uri contactURI = data.getData();
      
                  if (contactURI != null) {
      
                      String contactID = data.getData().getLastPathSegment().trim();
      
                      String contactName = ContactThumb.getDisplayName(getActivity(), contactURI);
      
                      if (contactName != null && !contactName.isEmpty() && contactID != null && !contactID.isEmpty()) {
      
                          final int THUMBNAIL_SIZE = 100;
      
                          Bitmap contactThumb = ContactThumb.loadContactPhoto(getActivity(), Long.valueOf(contactID));
      
                          if (contactThumb != null) {
      
                              final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
      
                              final int width = contactThumb.getWidth();
                              final int height = contactThumb.getHeight();
                              final int ratio = width / height;
      
                              final Bitmap resized = ThumbnailUtils.extractThumbnail(contactThumb, (THUMBNAIL_SIZE * ratio),
                                      THUMBNAIL_SIZE);
      
                              Drawable icon = new BitmapDrawable(getActivity().getResources(), resized);
      
                              alert.setIcon(icon);
      
                              alert.setTitle("Contact details");
      
                              final TextView homeTV = new TextView(getActivity());
      
                              homeTV.setText(contactName + " : " + contactID);
                              homeTV.setTextSize(12);
      
                              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
                                  homeTV.setTextColor(Color.WHITE);
                              }
      
                              homeTV.setPadding(30, 2, 20, 10);
                              homeTV.setMovementMethod(LinkMovementMethod.getInstance());
      
                              alert.setView(homeTV);
                              alert.show();
      
                          } else {
                              Toast.makeText(getActivity(), "Photo null", Toast.LENGTH_SHORT).show();
                          }
                      }
      
                  }
      
                  break;
              }
          } else {
              // cancelled or error
          }
      }
      

      ContactThumb 尝试......

      import java.io.InputStream;
      import android.content.ContentResolver;
      import android.content.ContentUris;
      import android.content.Context;
      import android.database.Cursor;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.net.Uri;
      import android.provider.ContactsContract;
      import android.provider.ContactsContract.Contacts;
      import android.provider.ContactsContract.PhoneLookup;
      import android.provider.ContactsContract.CommonDataKinds.Phone;
      import android.util.Log;
      
      public class ContactThumb {
      
      private static final String TAG = "THUMB";
      
      public static String getDisplayName(final Context ctx, final Uri contactURI) {
      
          String cname = null;
      
          try {
      
              final String[] projection = new String[] { ContactsContract.Contacts.DISPLAY_NAME };
              final Cursor cursor = ctx.getContentResolver().query(contactURI, projection, null, null, null);
      
              if (cursor != null) {
      
                  try {
      
                      if (cursor.moveToFirst()) {
                          cname = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                      }
      
                  } finally {
                      cursor.close();
                  }
      
              }
      
          } catch (final Exception e) {
              e.printStackTrace();
          }
      
          return cname;
      }
      
      public static Bitmap loadContactPhoto(final Context ctx, final long contactId) {
      
          final Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
      
          final InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(ctx.getContentResolver(), contactUri);
      
          if (input != null) {
              Log.i(TAG, "loadContactPhoto: input");
      
              return BitmapFactory.decodeStream(input);
      
          } else {
      
              byte[] photoBytes = null;
      
              Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
      
              final Cursor c = ctx.getContentResolver().query(photoUri,
                      new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO }, null, null, null);
      
              try {
      
                  if (c.moveToFirst()) {
                      photoBytes = c.getBlob(0);
                  }
      
              } catch (final Exception e) {
                  e.printStackTrace();
      
              } finally {
                  c.close();
              }
      
              if (photoBytes != null) {
      
                  Log.i(TAG, "loadContactPhoto: photoBytes");
      
                  return BitmapFactory.decodeByteArray(photoBytes, 0, photoBytes.length);
      
              } else {
      
                  Bitmap another = finalAttempt(ctx, contactId);
      
                  if (another != null) {
      
                      Log.i(TAG, "loadContactPhoto: another");
      
                      return another;
                  } else {
      
                      Log.i(TAG, "loadContactPhoto: might be returning default");
      
                      return getFacebookPhoto(ctx, getContactNumber(ctx, String.valueOf(contactId)));
                  }
              }
          }
      }
      
      public static String getContactNumber(final Context ctx, final String contactID) {
      
          Cursor phones = null;
      
          try {
      
              phones = ctx.getContentResolver().query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + " = " + contactID, null, null);
      
              String cnum = null;
      
              if (phones != null && phones.getCount() > 0) {
      
                  while (phones.moveToNext()) {
                      cnum = phones.getString(phones.getColumnIndex(Phone.NUMBER));
      
                      if (cnum != null && !cnum.isEmpty() && !cnum.contains("@")) {
      
                          Log.i(TAG, "getContactNumbers: : cnum: " + cnum);
      
                          try {
                              phones.close();
                          } catch (Exception e) {
                              e.printStackTrace();
                          }
      
                          return cnum;
                      }
                  }
              }
      
          } catch (Exception e) {
              e.printStackTrace();
          }
      
          return null;
      }
      
      public static Bitmap getFacebookPhoto(final Context ctx, String phoneNumber) {
      
          Uri phoneUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
          Uri photoUri = null;
          ContentResolver cr = ctx.getContentResolver();
      
          Cursor contact = cr.query(phoneUri, new String[] { ContactsContract.Contacts._ID }, null, null, null);
      
          if (contact.moveToFirst()) {
              long userId = contact.getLong(contact.getColumnIndex(ContactsContract.Contacts._ID));
              photoUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, userId);
      
          } else {
              Bitmap defaultPhoto = BitmapFactory.decodeResource(ctx.getResources(), android.R.drawable.ic_menu_report_image);
              return defaultPhoto;
          }
          if (photoUri != null) {
              InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, photoUri);
              if (input != null) {
                  return BitmapFactory.decodeStream(input);
              }
          } else {
              Bitmap defaultPhoto = BitmapFactory.decodeResource(ctx.getResources(), android.R.drawable.ic_menu_report_image);
              return defaultPhoto;
          }
          Bitmap defaultPhoto = BitmapFactory.decodeResource(ctx.getResources(), android.R.drawable.ic_menu_report_image);
          return defaultPhoto;
      }
      
      public static Bitmap finalAttempt(final Context ctx, final long contactId) {
      
          byte[] photoBytes = null;
      
          String[] projection = new String[] { ContactsContract.Contacts.PHOTO_ID, ContactsContract.Contacts.DISPLAY_NAME,
                  ContactsContract.CommonDataKinds.Phone.NUMBER, };
      
          ContentResolver cr = ctx.getContentResolver();
      
          final Uri contactUri = ContentUris.withAppendedId(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, contactId);
      
          Cursor cursor = cr.query(contactUri, projection, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
      
          if (cursor != null && cursor.moveToFirst()) {
      
              int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
              Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, id);
      
              Cursor c = cr.query(photoUri, new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO }, null, null, null);
      
              try {
                  if (c.moveToFirst()) {
                      photoBytes = c.getBlob(0);
                  }
      
              } catch (Exception e) {
      
              } finally {
                  cursor.close();
                  c.close();
              }
      
              if (photoBytes != null) {
                  return BitmapFactory.decodeByteArray(photoBytes, 0, photoBytes.length);
              }
          }
      
          return null;
      }
      
      }
      

      如果任何方法对您有用,请为我复制并粘贴代码的答案投票!

      查看此链接以获取Android Developers suggested way

      祝你好运

      【讨论】:

        【解决方案7】:

        我的问题似乎是因为我设备中的联系人是从 facebook 同步的,因此照片不可用。

        http://groups.google.com/group/android-developers/msg/be8d0cf3928e4b7f

        【讨论】:

        • 以及为什么默认联系人应用程序会显示 facebook 照片?
        • 因为 facebook 将联系人照片的访问权限授予联系人应用,但不授予其他未知应用。
        • 我也在开发一个短信应用程序,但仍然无法加载 facebook 联系人照片。我认为肯定有解决方案,因为 Handcent SMS 可以显示所有这些照片。 @PaulH:你找到解决办法了吗?
        【解决方案8】:

        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;
        
        }
        

        contactId 代表:

        getString(c.getColumnIndex(ContactsContract.Contacts._ID))
        

        来源:https://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html

        【讨论】:

          【解决方案9】:

          经过一番研究,我找到了解决方案:Displaying the Quick Contact Badge

          我的代码做了一些小的修改,对我来说很好用

              public Bitmap loadContactPhoto(String name) {
              String photoUri = null;     
              int thumbnailColumn;        
              ContentResolver cr = GlobalData.instance().getContext().getContentResolver();
              String[] projection = new String[] { ContactsContract.Contacts._ID ,ContactsContract.Contacts.PHOTO_ID,  ContactsContract.Contacts.PHOTO_URI, ContactsContract.Contacts.PHOTO_THUMBNAIL_URI};
              Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, ContactsContract.Contacts.DISPLAY_NAME + "='" + name + "'", null, null);
              if (cursor.moveToFirst()) {
                      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
                          thumbnailColumn =   cursor.getColumnIndex(Contacts.PHOTO_THUMBNAIL_URI);
                      else
                          thumbnailColumn = cursor.getColumnIndex(PhoneLookup._ID);
          
                      photoUri = cursor.getString(thumbnailColumn);
          
                      if(photoUri != null)
                          return loadContactPhotoThumbnail(photoUri);
                      else
                          return null;    
              }
              return null;
          }
          private Bitmap loadContactPhotoThumbnail(String photoData) {
              AssetFileDescriptor afd = null;
              try {
          
                  Uri thumbUri;
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                      thumbUri = Uri.parse(photoData);
                  } else {
                      final Uri contactUri = Uri.withAppendedPath(Contacts.CONTENT_URI, photoData);
                      thumbUri = Uri.withAppendedPath(contactUri, Photo.CONTENT_DIRECTORY);
                  }
                  afd = GlobalData.instance().getContext().getContentResolver().openAssetFileDescriptor(thumbUri, "r");
                  FileDescriptor fileDescriptor = afd.getFileDescriptor();
                  if (fileDescriptor != null)
                      return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, null);
              } catch (FileNotFoundException e) {
              } finally {
                  if (afd != null) {
                      try {
                          afd.close();
                      } catch (IOException e) {
                      }
                  }
              }
              return null;
          }
          

          【讨论】:

          • FileNotFoundException:没有内容提供者:/contacts/27/photo
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-04
          • 1970-01-01
          • 2013-08-12
          • 1970-01-01
          • 1970-01-01
          • 2015-11-26
          相关资源
          最近更新 更多