B4A Library Calendar Library

:)Hi,
Having had a need to be able to create and delete calendar events I produced my first calendar library (most of the code I got from the net).
The functions are;
GetListOfAllCalendars(boolean)
- this will return a 'Map' with the calendar Id and name. With this ID we can then create or delete events in this calendar.

CreateEvent(int CalID, String Title, String Desc, String Location, long StartTime, long EndTime, String RRule, boolean AllDay)
- used to create a calendar event using the calendar ID found above. At the moment the fields allowed are Calendar ID, TITLE, DESCRIPTION, LOCATION, STARTTIME, ENDTIME, Recurring Rule and ALLDAY.

Added with V1.1
CreateEventWithReminder(int CalID, String Title, String Desc, String Location, long StartTime, long EndTime, int ReminderTime, String RRule, boolean AllDay)
- used to create a calendar event using the calendar ID found above. At the moment the fields allowed are Calendar ID, TITLE, DESCRIPTION, LOCATION, STARTTIME, ENDTIME, Reminder Time, Recurring Rule and ALLDAY.

GetListofAllEventsforCalendar(int)
- using the calendar ID we can get a 'List' of all events for that calendar, items returned are the same as in the CreateEvent as well as the Event ID. the data is in the form of a List you just need to iterate thru it.

GetListofEventsforCalendarBetweenDates(int, long, long)
- As above but you can specify start and finish dates/time in milliseconds from epoch.

ListofEventsWithDescKeywordBetweenDates(int, String, long, long)
- similar to above but filter on 'string' in the Description field.

ListofEventsWithTitleKeywordBetweenDates(int, String, long, long)
- this time filter on Title field

DeleteCalendarEntry(int)
- once you have the event ID you can delete it with this routine.

This library works on the "unofficial" google model which works directly on the calendars on the phone its self this then syncs up to your google account online. The advantage is no problems with authorization but it probably will not work with all phones. I do hope to create a similar one using the new API which will work on everything and will not stop working. I have tried it on a HTC Desire 2.2 and an Asus tablet 3.1? and it worked on both.

To use it in your program,
B4X:
Dim Mycal As MyCalendar
Mycal.Initialize
myMap = Mycal.GetListOfAllCalendars(False)
Mycal.CreateEvent(1,"Test title 7","This is a test of the create event","At Work",(DateTime.Now ),(DateTime.Now + 3600000),False)
The code is well commented so should not be a problem.
Hope it is of use to someone, it has lots of expansion capability, update calendar event, add more fields to the create event routine, search on different fields etc.
Edward

Edit; Version 1.1 added,
  1. New module added to create events with reminder
  2. Added a recurring Rule field to the Create Event modules, see RFC 5545 - Internet Calendaring and Scheduling Core Object Specification (iCalendar) for all the many options available, it is then passed as a string e.g. "FREQ=MONTHLY;WKST=SU;BYDAY=2WE"
  3. Calendar Example attached, this demonstrates
    • Locating Calendar ID
    • Getting list of events for the selected calendar for the previous month.
    • Creating an event with a reminder
    • Creating an all day event
    • Creating a recurring event
The list of Calendars is loaded into a listview with the Calendar Name and ID.
A Preference Screen (AHPreferenceActivity) is also created to show how the calendar selection can be achieved thru a settings page on menu press.

Edit; Version 1.2 added.
  1. Updated to include the new Calendar API for Android 4 aka ICS
  2. Example program now shows events in a listview, a long_click gives the option to delete the event.
  3. To use the example program select the radio button for the required action then select the calendar you want this action on. The event list is not dynamic so after adding or deleting an event you will have to select read events for that calendar to update the listview.

Edit; Version 1.3 added see post #39 for details
  • New function 'ListExtendedCalendarEntryDetails(Value)' this returns a Map containing
    * hasAlarm
    * recurRule
    * duration
    * minutes
    * method
    * AttendeeName
    * AttendeeEmail
    * AttendeeStatus
  • Sorted bug where ICS did not get the recurring events.

Edit; Version 1.4 added
The bug that I thought I had fixed in v1.3 was not fixed this sorts it out (I hope)

Edit; Version 1.5 added
Details for recurring event now show the start and end time for the recurring event not the original event.

Edit; Version 1.6 added
Changed library to a process object. (no longer an activity object)

Edit; Version 1.7 added
Bug fixed where event timezone was not entered on pre 4.0 android non "all day" event.

Edit; Version 1.8 added
No change in functionality but now the events are returned sorted based on the date/time of the start of the event.

Edit; Version 1.9 added
The 2 create event methods now return the created event ID as a string

Edit; Version 1.11 added
Attached is an updated version of the library with 2 new functions;
GetEventDetails & UpdateEvent.
At the moment UpdateEvent allows you to change the
1) Title
2) Description
3) Location
4) StartTime
5) EndTime
If you do not want to change any of the first 3 pass "" for the relevant one.
To change the time set the ChangeTime Boolean to 'true' and pass both the start & end times. Both must be passed as the system can update both or neither not just one. If ChangeTime is set to 'false' a value must be still be entered in the StartTime & EndTime fields as the function still expects values even if they are not used. Normally I would not use the Boolean and just pass -1 for the time to indicate that it is not to be used but -1 is a valid time (1 millisecond before the epoch Jan 01 1970).

Fixed a bug where 'GetListOfAllCalendars(False)' only returned your "owned" calendars instead of all calendars.

Edit; Version 1.12 added See this post for some more detail
Added function 'GetExtendedListOfAllCalendars(int)'
This returns a LIST with the following calendar values
  • calID (long)
  • name (string)
  • displayName (string)
  • colourName (string)
  • location (string)
  • timezone (string)
  • accesslevel (string)
  • owner account (string)
The value passed in the function is the Access Level, details of the different values are contained in the info popup in B4A.
The Returned LIST can contain no calendars to many calendars depending on the Access Level used. If there is more then 1 calendar the group of 8 values for the additional calendars is repeated.
 

Attachments

  • CalendarExample v1.2.zip
    9.5 KB · Views: 3,822
  • calendar2 V1.12.zip
    18.7 KB · Views: 2,286
  • calendar2_v1.13.zip
    20.4 KB · Views: 1,268
Last edited:

Paulsche

Well-Known Member
Licensed User
Longtime User
ok, I've tested again with emulator, it is probably actually the ICOSWorldForecast Library, without the app running in the emulator with 2.2 Platform
Thanks for the help
 

Harris

Expert
Licensed User
Longtime User
Is it possible to sort the list returned by: GetListofEventsforCalendarBetweenDates (by start date)

I present a ListView from the items returned with GetListofEventsforCalendarBetweenDates. For example: Date Range = SD: Today ED: Today + 7. ListView shown below..

Saturday
Session 1 - 11/17/2012
Session 2 - 11/17/2012

Sunday
Session 5 - 11/18/2012

Saturday
Session 7 - 11/17/2012

The problem I encounter is when "new" calendar items are added, they are appended to the end of the list. So as in the above example, I get two sections for Saturday when I wish all items, for the same date, to appear under the same section.

Thanks
 

lagore

Active Member
Licensed User
Longtime User
Yes it should be easy to sort it by the date (makes more sense that way), should get it done over the next day or two.
 

lagore

Active Member
Licensed User
Longtime User
Version 1.8 added, this now sorts the returned events based on the date/time of the start of the event.
 

Harris

Expert
Licensed User
Longtime User
Most excellent. I shall try it out.
 

Harris

Expert
Licensed User
Longtime User
Great! Works as expected.

Thanks very much.
 

mcmanu

Active Member
Licensed User
Longtime User
Hi

I testet your nice Lib, but unfortunately it brings up an error message

galaxy s2 (android 4.0.4)
 

Attachments

  • Screenshot_2013-01-05-21-11-40.png
    Screenshot_2013-01-05-21-11-40.png
    74.7 KB · Views: 253
Last edited:

lagore

Active Member
Licensed User
Longtime User
Do you have a small app that you could upload (zip) so that I could have a look at it, I have never seen that error and I use the calendar library every day on an HTC X with 4.0
 

mcmanu

Active Member
Licensed User
Longtime User
Do you have a small app that you could upload (zip) so that I could have a look at it, I have never seen that error and I use the calendar library every day on an HTC X with 4.0

Thats the example i downloaded from the first Post, maybe its an android 4.0.4 issue!?
 

lagore

Active Member
Licensed User
Longtime User
Ok I think the problem is the example app it had not been changed since some of the updates, you should be able to write a very simple app to see your calendars and create/delete events. I will not be at my computer until tomorrow so will look at it then. It is not a 4.0.4 issue as that is in fact what I have.

Sent from my HTC One X using Tapatalk 2
 

mcmanu

Active Member
Licensed User
Longtime User
HI

All right, Thank you :) i will make my own app with the implementation of this lib and test it again :)
Thank you :)
 

lagore

Active Member
Licensed User
Longtime User
I just downloaded and ran the example and it ran fine for me (it is up to date), I presume it is an actual device and not the emulator you are running it on.
 

mcmanu

Active Member
Licensed User
Longtime User
mhh Strange, i will recompile it tomorrow and have a look :)
Yes i used my galaxy s2 :)
 

Harris

Expert
Licensed User
Longtime User
When using CreateEvent - All Day..

Question: The start and finish time must be on a midnight boundary... What does this mean exactly?

I want to create an all day event for Jan 15, 2013. What would be the start and end times be? A code example would be nice.

Thanks
 

lagore

Active Member
Licensed User
Longtime User
A midnight boundary is equal to a time of 00:00 on any day. So for your date we need to create a long which is = 15 Jan 2013 00:00. This is achieved using 'DateTime.DateParse("15/JAN/2013")' this will return a long (which if you converted to a time will give 00:00 on that date in that timezone), in the timezone I am currently this is 1358226000000 but an all day event has to be referenced to UTC timezone so using ' DateTime.GetTimeZoneOffsetAt' we calculate the difference between local timezone and UTC timezone, in my current case it is -18000000 when this is added to the local midnight we get 1358208000000 a quick calculation on the offset above means I am 5hrs behind UTC or eastern USA. If you use the code below calstart should always be the same no matter what part of the world you are in. This makes sense if you think about how your calendar/events/appointments changes when you change timezone, an all day event still shows as an all day event but the appointment you set at home is now out by the difference in timezones. The end time for the all day event is is the start time + 1 day.
B4X:
Sub CreateEvent
   DateTime.DateFormat = "dd/MMM/yyyy"                     'Set Date format to whatever you use
   Dim StartDate As Long = DateTime.DateParse("15/JAN/2013")   'StartDate now contains a date on the local midnight boundary
   Dim myCal As MyCalendar
   Dim calstart, offset As Long
   offset = DateTime.GetTimeZoneOffsetAt(StartDate) * DateTime.TicksPerHour   'Get the offset in ticks from local timezone to UTC timezone
   calstart = StartDate + offset      'Calstart now contains a time which is 0000 on 15 Jan 2013 in other words a midnight boundary
                              'use  DateTime.GetTimeZoneOffsetAt(StartDate) and not DateTime.TimeZoneOffset as the first one adjusts for winter summer time change 
   myCal.Initialize
   
   myCal.CreateEvent(2, "Birthday", "All day birthday party", "At Home", calstart, (DateTime.Add(calstart, 0, 0, 1)),Null, True)
End Sub
 

Harris

Expert
Licensed User
Longtime User
I was getting different results on different OS versions - like event started on the 15th of Jan. and ended on the 14th...

My calendar view showed events for Monday thru Friday, while Googles calendar showed the same events Tuesday thru Sat...

Setting a non - all day event (2:00 to 4:00 pm) seemed to work just fine.

Thanks much. I shall give this a whirl and see what results.
 

lagore

Active Member
Licensed User
Longtime User
I have found that creating an event on any os works the same but reading the events I had to modify the end date/time for pre and post ICS. This is because the calendar API is only official for android 4.0 and above so I had to create a working library for the pre 4.0 os which operates on a different system. You may have to modify the finish time to include the event based on the os.
 

Harris

Expert
Licensed User
Longtime User
Do you have an example on how I must deal with (handle) different OS versions and what needs to be handled differently? How would one detect when this would be required?

Or, would it be more practical to work with ICS and the official API and force users to upgrade (device / OS).

Google Calendar is so freakin useful... so much logic I do not have to address/handle (dates, reminders, db, etc, etc...) I wish it had user definable fields that I could extend. When sharing Cal, all participants can share and contribute to content. Does Google have a DB extension to Calendar?

Thanks
 

lagore

Active Member
Licensed User
Longtime User
The only thing that I had to modify slightly between the OS was how I searched for events between a block of dates (for all day events in my case not sure if it makes any difference for a regular events). The start date/time is the same in both cases it is the end date/time that you may have to modify. If you have 2 devices an ICS and a pre ICS then what I would do is create a few events over a few days or hours say 6 events first at 9am for 1 hour then the next at 11am for 1 hour and so on then using the same code on both devices search from start time (9am) to your finish time for the last event and see if it returns the same events. You may have to add 1 millisecond time to the finish time of one to get the last event. I use
B4X:
Dim ph As Phone
   
   If ph.SdkVersion < 14 Then
      calfinish = Finish_Date + offset      'non ICS modification
   Else
                                    'ICS modification
   End If
Once you have the event number then it the same for both to delete the event. Let my know if this does not make sense.
 

Harris

Expert
Licensed User
Longtime User
Still working thru above with mixed results... I may post a simple example to describe the issue when I understand more ( is it my code or bug).


Tasks:

Google Calendar also supports Tasks (somewhat). I see Task Subject, Due Date, completed, move to list, delete and Notes. Is it possible to support tasks as well as events in the official API?

The app I am creating works mainly with tasks (need to be marked as completed - on a due date) but start as an event (on a start date). For example, a bee hive needs treatment for parasitic mites. A treatment strip was inserted into hive on April 1, 2013 (recorded as event). A task is created to remove treatment strip on April 15, 2013. When task is completed, it is marked as done. The notes (of task) may indicate performance success of treatment.

Since many employees can access the shared calendar, anyone has access to the task and update the status.

Thanks
 
Top