Получить фото контактов, которые синхронизируются с Facebook для Android - PullRequest
7 голосов
/ 02 октября 2010

Я пытаюсь показать фотографии контактов в своем приложении, но я получаю фотографии тех, кто был добавлен только вручную, а не тех, которые синхронизируются с Facebook.Как обойти это?Вот мой код ниже:

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

Ответы [ 5 ]

4 голосов
/ 22 декабря 2010

Не работает для контактов, которые синхронизируются только с FB. Вам нужно будет использовать API-график FB и получить оттуда фотографию; и вам нужно знать имя контактов в фейсбуке.

 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;
}
2 голосов
/ 01 февраля 2011

Я пробовал каждое решение, найденное в Stack Overflow на момент написания этой статьи, и ничто не сможет правильно восстановить фотографию, полученную с Facebook через официальный адаптер синхронизации учетной записи приложения Facebook.решения, которые «думают», что работают, вероятно, используют телефоны HTC Sense, которые поставляются с адаптером синхронизации Facebook, написанным HTC, который не имеет тех же требований безопасности, что и официальное приложение Facebook.Из всех методов удалось получить доступ к байтам фотографии на Facebook, и вы получите исключение SqliteException, в котором говорится, что запрошенное содержимое ограничено.Сейчас это просто невозможно.

0 голосов
/ 17 сентября 2011

Определенно нет способа сделать это стандартным способом.Таким образом, мы должны использовать SQL-инъекцию, чтобы иметь возможность взломать базу данных контактов и получить аватары Facebook.Следующий код работает на большинстве Motorolas, которые используют 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 голосов
/ 17 декабря 2010

Я получаю картинку для всех контактов, даже тех, которые синхронизируются с 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.Не используйте идентификатор фотографии в таблице данных для создания Uri.Я также попробовал это, и получение фотографии сработало для меня, только если я использую URI, который ссылается непосредственно на объединенного пользователя.Затем вы получите изображение по умолчанию для этого человека независимо от того, где оно было синхронизировано.

0 голосов
/ 04 октября 2010

Код, который вы дали, должен иметь доступ только к фотографии по умолчанию.Кроме того, вы должны добавить идентификатор контакта к этому URI, а не идентификатор фотографии (при условии, что вы используете идентификатор фотографии из таблицы данных).

Если есть несколько фотографий, вы можете попробовать получить к ним доступ непосредственно из таблицы данных.Вам нужно будет проанализировать курсор базы данных и вручную преобразовать необработанные байтовые данные в растровое изображение, как показано ниже:

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 соответствовал контакту, для которого вы хотите получить фотографии.

Если вы хотите ограничить только фотографии в Facebook, вам нужно будет использовать ContactsContract.Data.RAW_CONTACT_ID, который вы должны получить из таблицы RawContacts, используя свой идентификатор контакта и фильтр на основе учетной записи Facebook (при условии, что вы знаете, какую учетную запись вы ищете ... это может варьироваться в зависимости от реализации поставщика синхронизации ...)

...