我正在尝试通过应用程序中的ContentProvider
更新联系人图像。这几乎总是有效的(我在生产应用程序中使用这种方法大约 4 年,有 ~50000 个用户和 1M 下载量(。我几乎从来没有遇到过问题,但似乎该功能不是防弹的。它在一个用户设备上反复失败,我不知道为什么。
我做什么
我只有位图并尝试保存已知的联系人ID。如果联系人已有图像,我会替换它,否则我会添加图像。
结果和奎西顿
联系人图像不会在一个用户设备上更新。日志显示,失败的联系人还没有图像。这很好,所以我只是创建一个新的。该函数返回一个Uri
但此为 null,因此保存图像失败。为什么?有什么想法吗?
日志信息:
联系人图像集 - 已更新: -1, 新 URI: 空, 旧照片 ID: -1
设备信息:
- 其他联系人确实有效,只有少数联系人失败
- 该设备有足够的剩余空间,所以这也不能是源
- 用户仅使用Google通讯录,而不使用其他服务(如Outlook或类似服务,因此没有只读联系人或类似服务(
法典
// the id of the contact
long contactRawId = ...;
// 1) get bitmap
Bitmap bitmap = ...;
// 2) Convert Bitmap to byte
byte[] photo =
// 3) save or update contact picture via content provider
ContentValues values = new ContentValues();
int photoId = -1;
String where = ContactsContract.Data.RAW_CONTACT_ID + " == " +
contactRawId + " AND " + ContactsContract.Contacts.Data.MIMETYPE + "=='" +
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = MainApp.get().getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
null,
where,
null,
null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if (cursor.moveToFirst()) {
photoId = cursor.getInt(idIdx);
}
cursor.close();
values.put(ContactsContract.Data.RAW_CONTACT_ID, contactRawId);
values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, photo);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
int updated = -1;
Uri newUri = null;
if (photoId >= 0) {
updated = MainApp.get().getContentResolver().update(
ContactsContract.Data.CONTENT_URI,
values,
ContactsContract.Data._ID + " = " + photoId, null);
} else {
newUri = MainApp.get().getContentResolver().insert(
ContactsContract.Data.CONTENT_URI,
values);
}
L.d("Contact image set - updated: %d, newUri: %s, old photoId: %d", updated, newUri, photoId);
观察
- 一个有这个问题的人有一个扎根的OnePlus 3T运行牛轧糖7.1.1
- 与此同时,他清除了应用程序数据,现在所有联系人都在工作
可能您正在主线程中运行更新过程。 在AsyncTask
中移动更新过程。
繁重的任务或包含异步操作(如下载任务(的任务必须始终在另一个线程中移动,否则它们将被绑定到 UI 线程并在它们不能足够快地完成工作时跳过,从而导致奇怪的不良效果。
这看起来不像是代码的问题,而是手机的问题
它在一个用户设备上反复失败,我不知道为什么。
我在使用应用程序时遇到了类似的问题,但功能不同。要解决此问题,您需要使用用户的设备并调试应用程序(您可以克隆它(。在单个设备上出现问题,免除其他设备表明该设备是问题所在,它可能需要"奇怪"权限。