获取与 facebook for android 同步的联系人照片
Posted
技术标签:
【中文标题】获取与 facebook for android 同步的联系人照片【英文标题】:Get contacts photo which are synced with facebook for android 【发布时间】:2011-04-20 05:20:15 【问题描述】:我试图在我的应用程序中显示联系人图片,但我得到的只是手动添加的图片,而不是与 facebook 同步的图片。如何解决这个问题?下面是我的代码:
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(PhotoId));
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri);
return BitmapFactory.decodeStream(input);
【问题讨论】:
我遇到了同样的问题。似乎仅与 FB 同步的联系人会出现此问题。对于从多个来源同步的联系人,即 twitter 和 FB,这很好。 【参考方案1】:它不适用于仅从 FB 同步的联系人。您需要使用 FB graph 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;
【讨论】:
为什么总是出错?当我连接到该 URL 时权限被拒绝? 您是否忘记将 INTERNET 权限添加到您的 androidManifest.xml 中?【参考方案2】:在撰写本文时,我已尝试在 Stack Overflow 上找到的所有解决方案,但没有任何方法可以正确检索通过 Facebook 官方应用帐户同步适配器来自 Facebook 的照片。
需要明确的是,发布“认为”他们工作的解决方案的人可能使用 HTC sense 手机,该手机配备了由 HTC 编写的 Facebook 同步适配器,其安全要求与官方 Facebook 应用程序不同。
这是一个安全问题,其中一种方法确实设法尝试访问 facebook 照片的字节,您最终会得到一个 SqliteException ,说明请求的内容受到限制。
作为系统进程运行的相同代码会很好地提取照片。只是目前还不可能。
【讨论】:
【参考方案3】:您提供的代码只能访问默认照片。此外,您应该将联系人 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 与您要为其拍照的联系人对应。
如果您想仅限于 facebook 照片,则需要使用 ContactsContract.Data.RAW_CONTACT_ID 代替,您应该使用您的联系人 ID 和基于 facebook 帐户的过滤器从 RawContacts 表中获取它(假设您知道您要查找的帐户...可能因同步提供程序实施而异...)
【讨论】:
此方法仍会导致来自 facebook for android 的图片为空字节。我想这是因为 facebook for android 的 api 有一个白名单系统,它允许数据只共享给 android 默认应用程序。 我可以发誓,在使用类似方法之前我已经加载了 Facebook 照片……不过,这可能取决于您的同步提供商。我相信那里有几个不同的。您是否尝试过切换到不同的 Facebook 客户端应用程序? 是的,这正是问题所在。 facebook 的官方应用程序(facebook for android)似乎有一个愚蠢的政策,阻止其他应用程序使用数据。我很确定 Facebook 的另一个同步应用程序可以完成这项工作。【参考方案4】:我得到了所有联系人的图片,甚至是从 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 时,检索照片才对我有用。然后,无论从何处同步,您都将获得此人的默认图像。
【讨论】:
这是否也适用于仅 FB 同步的联系人?我尝试过,但在尝试检索照片输入流后输入为 null 失败。 我看了看,它似乎只适用于一些 facebook 图片。看起来一些 Facebook 图片已复制到此人的 google 联系人中,然后我才能加载这些图片。【参考方案5】:绝对没有办法以标准方式做到这一点。因此,我们必须使用 SQL 注入才能破解联系人数据库并获取 Facebook 头像。以下代码适用于大多数在 Android 2.2 或更高版本上使用 Motoblur 的摩托罗拉:
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 注入,这需要有根手机。
【讨论】:
这似乎不再适用于 Android 4.0.x 设备。生成的 SQL 被转义以防止注入。 :(以上是关于获取与 facebook for android 同步的联系人照片的主要内容,如果未能解决你的问题,请参考以下文章
Facebook SDK for Android 4.1.0 共享对话框取消
有没有办法知道用户使用 facebook SDK for Android 在 facebook 上有蓝色勾号?
朋友个人资料图片与 android 中 facebook 的个人资料名称不匹配
Facebook SDK Initialization for SDK v3.23.1 为 Android 实现应用事件