2010-10-02 60 views
7

我试图展现在我的应用接触的照片,但我得到那些谁手动,并不代表加入其同步与Facebook的照片。如何解决这个问题?这里是我的代码如下:获取联系人的照片被同步与Facebook的Android

Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(PhotoId)); 
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri); 
return BitmapFactory.decodeStream(input); 
+0

我遇到了同样的问题。似乎只有FB同步的联系人才会出现问题。对于从多个来源(即twitter和FB)同步的联系人,这很好。 – 2010-12-22 03:17:30

回答

0

你给出的代码只能访问默认的照片。此外,您应该将联系人ID附加到该URI,而不是照片ID(假设您使用数据表中的照片ID)。

如果有,你可能想尝试直接从数据表中访问它们多张照片。您需要手动解析数据库游标并转换成原始字节数据转换成位图,如下图所示:

String[] projection = {ContactsContract.CommonDataKinds.Photo.PHOTO}; 
Uri uri = Uri. ContactsContract.Data.CONTENT_URI; 
String where = ContactsContract.Data.MIMETYPE 
     + "=" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + " AND " 
     + ContactsContract.Data.CONTACT_ID + " = " + mContactId; 
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null); 

if(cursor!=null&&cursor.moveToFirst()){ 
    do{ 
     byte[] photoData = photoCursor.getBlob(0); 
     Bitmap photo = BitmapFactory.decodeByteArray(photoData, 0, 
       photoData.length, null); 

     //Do whatever with your photo here... 
    }while(cursor.moveToNext()); 
} 

你想mContactId与您想要照片的接触相对应。

如果您只想限制为脸书照片,则需要使用ContactsContract.Data.RAW_CONTACT_ID,您应该使用联系人ID和基于Facebook帐户的筛选器从RawContacts表中获得该信息(假设您知道什么帐户你正在寻找......这可以通过同步提供者实现改变...)

+0

这种方法仍然导致Android的facebook的图片为空字节。我想这是因为android的facebook的api有一个白名单系统,它允许数据只被分享给android默认应用程序。 – Yash 2010-10-04 19:48:48

+0

仍然感谢您的回复 – Yash 2010-10-04 20:08:59

+0

我可以发誓,我已经装载Facebook照片之前使用类似的方法......它可能取决于您的同步提供者,但。我相信那里有几个不同的东西。你有没有尝试切换到不同的Facebook客户端应用程序? – 2010-10-05 00:04:38

0

我得到的图片甚至有的认为是从Facebook同步与此代码的所有联系人:

* @param context 
*   The context used to retrieve the image. 
* @return The image of the user that is saved in the address book or null if 
*   the user does not exists or has no image. 
*/ 
public Bitmap getContactPhoto(Context context) { 
    ContentResolver contentResolver = context.getContentResolver(); 
    Uri photoUri = getCurrentUri(contentResolver); 

    if (photoUri != null) { 
     InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(
       contentResolver, photoUri); 
     if (input != null) { 
      return BitmapFactory.decodeStream(input); 
     } 
    } else { 
     Log.d(getClass().getSimpleName(), "No photo Uri"); 
    } 
    return null; 
} 

private Uri getCurrentUri(ContentResolver contentResolver) { 
    Cursor contact = contentResolver.query(lookUpUri, 
      new String[] { ContactsContract.Contacts._ID }, null, null, null); 

    if (contact.moveToFirst()) { 
     long userId = contact.getLong(contact.getColumnIndex(ContactsContract.Contacts._ID)); 
     return ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, userId); 
    } 
    return null; 
} 

也许再看一遍创建你的photoId的代码。不要在数据表中使用照片的ID来创建Uri。我也尝试过,只有当我使用直接链接到合并用户的URI时,才能检索出适合我的照片。然后,您将获得此人的默认图像,而不管它从何处同步。

+0

这是否也适用于FB-synced-only联系人?我尝试过,但在尝试检索照片输入流后输入为空时失败。 – 2010-12-22 03:18:46

+0

我看了一下,它似乎只适用于某些Facebook图片。它看起来像一些Facebook图片被复制到该人的谷歌联系人,然后才能够加载这些图片。 – Janusz 2010-12-22 07:54:38

4

它不会为只从FB同步联系人工作。您需要使用FB图形API并从那里获取照片;你需要知道联系人的facebook名称。

Bitmap contactPhoto = getImageBitmap("http://graph.facebook.com/mathiaslin/picture?type=square"); 

final private static Bitmap getImageBitmap(String url) { 
    Bitmap bm = null; 
    try { 
     URLConnection conn = new URL(url).openConnection(); 
     conn.connect(); 
     InputStream is = conn.getInputStream(); 
     BufferedInputStream bis = new BufferedInputStream(is); 
     bm = BitmapFactory.decodeStream(bis); 
     bis.close(); 
     is.close(); 
    } catch (IOException e) { 
     Log.e(TAG, "Error getting bitmap", e); 
    } 
    return bm; 
} 
+0

为什么总是错误?当我连接到该URL时被拒绝了吗? – user430926 2011-03-31 08:31:21

+1

你忘了给你的AndroidManifest.xml添加INTERNET权限吗? – 2011-05-26 01:06:14

2

我试图在写这一点,什么都不会正确地检索来自Facebook的通过官方Facebook应用程序帐户同步适配器照片的时间对堆栈溢出发现每一个解决方案。

需要说明的是,发布解决方案的人“认为”他们的工作原理可能是使用HTC智能手机,它附带由HTC编写的Facebook同步适配器,与官方Facebook应用程序没有相同的安全要求。

这是一个安全的事情,的方法之一还是设法尝试访问Facebook的照片的字节,你最终会与SqliteException说,请求的内容受到限制。

相同的代码运行的系统进程将拉动照片罚款。这是不可能的,因为现在。

0

绝对没有办法在一个标准的方式来做到这一点。因此,我们必须使用SQL注入才能破解联系人数据库并获取Facebook头像。下面的代码适用于大多数摩托罗拉,它使用的Motoblur,在Android 2.2或更高版本:

public static Bitmap loadFacebookAvatar(Context context, long personId) { 
    String[] rawProjection = {ContactsContract.RawContacts._ID}; 
    String contactIdAssertion = ContactsContract.RawContacts.CONTACT_ID + " = " + personId; 
    String rawWhere = new StringBuilder() 
      .append(contactIdAssertion).append(") UNION ALL SELECT ") 
      .append(ContactsContract.RawContacts._ID).append(" FROM view_raw_contacts WHERE (") 
      .append(contactIdAssertion).toString(); 
    Cursor query = context.getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, 
      rawProjection, 
      rawWhere, null, null); 
    if (query != null && query.moveToFirst()) { 
     do { 
      long id = query.getLong(query.getColumnIndex(ContactsContract.RawContacts._ID)); 
      String[] projection = {ContactsContract.CommonDataKinds.Photo.PHOTO}; 
      Uri uri = ContactsContract.Data.CONTENT_URI; 

      String mimeTypeAssertion = ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'"; 
      String photoAssertion = ContactsContract.CommonDataKinds.Photo.PHOTO + " IS NOT NULL"; 
      String rawContactIdAssertion = ContactsContract.CommonDataKinds.Photo.RAW_CONTACT_ID + " = " + id; 

      String where = new StringBuilder().append(mimeTypeAssertion).append(" AND ") 
        .append(photoAssertion).append(" AND ").append(rawContactIdAssertion) 
        .append(") UNION ALL SELECT ").append(ContactsContract.CommonDataKinds.Photo.PHOTO) 
        .append(" FROM view_data WHERE (").append(photoAssertion).append(" AND ") 
        .append(rawContactIdAssertion).toString(); 

      Cursor photoQuery = context.getContentResolver().query(uri, projection, where, null, null); 
      if (photoQuery != null && photoQuery.moveToFirst()) { 
       do { 
        byte[] photoData = photoQuery.getBlob(photoQuery.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO)); 
        if (photoData != null) { 
         return BitmapFactory.decodeByteArray(photoData, 0, photoData.length, null); 
        } 
       } while (photoQuery.moveToNext()); 
      } 
     } while (query.moveToNext()); 
    } 
    return null; 
} 

对于其他手机,你必须得到联系人数据库,并对其进行分析,以确定如何应用SQL注入,这需要一个根深蒂固的电话。

+0

这似乎不再适用于Android 4.0.x设备。生成的SQL会被转义以防止注入。 :( – 2012-04-04 21:51:49