Я программно создал контакт в адресной книге Android, в котором есть имя и номер телефона.Теперь я хотел бы добавить фотографию к этому контакту, но я не могу заставить это работать.Я не получаю сообщение об ошибке, но фотография, кажется, не добавляется.
Если я создаю новый контакт с фотографией, фотография добавляется правильно, и я могу обновить существующую фотографию этойсвязаться также.Единственная проблема - это контакт без фотографии.
Я уже прочитал несколько решений здесь и здесь , и попробовал несколько вариантов на основе этих ответов, но ни один из них не работает.Мое лучшее предположение, что я делаю что-то не так с RAW_CONTACT_ID
.Кто-нибудь, кто может найти мою ошибку?
private void createNewContact()
{
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_TYPE, MY_ACCOUNT_TYPE);
builder.withValue(RawContacts.ACCOUNT_NAME, MY_ACCOUNT_NAME);
ops.add(builder.build());
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
builder.withValue(StructuredName.GIVEN_NAME, myName);
ops.add(builder.build());
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
builder.withValue(Phone.TYPE, Phone.TYPE_WORK);
builder.withValue(Phone.NUMBER, myPhoneNumber);
ops.add(builder.build());
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
builder.withValue(Photo.PHOTO, myPhotoByteArray);
ops.add(builder.build());
try
{
context.getContentResolver().applyBatch(AUTHORITY, ops);
}
catch (Exception e)
{
// Handle exception
}
}
private static final String BASIC_SELECTION = RawContacts.ACCOUNT_TYPE + "='" + MY_ACCOUNT_TYPE + "'";
private void editContact() {
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(BASIC_SELECTION + " AND " + Data.MIMETYPE + "='" + StructuredName.CONTENT_ITEM_TYPE + "'", null);
builder.withValue(StructuredName.GIVEN_NAME, myName);
ops.add(builder.build());
builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(BASIC_SELECTION + " AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'" + " AND " + Phone.TYPE + "='" + Phone.TYPE_WORK + "'", null);
builder.withValue(Phone.NUMBER, myPhoneNumber);
ops.add(builder.build());
if (isContactWithoutPhoto())
{
// Contact without photo: insert new photo
// TODO: this part doesn't work yet!
int rawContactId = getRawContactId();
if (rawContactId != -1)
{
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValue(Data.RAW_CONTACT_ID, rawContactId);
builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
builder.withValue(Photo.PHOTO, myPhotoByteArray);
ops.add(builder.build());
}
}
else
{
// Contact already has a photo: update
builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(BASIC_SELECTION + " AND " + Data.MIMETYPE + "='" + Photo.CONTENT_ITEM_TYPE + "'", null);
builder.withValue(Photo.PHOTO, myPhotoBytes);
ops.add(builder.build());
}
try
{
context.getContentResolver().applyBatch(AUTHORITY, ops);
}
catch (Exception e)
{
// Handle exception
}
}
private int getRawContactId()
{
int rawContactId = -1;
Cursor cursor = null;
try
{
cursor = App.getContext().getContentResolver().query(RawContacts.CONTENT_URI, null, ACCOUNT_TYPE_SELECTION, null, null);
if (cursor != null && cursor.moveToFirst())
{
rawContactId = cursor.getInt(cursor.getColumnIndex(RawContacts._ID));
}
}
finally
{
if (cursor != null)
{
cursor.close();
}
}
return rawContactId;
}
РЕДАКТИРОВАТЬ:
Мне нужен только один контакт, который создается один раз, после чего ему нужно толькорегулярно обновляться.Этот контакт сохраняется в собственной учетной записи с типом MY_ACCOUNT_TYPE и именем MY_ACCOUNT_NAME.Следовательно, builder.withSelection(BASIC_SELECTION
для каждой операции обновления, в которой вместо идентификатора используется MY_ACCOUNT_TYPE.
Я также попытался добавить этот же выбор к части «обновить фотографию на существующем контакте», чтобы реализовать ее больше какдругой код «обновления», потому что я хочу быть уверенным, что обновляю фотографию ТОЛЬКО для этого единственного контакта:
int rawContactId = getRawContactId();
if (rawContactId != -1)
{
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withSelection(BASIC_SELECTION + " AND " + Data.MIMETYPE + "='" + Photo.CONTENT_ITEM_TYPE + "'", null);
builder.withValue(Data.RAW_CONTACT_ID, rawContactId);
builder.withValue(Photo.PHOTO, myPhotoByteArray);
ops.add(builder.build());
В этом случае приложение явно вылетает с ошибкой java.lang.IllegalArgumentException: only updates, deletes, and asserts can have selections
.Идентификатор уже собран с помощью BASIC_SELECTION
, поэтому я ожидаю, что таким образом будет обновлен правильный контакт.
В случае, если кто-то задается вопросом, какой (статический) импорт используется для ContactsContract:
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.PhoneLookup;
import static android.provider.ContactsContract.AUTHORITY;
import static android.provider.ContactsContract.CommonDataKinds.Note;
import static android.provider.ContactsContract.CommonDataKinds.Phone;
import static android.provider.ContactsContract.CommonDataKinds.StructuredName;
import static android.provider.ContactsContract.Data;
import static android.provider.ContactsContract.RawContacts;