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,858
  • calendar2 V1.12.zip
    18.7 KB · Views: 2,322
  • calendar2_v1.13.zip
    20.4 KB · Views: 1,309
Last edited:

cmweb

Active Member
Licensed User
Longtime User
Hi Edward,

The routine "GetListofAllEventsforCalendar(int)" only retrieves from the 'events' table so if you have an event that starts on the first monday and recurs for the next 5 mondays only the first events in retrieved. All of the other routines which search between dates search the "instances" table so will return all 6 events.
Unfortunately it still doesn't get the recurring events.

I am using

mylist = cal.GetListofEventsforCalendarBetweenDates

and it retreives the non-curring events between the given dates, but not the recurring events.

Example:

I want the get all events between today (tuesday) and next sunday.

I have a recurring event, that started on a saturday in may 2012 and is recurring every week on saturday. Google Calendars shows that event on saturday, august 11,2012.

But this event won't be retreived by GetListofEventsforCalendarBetweenDates.

I guess, there's still something wrong... :-(

Best regards,

Carsten
 

lagore

Active Member
Licensed User
Longtime User
Hi Carsten,
I think I have it this time, in the 4.0 version it was looking at the 'event' time in the instances table but I have just realised that this time is the time of the original event not the recurring event so the search could not find it. There is a field in the instances table for begin and end and these are the ones that the individual recurring events use and they are the ones that I now search on. I have done a quick compare of a 2.2 and 4.1 (on emulator) and they are now returning the same recurring events. I hope this sorts your problem, let me know if not or if you need more info pulled from the events.
Regards
 

cmweb

Active Member
Licensed User
Longtime User
Hi Carsten,
I think I have it this time, in the 4.0 version it was looking at the 'event' time in the instances table but I have just realised that this time is the time of the original event not the recurring event so the search could not find it. There is a field in the instances table for begin and end and these are the ones that the individual recurring events use and they are the ones that I now search on. I have done a quick compare of a 2.2 and 4.1 (on emulator) and they are now returning the same recurring events. I hope this sorts your problem, let me know if not or if you need more info pulled from the events.
Regards
Hi Edward,

yes, the recurring events will be found now...

But I do have two little problems:

for example: Event every saturday at 2pm, first event was back in 2010.

- as starttime of a recurring event I'm getting the starttime of the first event of that row - the date in 2010 -, not the time/date of the specific event that matches my GetListofEventsforCalendarBetweenDates query.

- end time of a recurring event is always "null".

Is there a chance to improve that behaviour?

Best regards,

Carsten
 

lagore

Active Member
Licensed User
Longtime User
Hi Carsten,
Getting there slowly, the recurring event should now show the start & end time for itself not the original event, I forgot to change the returned times from the events table to those from the instances table.
 

lagore

Active Member
Licensed User
Longtime User
v1.6 added (see first post)
The calendar is no longer an activity object, I have not tested it in a non activity situation let me know if it works!!
 

cmweb

Active Member
Licensed User
Longtime User
Hi Edward,

That sounds great!

I will try tomorrow and will give you feedback...

Best regards,

Carsten

Gesendet von meinem GT-N7000 mit Tapatalk 2
 

cmweb

Active Member
Licensed User
Longtime User
Hi Carsten,
Getting there slowly, the recurring event should now show the start & end time for itself not the original event, I forgot to change the returned times from the events table to those from the instances table.
Hi Edward,

this works excellent now! Thanks a lot, you're awesome!

Best regards,

Carsten
 

juancarloscm

Member
Licensed User
Longtime User
Error loading the calendar application

hello

when I run the sample calendar tells me that the library is not AHPreferenceManager, AHPreferenceScreen
I'll be doing something wrong

thanks
 

juancarloscm

Member
Licensed User
Longtime User
does not display my calendar

because when I run and give the option to create envento shows me anything I version is 2.3.3

thanks:sign0085
 

lagore

Active Member
Licensed User
Longtime User
Can you post your code and we can have a look at it or are you using the example program? Are you using an actual device or the emulator.
 

juancarloscm

Member
Licensed User
Longtime User
library calendar

if I'm using the example program, when I create new event you do not do anything, annex the screenshot

thanks
 

Attachments

  • pantalla1.jpg
    pantalla1.jpg
    40 KB · Views: 398
  • pantalla2.jpg
    pantalla2.jpg
    60.1 KB · Views: 338

lagore

Active Member
Licensed User
Longtime User
The problem is the emulator, it only has limited support for calendars which you have to set up and you can only set up one calendar, if you have a real device try it on that.
 

JohnC

Expert
Licensed User
Longtime User
Get Calendar Force-Close when try to edit

Hi,

First, great library - thanks for the effort!

The only thing I am running into is if I create a calendar entry (that also has an alarm), it gets added and displayed just fine in the built-in calendar app. But if I try to "edit" it from anywhere (from the alarm notification screen, or from the built-in calendar app (samsungs version), it will give me a force-close error. I can manually create an alarm entry for this same "calendar" using the built-in app, and then edit it no problem - it's just that I can't edit any entries created with this lib.

Some Info: I am running Android 2.3.4 on a GSII and creating the entry from a "service" module.

NOTE: The built-in "Calendar" app is crashing, not my app, its just that it only crashes when I try to edit alarms created with this lib.

(The Error log of the cal app is at the bottom)

Here is my code:
---------------
Dim DD As Long
Dim DT As Long
Dim CID As Int
Dim Cal As MyCalendar
Dim Cals As Map
Dim i As Int
Dim A As String
Dim AI As Int

Cal.Initialize
Cals.Initialize

Cals = Cal.GetListOfAllCalendars (True)
CID = -1
For i = 0 To Cals.Size - 1
A = Cals.GetValueAt(i)
AI = Cals.GetKeyAt(i)
If A.ToUpperCase = "MYCALENDAR" Then
CID = AI
Exit
End If
Next
If CID = -1 Then
Return "NOCAL"
End If

DateTime.DateFormat = "MM/dd/yy"
DateTime.TimeFormat = "HH:mm"

DD = DateTime.DateParse("09/13/12")
DT = DateTime.TimeParse("10:00") - DD 'get just the time of the date

Cal.CreateEventWithReminder(CID, "Title of Alarm","This is an Alarm Desc","",DD + DT, DD + DT,5,Null,False)



And here is the error log when the "CALENDAR APP" (not my app) crashes:
------------------------
threadid=1: thread exiting with uncaught exception (group=0x4001e578)
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.calendar/com.android.calendar.EditEvent}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3691)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.android.calendar.EditEvent.setVariableTimezone(EditEvent.java:4344)
at com.android.calendar.EditEvent.setTimezone(EditEvent.java:4357)
at com.android.calendar.EditEvent.setAllday(EditEvent.java:4905)
at com.android.calendar.EditEvent.onCreate(EditEvent.java:2575)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
... 11 more
Force finishing activity com.android.calendar/.EditEvent
 

eps

Expert
Licensed User
Longtime User
Just wanted to say, thanks for this I've started to use the library now. If my Apps go big I'll remunerate you!

This all works well on my HTC evo 3d I could create entries, move them, edit them and delete them.

I've almost got my app fully converted to use your code.

One possible wish would be to allow users to create their own calendar, as opposed to using an existing one on the device.
 

lagore

Active Member
Licensed User
Longtime User
I have never tried spanning more then one day there is no reason why it could not be updated to do this I will have a look and see if it can be easily done, I will also look at the possibility of getting the library to create a calendar. On my app I get the user to create a calendar the normal way then it is available inside the app, but it would be nice to create it from within.

Sent from my HTC One X using Tapatalk 2
 

eps

Expert
Licensed User
Longtime User
Actually it will span multiple days, I can post the code, but it's quite obvious.

It just foxed me that I had a start date of (say) the 26th and an end date of the 27th, but only the 26th was covered in the calendar itself. I think added a day to the end date and this extended the end date and time to what I expected to see :) although I did also stop it from creating an "all day" event - which I might switch back to, as it looks a tad odd, with the calendar day view being taken up with the whole event.. Of course it also shows me that I need to start dealing with the times of the events in question, not just the days on which they occur, more work!

:)
 

lagore

Active Member
Licensed User
Longtime User
Have been playing with it this morning and had no problems spanning multiple days. I don't think you should use the 'all day' indicator with anything other then a standard all day event eg a 24hr event on the one day.
I should be able to get the create calendar option running just need to read up on sync adapters to give it full functionally.
 
Top