2010-10-02 57 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