So I encountered an issue on an Android 10 phone where deleted events are still present when I query the user's calendar. The problem persisted across several hours (3 at the time of writing this)
I've looked through the following posts already in an attempt to find solutions, but none of them seemed to have worked for me, and I'm not sure if I'm just implementing their solutions incorrectly, if something's wrong with the phone, or whatever else.
Here's the posts I mentioned above:
Calendar deleted event exists in cursor
Deleting events from Calendar not being deleted
Android CalendarContract, deleting a recurring event causes all events to disappear on calendar?
Querying android calendar retrieves even deleted events
I know that when a user deletes something off their calendar, there's a possibility of it hanging around in whatever DB or structure Android stores the events in with a dirty
or deleted
flag set. My problem is that the events are both still present, and have neither of the previously mentioned flags set.
Additionally, I know that it could be a sync issue between Google's calendar and whatever local datastore the events are being stored in, but this issue persisted on the phone I'm testing on even after pulling in newly created events from the user's calendar, which makes it seem to me that the local datastore and the calendar should be in sync.
Here's the full code for the file where this problem is occurring for me - some things may not be related to the issue but I'm including everything just in case.
package com.example.plumbingreportgenerator.util.calendar;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CalendarContract;
import android.provider.CalendarContract.*;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class EventReader {
// the context of the application this is being used in
private Context applicationContext;
public static final String[] EVENT_PROJECTION = new String[] {
Events.CALENDAR_ID, // 0
Events.TITLE, // 1
Events.DTSTART, // 2
Events.DELETED,
Events.DIRTY
};
// The indices for the projection array above.
private static final int PROJECTION_CALENDAR_ID_INDEX = 0;
private static final int PROJECTION_TITLE_INDEX = 1;
private static final int PROJECTION_DTSTART_INDEX = 2;
private static final int PROJECTION_DELETED_INDEX = 3;
private static final int PROJECTION_DIRTY_INDEX = 4;
public EventReader(Context context){
applicationContext = context;
}
// use android and java date libraries to determine the start of the month given by year and month
private static long getStartOfMonth(int year, int month){
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.set(java.util.Calendar.YEAR, year);
cal.set(java.util.Calendar.MONTH, month);
cal.set(java.util.Calendar.DAY_OF_MONTH, 1);
cal.set(java.util.Calendar.HOUR_OF_DAY, 0);
cal.set(java.util.Calendar.MINUTE, 0);
cal.set(java.util.Calendar.SECOND, 0);
cal.set(java.util.Calendar.MILLISECOND, 0);
return cal.getTimeInMillis();
}
private static long getEndOfMonth(int year, int month){
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.set(java.util.Calendar.YEAR, year);
cal.set(java.util.Calendar.MONTH, month);
cal.set(java.util.Calendar.DAY_OF_MONTH, cal.getActualMaximum(java.util.Calendar.DAY_OF_MONTH));
cal.set(java.util.Calendar.HOUR_OF_DAY, 23);
cal.set(java.util.Calendar.MINUTE, 59);
cal.set(java.util.Calendar.SECOND, 59);
cal.set(java.util.Calendar.MILLISECOND, 999);
return cal.getTimeInMillis();
}
// gets event titles for the given calendar from the given month
public ArrayList<EventTitleDateTuple> getEventDetailsForMonth(long calendarId, int year, int month){
// get the millisecond values for the start and end of the month given by year and month
long startOfMonth = getStartOfMonth(year, month);
long endOfMonth = getEndOfMonth(year, month);
// Create cursor and query for the events table
Cursor cur = null;
ContentResolver cr = applicationContext.getContentResolver();
Uri uri = Events.CONTENT_URI;
String selection = "((" + Events.CALENDAR_ID + " = ?) AND (" + Events.DELETED + " != 1) AND (" + Events.DIRTY + " != 1 ))";
String[] selectionArgs = new String[] {Long.toString(calendarId)};
// Submit the query and get a Cursor object back.
cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);
ArrayList<EventTitleDateTuple> eventDetails = new ArrayList<EventTitleDateTuple>();
while (cur.moveToNext()) {
long calID = 0;
String title = null;
long dtStart = 0;
// Get the field values
calID = cur.getLong(PROJECTION_CALENDAR_ID_INDEX);
title = cur.getString(PROJECTION_TITLE_INDEX);
int deleted = cur.getInt(PROJECTION_DELETED_INDEX);
int dirty = cur.getInt(PROJECTION_DIRTY_INDEX);
dtStart = cur.getLong(PROJECTION_DTSTART_INDEX);
// if the start date of the event is after this month and before the end of this month
if(dtStart >= startOfMonth && dtStart <= endOfMonth && title != null && title.length() > 0 && deleted != 1 && dirty != 1 && !title.contains("testy mates face")){
// the deleted events still make it through to here
eventDetails.add(new EventTitleDateTuple(title, dtStart));
}
}
cur.close();
return eventDetails;
}
}
This is not a problem with deleting events, it is problem with syncing. Sometimes in 2020/2021 Google added a "feature" (or a bug) in form of some kind of annoying cache.
In reality it means, from now on (unlike before) you simply never know if you have a fresh data or outdated data from their cache. The only way to somewhat force their cache to update regularly is to have constantly turned on auto-syncing of ALL CALENDARS, all the time.
This way changes take only seconds and Google Calendar cache is always being updated. If the auto-syncing of just 1 calendar is turned off, from unknown reasons cache is not updated on time and often it takes hours to reflect changes...
Similar problems can be find on these links:
Android CalendarContract.Instances table returns old values
Android Calendar Provider does not return latest data
Or even here on Google Support page:
https://support.google.com/calendar/thread/47536340?hl=en
I would love to know who in Google had this genius idea...Argh