我最近在玩一些代码,这些代码通过我的联系人并为没有照片集的任何联系人创建一个身份图标。在大多数情况下,这最终工作得很好,但由于某种原因,我有一些不会更新的联系人。日志输出说它正在创建照片。update() 返回 1 表示 1 行已更新,并逐步执行联系人的代码,该联系人似乎从未显示过新照片看起来不错。
只有少数几个没有更新的事实真正困扰着我,我猜这里一定有我做错或遗漏的事情。
private void processContacts() {
Cursor cursor = getContacts();
Log.d(TAG, "Processing " + cursor.getCount() + " contacts");
while(cursor.moveToNext()) {
final long contactId = cursor.getLong(0);
final String name = cursor.getString(1);
if (!TextUtils.isEmpty(name)) {
final Uri contactUri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
contactId);
if(ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(),
contactUri, true) == null) {
Log.d(TAG, String.format("Creating identicon for %s", name));
generateIdenticon(contactId, name);
} else {
Log.i(TAG, String.format("%s already has a contact photo", name));
}
}
}
cursor.close();
}
private Cursor getContacts() {
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME };
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
return getContentResolver().query(uri, projection, null, null, sortOrder);
}
private void generateIdenticon(long contactId, String name) {
if (!TextUtils.isEmpty(name)) {
updateNotification(getString(R.string.identicons_creation_service_running_title),
String.format(getString(R.string.identicons_creation_service_contact_summary),
name));
final byte[] hash = Identicon.generateHash(name);
final byte[] identicon = Identicon.generateIdenticonByteArray(hash);
if (identicon == null) {
Log.e(TAG, "generateIdenticon() - identicon for " + name + " is null!");
} else {
if (!setContactPhoto(getContentResolver(), identicon, contactId)) {
Log.e(TAG, "Unable to save identicon for " + name);
}
}
}
}
private boolean setContactPhoto(ContentResolver resolver, byte[] bytes, long personId) {
ContentValues values = new ContentValues();
int photoRow = -1;
String where = ContactsContract.Data.RAW_CONTACT_ID + " == " +
String.valueOf(personId) + " AND " + ContactsContract.Data.MIMETYPE + "=='" +
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = resolver.query(
ContactsContract.Data.CONTENT_URI,
null,
where,
null,
null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if(cursor.moveToFirst()){
photoRow = cursor.getInt(idIdx);
}
cursor.close();
values.put(ContactsContract.Data.RAW_CONTACT_ID, personId);
values.put(ContactsContract.Data.IS_PRIMARY, 1);
values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, bytes);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
if (photoRow >= 0) {
final int rowsUpdated = resolver.update(ContactsContract.Data.CONTENT_URI,
values, ContactsContract.Data._ID + "=" + photoRow, null);
return rowsUpdated >= 1;
} else {
final Uri uri = resolver.insert(ContactsContract.Data.CONTENT_URI, values);
return uri != null && !TextUtils.isEmpty(uri.toString());
}
}
所有这些都是在后台服务中完成的,我所有的联系人都通过谷歌同步。最后要注意的一件事是,当我调用 ContactsContract.Contacts.openContactPhotoInputStream() 以查看照片是否可用时(即使在我尝试更新照片之后),这些选择联系人总是返回 null。
非常感谢任何有关可能发生的事情的帮助或见解。