Learning from DashClock: How to display information about your next calendar appointment
DashClock is lock screen clock widget for Android 4.2+.
It is an awesome code example, from which we can learn and take snippets.
Do you want to know how to display information about your next calendar appointment?
CalendarExtension is good answer.
It's very important to note that these API works only with Android 4.0+.
With this code we are going to query CalendarContract instances
We can manage multiple calendars on our device. For each calendar we can have multiple events.
An instance is a single occurrence of an event including time zone specific start and end days and minutes
With:
With
Move the cursor to the first row and check if there is an appointment.
We can get the event title:
Finally we can calculate how many hours are missing to next appointment (in minutes,hours or days).
To use the Calendar content provider you need to declare the necessary permissions within your manifest file first:
This is our log:
02-14 00:11:46.870: D/calendarExtension(16367): Until=48 min
02-14 00:11:46.870: D/calendarExtension(16367): Title=Test calandar
02-14 00:11:46.870: D/calendarExtension(16367): Body=01:00
C
It is an awesome code example, from which we can learn and take snippets.
Do you want to know how to display information about your next calendar appointment?
CalendarExtension is good answer.
- First of all we can access the data by making use of the CalendarContract content provider.
- Find next single occurrences of an event in next few hours
- Format information and that's all
It's very important to note that these API works only with Android 4.0+.
With this code we are going to query CalendarContract instances
long now = getCurrentTimestamp(); Cursor cursor= getContentResolver().query( CalendarContract.Instances.CONTENT_URI.buildUpon() .appendPath(Long.toString(now)) .appendPath(Long.toString(now + DEFAULT_LOOK_AHEAD_HOURS * HOUR_MILLIS)) .build(), EventsQuery.PROJECTION, CalendarContract.Instances.ALL_DAY + "=0 AND " + CalendarContract.Instances.SELF_ATTENDEE_STATUS + "!=" + CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED + " AND " + CalendarContract.Instances.STATUS + "!=" + CalendarContract.Instances.STATUS_CANCELED + " AND " + CalendarContract.Instances.VISIBLE + "!=0", null, CalendarContract.Instances.BEGIN);Calendar’s data model consists of calendars, events, event instances.
We can manage multiple calendars on our device. For each calendar we can have multiple events.
An instance is a single occurrence of an event including time zone specific start and end days and minutes
CalendarContract.Instances.CONTENT_URI
is the content:// style URL for the top-level calendar authority.With:
.appendPath(Long.toString(now)) .appendPath(Long.toString(now + DEFAULT_LOOK_AHEAD_HOURS * HOUR_MILLIS))we are choosing a time interval, between now and the next XX hours (
=DEFAULT_LOOK_AHEAD_HOURS
)With
EventsQuery.PROJECTION
we define a list of which columns to return.
private interface EventsQuery { String[] PROJECTION = { CalendarContract.Instances.EVENT_ID, CalendarContract.Instances.BEGIN, CalendarContract.Instances.END, CalendarContract.Instances.TITLE, }; int EVENT_ID = 0; int BEGIN = 1; int END = 2; int TITLE = 3; }With filter we declare which rows to return: in this case, we skip over events that are not ALL_DAY but span multiple days, including the next XX hours, not cancelled or declined.
Move the cursor to the first row and check if there is an appointment.
while (cursor.moveToNext()) { nextTimestamp = cursor.getLong(EventsQuery.BEGIN); timeUntilNextAppointent = nextTimestamp - currentTimestamp; if (timeUntilNextAppointent >= 0) { break; // We find an appointment ! } }We have found an appointment. We can retrieve and format information.
We can get the event title:
String eventTitle = cursor.getString(EventsQuery.TITLE);We can get the beginning time of the instance, in UTC milliseconds
long nextTimestamp = cursor.getLong(EventsQuery.BEGIN);and format this data in this way:
Calendar nextEventCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); nextEventCalendar.setTimeInMillis(nextTimestamp); StringBuilder expandedBodyFormat = new StringBuilder(); if (nextTimestamp - currentTimestamp > 24 * HOUR_MILLIS) { expandedBodyFormat.append("EEEE, "); } if (DateFormat.is24HourFormat(this)) { expandedBodyFormat.append("HH:mm"); } else { expandedBodyFormat.append("h:mm a"); } String expandedBody = new SimpleDateFormat(expandedBodyFormat.toString()) .format(nextEventCalendar.getTime());
Finally we can calculate how many hours are missing to next appointment (in minutes,hours or days).
int minutesUntilNextAppointment = (int) (timeUntilNextAppointent / MINUTE_MILLIS); String untilString; if (minutesUntilNextAppointment < 60) { // Minutes untilString = getResources().getQuantityString( R.plurals.calendar_template_mins, minutesUntilNextAppointment, minutesUntilNextAppointment); } else { int hours = Math.round(minutesUntilNextAppointment / 60f); if (hours < 24) { //Hours untilString = getResources().getQuantityString( R.plurals.calendar_template_hours, hours, hours); } else { //Days int days = hours / 24; // floor, not round for days untilString = getResources().getQuantityString( R.plurals.calendar_template_days, days, days); } }Here you can find more information about Events.
To use the Calendar content provider you need to declare the necessary permissions within your manifest file first:
That's all!
Log.d(TAG, "Until=" + untilString); Log.d(TAG, "Title=" + eventTitle); Log.d(TAG, "Body=" + expandedBody);
This is our log:
02-14 00:11:46.870: D/calendarExtension(16367): Until=48 min
02-14 00:11:46.870: D/calendarExtension(16367): Title=Test calandar
02-14 00:11:46.870: D/calendarExtension(16367): Body=01:00
C
Comments
Post a Comment