0

私は最近、連絡先を調べて、写真セットを持たない連絡先の ID アイコンを作成するコードをいじっていました。ほとんどの場合、これは非常にうまく機能しましたが、何らかの理由で更新されない連絡先がいくつかあります. ログ出力は、写真を作成していると言っています。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());
    }
}

これはすべてバックグラウンド サービス内で行われ、すべての連絡先は Google 経由で同期されます。最後に注意すべきことは、写真が利用可能かどうかを確認するために ContactsContract.Contacts.openContactPhotoInputStream() を呼び出すと、これらの選択した連絡先は常に null を返すことです (写真を更新しようとした後でも)。

何が起こっているのかについての助けや洞察は大歓迎です。

4

0 に答える 0