Android Question How to read 'repeated / recurring events' of a Calendar ?

AnandGupta

Well-Known Member
Licensed User
Using Don's Library

I can now list all calendars in my phone,

and also list events of a selected calendar,

But, if a event is marked as 'repeat' monthly, say, then it is not showing for next month date range.
Screenshot_2021-03-28-16-51-37.png

i.e. the above event is made in month of March with repeat 'every month', now when I see events for month April, it does not show.

How to read 'repeated events' ?
Our Forum search did not throw lights on it. Please help.

Regards,

Anand
 

AnandGupta

Well-Known Member
Licensed User
Hmm... no reply. This must be very tough job.

I searched for it outside our Forum. Found similar query and probably an answer,

B4X:
String[] projection = new String[] {
        "title", "description", "begin", "eventLocation"
};
String selection = "calendar_id = " + calID;
String path = "instances/when/" + (now - window) + "/" + (now + window);
String sortOrder = "begin DESC";
Cursor managedCursor = getCalendarManagedCursor(
        projection, selection, path, sortorder);

But it is Java code, I think. How can I make it B4A code ?
Any help / guide is appreciated.

Regards,

Anand
 
Upvote 0

walt61

Active Member
Licensed User
Hi @AnandGupta,

Good timing as I needed to figure that out too (I'm working on a class based on @DonManfred's thread, will post a thread when it's ready, can't promise an ETA for now).

It took me quite some time to figure it out, but this seems to work; details about recurring event instances can be found at https://developer.android.com/reference/android/provider/CalendarContract.Instances. Apparently the instances are kept in a separate database (or table), I found that out at https://stackoverflow.com/questions...dar-recurring-events-have-wrong-end-date-time.

B4X:
    Dim econ As EventConstants ' This type comes from DonManfred's GoogleCalendarClient library
    Dim ECON_INSTANCE_BEGIN As String = "begin"
    Dim ECON_INSTANCE_END As String = "end"
    Dim ECON_INSTANCE_EVENT_ID As String = "event_id"

    Dim eventInstanceProjection() As String = Array As String(econ.ID, econ.ALL_DAY, econ.AVAILABILITY, _
                                                            econ.CALENDAR_ACCESS_LEVEL, econ.DESCRIPTION, econ.DTEND, _
                                                            econ.DTSTART, econ.DURATION, econ.LOCATION, _
                                                            econ.ORGANIZER, econ.TITLE, econ.CUSTOM_APP_PACKAGE, _
                                                            econ.CUSTOM_APP_URI, econ.DISPLAY_COLOR, econ.EVENT_COLOR, _
                                                            econ.EVENT_COLOR_KEY, econ.EVENT_END_TIMEZONE, econ.EVENT_TIMEZONE, _
                                                            econ.EXDATE, econ.EXRULE, econ.RDATE, _
                                                            econ.RRULE, econ.STATUS, econ.SYNC_ID, _
                                                            econ.VISIBLE, ECON_INSTANCE_BEGIN, ECON_INSTANCE_END, _
                                                            ECON_INSTANCE_EVENT_ID)

    Dim repeatRecurringInstancesFrom As Long = DateTime.Add(DateTime.Now, 0, -1, 0) ' DateTime from
    Dim repeatRecurringInstancesTo As Long = DateTime.Add(DateTime.Now, 0, 1, 0)' DateTime to

    Dim instanceSelectionArgs() As String
    Dim instanceURI As Uri
    instanceURI.Parse("content://com.android.calendar/instances/when/")
    instanceURI.WithAppendedPath(instanceURI, repeatRecurringInstancesFrom)
    instanceURI.WithAppendedPath(instanceURI, repeatRecurringInstancesTo)
    Dim crsr As Cursor = cr.Query(instanceURI, eventInstanceProjection, "", instanceSelectionArgs, ECON_INSTANCE_EVENT_ID & " ASC")
'...

In other words,
- the URI differs, and contains the DateTime window that is requested
- use cursor (and 'projection') columns "begin" and "end" instead of "DTstart" and "DTend" (the former 2 are relevant to instances, the latter 2 are relevant to the 'main' event entries)
- column "event_id" contains the instance's id (whereas "id" contains that of the 'main' event entry)

Hope this helps !
 
Upvote 0

AnandGupta

Well-Known Member
Licensed User
Good timing as I needed to figure that out too (I'm working on a class based on @DonManfred's thread, will post a thread when it's ready, can't promise an ETA for now).
Hi @walt61 ,

Thanks a lot for your reply and advise.

As I did not receive any reply prior to yours, I understand that this is not so simple job. So take your time, no hurry.
It will eventually help other members too.

I will try your suggested code and revert.

Regards,

Anand
 
Upvote 0

AnandGupta

Well-Known Member
Licensed User
Hi @walt61 ,

I tried your suggested code, but no result, no error either.

Will wait for your library.

I can upload my project here, if it helps.

Regards,

Anand
 
Upvote 0

walt61

Active Member
Licensed User
Fortunately it's not something weird that happens on your device but not on mine :)

Replace this line in Button3_Click
B4X:
Dim crsr As Cursor = cr.Query(instanceURI, eventInstanceProjection, "", instanceSelectionArgs, ECON_INSTANCE_EVENT_ID & " ASC")

With this one:
B4X:
    cr.QueryAsync(instanceURI, eventInstanceProjection, econ.CALENDAR_ID & "=" & EditText1.Text, instanceSelectionArgs, ECON_INSTANCE_EVENT_ID & " ASC")

What was wrong is:
- you were expecting the async version to be used (the next line is the 'wait for' for the query completion) but were using the synchronous version from my example
- you didn't pass a value for the 'selection' parameter; the calendar id needs to be specified there

I'm getting the results now - do you see them too?
 
Upvote 0

AnandGupta

Well-Known Member
Licensed User
What was wrong is:
- you were expecting the async version to be used (the next line is the 'wait for' for the query completion) but were using the synchronous version from my example
- you didn't pass a value for the 'selection' parameter; the calendar id needs to be specified there
Thanks a lot @walt61 for fixing my bug.

I missed that it was not async .

Yes it is showing results. I can move to next phase now. Thanks.

Still I will like to use your library too, when you complete it.

Regards,

Anand
 
Upvote 0
Top