Reputation: 3
Android provides the framework to get on device information about calendars, that I can used to see the calendars and events that I've created in Google Calendar.
fun getUpcomingEvents(calendarId: Long): List<CalendarEvent> {
val eventsList = mutableListOf<CalendarEvent>()
val now = Calendar.getInstance()
val next24Hours = Calendar.getInstance().apply {
add(Calendar.HOUR_OF_DAY, 24)
}
val startMillis = now.timeInMillis
val endMillis = next24Hours.timeInMillis
val selection = "${CalendarContract.Events.CALENDAR_ID} = ? AND " +
"${CalendarContract.Events.DTSTART} >= ? AND " +
"${CalendarContract.Events.DTEND} <= ?"
val selectionArgs = arrayOf(calendarId.toString(), startMillis.toString(), endMillis.toString())
val projection = arrayOf(
CalendarContract.Events._ID,
CalendarContract.Events.TITLE,
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND,
// Add other fields you want to retrieve
)
val eventsUri: Uri = CalendarContract.Events.CONTENT_URI
ContentResolver.requestSync(
getCalendarSyncAccount(), // Replace with the relevant account
CalendarContract.AUTHORITY,
Bundle().apply {
putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true)
putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true)
}
)
val cursor: Cursor? = context.contentResolver.query(eventsUri, projection, selection, selectionArgs, null)
cursor?.use {
while (it.moveToNext()) {
val eventIdIndex = it.getColumnIndex(CalendarContract.Events._ID)
val titleIndex = it.getColumnIndex(CalendarContract.Events.TITLE)
val dtstartIndex = it.getColumnIndex(CalendarContract.Events.DTSTART)
val dtendIndex = it.getColumnIndex(CalendarContract.Events.DTEND)
// Get indices for other fields
val eventId = it.getLong(eventIdIndex)
val title = it.getString(titleIndex)
val dtstart = it.getLong(dtstartIndex)
val dtend = it.getLong(dtendIndex)
// Retrieve values for other fields
eventsList.add(CalendarEvent(eventId, title, dtstart, dtend))
}
}
return eventsList
}
This works a treat if I provide a hardcoded time-frame in the past. But the information will only be as up-to-date as the last time I opened the Google Calendar app. The ContentResolver.requestSync(...)
doesn't seem to have an effect. Not directly after I call it, not two days later. Only if I manually update the info by opening the Gcal app. But I don't think I have the rest of the correct boiler-plate for this sync to work.
What I require is the up-to-date calendar information. The Content Provider docs are woefully incomplete in this regard, only really mentioning something about sync adapters as a footnote. Looking for more info, it sounds like what I want, but again there's a big question mark as to what you actually run under onPerformSync
:
override fun onPerformSync(
account: Account,
extras: Bundle,
authority: String,
provider: ContentProviderClient,
syncResult: SyncResult
) {
/*
* Put the data transfer code here.
*/
}
Even in other tutorials I find online, it always seems entirely overcomplicated for simply refreshing data I already have access to and overly generic not really explaining what's required for my use case.
Are these SyncAdapter
s really the right tool for my job? If so, what kind of logic to I need to run to actually get Google Calendar information synced up with the on device info, reliably?
Upvotes: 0
Views: 42