我正在尝试在我的应用程序中显示联系人图片,但我正在获取那些仅手动添加的图片,而不是那些与facebook同步的图片。如何解决这个问题?以下是我的代码:
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(PhotoId));
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri);
return BitmapFactory.decodeStream(input);
答案 0 :(得分: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;
}
答案 1 :(得分:2)
在撰写本文时,我已尝试在Stack Overflow上找到的所有解决方案,没有任何内容可以通过官方Facebook应用帐户同步适配器正确检索来自Facebook的照片。
要明确的是,发布“认为”他们工作的解决方案的人可能正在使用HTC感应手机,该手机配有由HTC编写的Facebook同步适配器,其安全要求与官方Facebook应用程序不同。
这是一个安全问题,其中一个方法确实试图访问Facebook照片的字节,你最终会得到一个SqliteException,说请求的内容是受限制的。
与系统进程运行相同的代码会将照片拉得很好。现在就不可能了。
答案 2 :(得分: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与您想要照片的联系人对应。
如果你想限制只有facebook照片,你需要使用ContactsContract.Data.RAW_CONTACT_ID,你应该使用你的联系人ID和基于facebook帐户的过滤器从RawContacts表中获取(假设你知道)您正在寻找什么帐户......可能因同步提供商实施而异...)
答案 3 :(得分: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时才检索照片。然后,您将获得此人的默认图像,无论其在哪里同步。
答案 4 :(得分:0)
绝对没有办法以标准的方式做到这一点。因此,我们必须使用SQL注入,以便能够破解联系人数据库并获取Facebook头像。以下代码适用于在Android 2.2或更高版本上使用Motoblur的大多数Motorolas:
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注入,这需要带有根电话。