Project: titanium
Issue TIMOB-7948: Android: Invalid column visibility when querying events in Ti.Android.Calendar
Here is the sample app from our Calendar TDoc that shows the error. The error seems to happen when {{getEventsInYear}} is called {code} var calendars = []; var selectedCalendarName; var selectedCalendarId; var pickerData = []; var win = Ti.UI.createWindow({ backgroundColor: 'white', exitOnClose: true, fullscreen: false, layout: 'vertical', title: 'Calendar Demo' }); var scrollView = Ti.UI.createScrollView({ backgroundColor: '#eee', height: 500, top: 20 }); var label = Ti.UI.createLabel({ backgroundColor: 'white', text: 'Click on the button to display the events for the selected calendar', textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER, top: 20 }); scrollView.add(label); var selectableCalendars = Ti.Android.Calendar.selectableCalendars; for (var i = 0, ilen = selectableCalendars.length; i < ilen; i++) { calendars.push({ name: selectableCalendars[i].name, id: selectableCalendars[i].id }); pickerData.push( Ti.UI.createPickerRow({ title: calendars[i].name }) ); if(i === 0){ selectedCalendarName = selectableCalendars[i].name; selectedCalendarId = selectableCalendars[i].id; } } var selectableCalendars = null; if(!calendars.length){ label.text = 'No calendars available. Select at least one in the native calendar before using this app'; } else { label.text = 'Click button to view calendar events'; var picker = Ti.UI.createPicker({ top:20 }); picker.add(pickerData); win.add(picker); picker.addEventListener('change', function(e){ for (var i = 0, ilen = calendars.length; i < ilen; i++) { if(calendars[i].name === e.row.title){ selectedCalendarName = calendars[i].name; selectedCalendarId = calendars[i].id; } } }); var button = Ti.UI.createButton({ title: 'View events', top: 20 }); win.add(button); button.addEventListener('click', function(e){ label.text = 'Generating...'; var currentYear = new Date().getFullYear(); var consoleString = ''; function print(s) { if (consoleString.length) { consoleString = consoleString + '\n'; } consoleString = consoleString + s; } var calendar = Ti.Android.Calendar.getCalendarById(selectedCalendarId); function printReminder(r) { var typetext = '[method unknown]'; if (r.method == Ti.Android.Calendar.METHOD_EMAIL) { typetext = 'Email'; } else if (r.method == Ti.Android.Calendar.METHOD_SMS) { typetext = 'SMS'; } else if (r.method == Ti.Android.Calendar.METHOD_ALERT) { typetext = 'Alert'; } else if (r.method == Ti.Android.Calendar.METHOD_DEFAULT) { typetext = '[default reminder method]'; } print(typetext + ' reminder to be sent ' + r.minutes + ' minutes before the event'); } function printAlert(a) { print('Alert id ' + a.id + ' begin ' + a.begin + '; end ' + a.end + '; alarmTime ' + a.alarmTime + '; minutes ' + a.minutes); } function printEvent(event) { if (event.allDay) { print('Event: ' + event.title + '; ' + event.begin.toLocaleDateString() + ' (all day)'); } else { print('Event: ' + event.title + '; ' + event.begin.toLocaleDateString() + ' ' + event.begin.toLocaleTimeString()+ '-' + event.end.toLocaleTimeString()); } var reminders = event.reminders; if (reminders && reminders.length) { print('There is/are ' + reminders.length + ' reminder(s)'); for (var i = 0; i < reminders.length; i++) { printReminder(reminders[i]); } } print('hasAlarm? ' + event.hasAlarm); var alerts = event.alerts; if (alerts && alerts.length) { for (var i = 0; i < alerts.length; i++) { printAlert(alerts[i]); } } var status = event.status; if (status == Ti.Android.Calendar.STATUS_TENTATIVE) { print('This event is tentative'); } if (status == Ti.Android.Calendar.STATUS_CONFIRMED) { print('This event is confirmed'); } if (status == Ti.Android.Calendar.STATUS_CANCELED) { print('This event was canceled'); } } var events = calendar.getEventsInYear(currentYear); if (events && events.length) { print(events.length + ' event(s) in ' + currentYear); print(''); for (var i = 0; i < events.length; i++) { printEvent(events[i]); print(''); } } else { print('No events'); } label.text = consoleString; }); } win.add(scrollView); win.open(); {code} Also make sure you add READ_CALENDAR and WRITE_CALENDAR permissions to your tiapp.xml: {code} {code} And finally, here is the trace: {code} /CursorWrapperInner(31255): Cursor finalized without prior close() E/DatabaseUtils(31274): Writing exception to parcel E/DatabaseUtils(31274): java.lang.IllegalArgumentException: Invalid column visibility E/DatabaseUtils(31274): android.database.sqlite.SQLiteQueryBuilder.computeProjection(SQLiteQueryBuilder.java:588) E/DatabaseUtils(31274): android.database.sqlite.SQLiteQueryBuilder.buildQuery(SQLiteQueryBuilder.java:403) E/DatabaseUtils(31274): android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:347) E/DatabaseUtils(31274): android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:291) E/DatabaseUtils(31274): com.android.providers.calendar.CalendarProvider2.handleInstanceQuery(CalendarProvider2.java:1015) E/DatabaseUtils(31274): com.android.providers.calendar.CalendarProvider2.query(CalendarProvider2.java:840) E/DatabaseUtils(31274): android.content.ContentProvider$Transport.query(ContentProvider.java:178) E/DatabaseUtils(31274): android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112) E/DatabaseUtils(31274): android.os.Binder.execTransact(Binder.java:338) E/DatabaseUtils(31274): dalvik.system.NativeStart.run(Native Method) E/TiJSError(31255): (main) [141129,172202] ----- Titanium Javascript Runtime Error ----- E/TiJSError(31255): (main) [0,172202] - In pullRequests/1591.js:135,27 E/TiJSError(31255): (main) [0,172202] - Message: Uncaught Error: Invalid column visibility E/TiJSError(31255): (main) [0,172202] - Source: var events = calendar.getEventsInYear(currentYear); E/V8Exception(31255): Exception occurred at pullRequests/1591.js:135: Uncaught Error: Invalid column visibility {code}
Story points: 1