Удалить только один экземпляр повторяющегося события из моего календаря Android

Я просматривал различные посты о том, как удалить только один экземпляр повторяющегося события из календаря моего телефона Android 2.3, но мне не удалось найти идеальный ответ. Пока что лучшее, с чем я столкнулся, это:

Uri eventsUri = Uri.parse("content://com.android.calendar/events");
Uri deleteEventUri = Uri.withAppendedPath(eventsUri, String.valueOf(id2));
DeleteEventActivity.context.getContentResolver().delete(deleteEventUri, null, null);

Где id2 - это идентификатор события, которое я хочу удалить. У меня проблема в том, что я хочу удалить только один экземпляр повторяющегося события, но этот код удаляет все вхождения. Есть ли способ удалить только один экземпляр? Благодарю.

4 ответа

Если кто-то еще борется с этим, я, наконец, взломал его!

Оказывается, вы не удаляете и не исправляете какие-либо записи, фактически вы вставляете новое событие, называемое исключением. Мне потребовалось несколько месяцев, чтобы найти эту информацию где угодно, и даже найдя ее, еще несколько месяцев, чтобы понять, что именно нужно включить в исключение, чтобы заставить его работать, поэтому вот как я это сделал.

Во-первых, запросите фактический экземпляр события, для которого вы хотите отменить одно вхождение. Вам необходимо запросить таблицу CalendarContract.Instances, чтобы получить значения CalendarContract.Instances.TITLE, CalendarContract.Instances.BEGIN и CalendarContract.Instances.EVENT_ID. То, как я делаю это в своем коде, на самом деле не вписывается в контекст этого ответа, так что, надеюсь, вы сможете решить, как это сделать самостоятельно. Сохраните эти значения как:

final String title = eventCursor.getString(0); final long beginl=eventCursor.getLong(1); final int id = eventCursor.getInt(2);

Затем нам нужно настроить новое событие следующим образом:

 final Context context = getApplicationContext();
 final ContentResolver contentResolver = context.getContentResolver();
 final Uri.Builder builder = Uri.parse(
"content://com.android.calendar/events").buildUpon();
 final Cursor eventCursor = contentResolver.query(builder.build(),
new String[] 
   {Events.CALENDAR_TIME_ZONE,Events.ALL_DAY,Events.CALENDAR_ID,Events._SYNC_ID,     Events.OWNER_ACCOUNT }, 
   "_id=" + id, null, null);
 while (eventCursor.moveToNext()) {
final String timezone=eventCursor.getString(0);
final String allday=eventCursor.getString(1);
final long calID=eventCursor.getLong(2);
final String mSyncId=eventCursor.getString(3);
final String account=eventCursor.getString(4);
ContentValues values = new ContentValues();
    values.put(Events.TITLE, title);
    values.put(Events.EVENT_TIMEZONE, timezone);
values.put(Events.ORIGINAL_SYNC_ID, mSyncId);//not 100% sure about this,may also need a date?
values.put(Events.HAS_ALARM, "0");
values.put(Events.HAS_ATTENDEE_DATA,"0");
values.put(Events.ALL_DAY, allday);
    values.put(Events.DTSTART, beginl+3600000);
    values.put(Events.ORIGINAL_INSTANCE_TIME, beginl+3600000);
values.put(Events.STATUS, Events.STATUS_CANCELED);
Uri uri = Uri.withAppendedPath(Events.CONTENT_EXCEPTION_URI,
        String.valueOf(id));
uri = asSyncAdapter(uri, account, CTS_TEST_TYPE);
Uri resultUri = context.getContentResolver().insert(uri, values);
    try {
        int eventID = Integer.parseInt(resultUri.getLastPathSegment()); 
        int debug=eventID;
        } catch (Exception e) {
        int debug=0;
        }
}
static Uri asSyncAdapter(Uri uri, String account, String accountType) {
    return uri.buildUpon()  
    .appendQueryParameter
        (android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
    .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
    .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
}

Надеюсь, это работает, я пытался вырезать части моего кода, которые не имеют отношения к делу. Вы заметите, что мне нужно добавить 3600000 к значению beginl (1 час в миллисекундах). Я предполагаю, что это потому, что мы сейчас находимся в BST, и этот код не будет работать после смены часов, но я буду беспокоиться об этом в то время!

Наконец, я использовал приложение под названием Content Provider Helper, чтобы помочь мне это выяснить. Вы можете использовать его для запроса таблиц вашего контент-провайдера. Я попытался бы создать исключение, используя мой код, затем использовать приложение календаря для телефонов, чтобы удалить экземпляр, и сравнить две записи.

Вот основы

  1. Найдите экземпляр, который вы хотите удалить. (с помощью Instances.query())
  2. Создайте URI исключения с добавленным идентификатором события.
  3. Создайте ContentValues, Поместите значение BEGIN вашего экземпляра как ... Events.ORIGINAL_INSTANCE_TIME. Поместите STATUS_CANCELED как ... Events.STATUS
  4. Теперь только вставьте (yourURI, yourValues) и все!

Вам нужно будет обновить столбец EXDATE исходного события.

Как насчет обновления отдельных экземпляров повторяющегося события? Скажем, у меня есть ежедневное повторяющееся событие с понедельника по пятницу, но я хочу обновить несколько полей (начало, конец/длительность, название, описание, весь день, доступность, статус) только для экземпляра в среду. Как это может быть сделано?

Я попробовал подход, упомянутый @alex-f:

  1. Найти инстансы для среды
  2. Создан URI исключения с добавленным идентификатором.
  3. Создан и помещен BEGIN как ORIGINAL_INSTANCE_TIME.
  4. Я не трогал СТАТУС, так как хочу обновить, а не удалить.
  5. Я также помещаю все другие обновленные значения в свой ContentValues
  6. Выполнять insert(uri, values)

Но это испортило мои данные о событиях:

  1. Когда я запустил приложение Google Календарь, я увидел, что мероприятия в понедельник и вторник больше нет.
  2. Вместо обновления только события по средам все экземпляры по средам, четвергам и пятницам показывают обновленные данные.
Другие вопросы по тегам