假设我通过在地址簿上使用某些查询找到了联系人。通过执行查询来找到来自特定帐户(例如WhatsApp)的联系信息,正如我写的那样here。
现在我有一张图片,我希望用它来更新联系人的照片。
我根据我在StackOverflow上找到的更新联系人照片的内容创建了代码。
事实上,有些用户声称它没有做任何事情。我不确定是什么原因造成的。也许访问联系人的方式不好(id / lookup-key?)。也许我需要一个额外的地址簿字段。也许查询本身是错误的......
我在弄清楚这个问题的原因时遇到了问题,因为我无法重现它,大多数用户也是如此。
这就是我的所作所为:
final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
final String lookupKey=...;
try {
FileInputStream fileInputStream = new FileInputStream(file);
final byte[] photoByteArray = new byte[(int) file.length()];
fileInputStream.read(photoByteArray);
fileInputStream.close();
final Builder builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(Data.LOOKUP_KEY + "=?" + " AND " + Data.MIMETYPE + "=?", new String[]{lookupKey, Photo.CONTENT_ITEM_TYPE});
builder.withValue(Photo.PHOTO, photoByteArray);
ops.add(builder.build());
file.delete();
} catch (IOException e) {
e.printStackTrace();
}
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops )
代码有什么问题吗?
我应该以不同方式更新联系人吗?
为什么有些用户无法更新?查找键不够吗?它可以更新错误的数据吗?
我已经读过某些地方,我可能需要使用RAW-contact-id,但无法找到准确的操作。查询然后更新/插入?
有人建议开发人员应考虑使用其应用帐户来保存照片,而不是更新,因为它可能会导致问题。这是真的吗?
答案 0 :(得分:2)
我在代码中看到了许多可能的问题:
newUpdate
),如果目前没有照片,则应该newInsert
代替。OutOfMemoryError
上崩溃,因为它们的内存非常有限,或者因为内存目前被大量使用别的。您应该使用try / catch包装整个代码,包括applyBatch,并捕获所有异常/错误并将其报告给日志,最好也报告给您的错误报告库(Firebase / crashlytics / etc)PHOTO
字段,您还应该更新PHOTO_FILE_ID
字段,因为某些应用可能会选择阅读PHOTO_FILE_ID
并从中获取照片代替。SUPER_PRIMARY
,因此如果同一个联系人中的其他一些RawContact也有照片,则可能会“赢”,并成为该联系人的主要照片以下代码应该有所帮助:
// To simplify the code i didn't worry about try/catch, freeing resources,
// or running slow queries on the main thread, make sure your code does!
public ContentProviderOperation setPhoto(int contactId, byte[] photoByteArray) {
long rawId = getRawId(contactId);
ContentProviderOperation.Builder builder;
String selection = Data.RAW_CONTACT_ID + " = '" + rawId + "' AND " + Data.MIMETYPE + "= '" + Photo.CONTENT_ITEM_TYPE + "'";
Cursor cur = contentResolver.query(Data.CONTENT_URI, new String[]{ Data._ID }, selection, null, null);
if (cur.moveToFirst()) {
// this RawContact already has a photo!
Long photoDataId = cur.getLong(0);
Uri uri = ContentUris.withAppendedId(Data.CONTENT_URI, photoDataId);
builder = ContentProviderOperation.newUpdate(uri);
} else {
// this RawContact has no photo.
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValue(Data.RAW_CONTACT_ID, rawId);
}
builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
builder.withValue(Data.IS_SUPER_PRIMARY, 1);
builder.withValue(Data.IS_PRIMARY, 1);
builder.withValue(Photo.PHOTO, photoByteArray);
builder.withValue(Photo.PHOTO_FILE_ID, null);
return builder.build();
}
private long getRawId(long contactId) {
String selection = RawContacts.CONTACT_ID + "='" + contactId + "'";
Cursor cur = contentResolver.query(RawContacts.CONTENT_URI, new String[]{ RawContacts._ID }, selection, null, null);
try {
if (cur.moveToNext()) {
return cur.getLong(0);
}
} finally {
cur.close();
}
return 0;
}