/* * Copyright (C) 2008 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.zxing.client.android.result; import android.content.ActivityNotFoundException; import android.util.Log; import com.google.zxing.client.android.R; import com.google.zxing.client.result.CalendarParsedResult; import com.google.zxing.client.result.ParsedResult; import android.app.Activity; import android.content.Intent; import java.text.DateFormat; import java.util.Date; /** * Handles calendar entries encoded in QR Codes. * * @author dswitkin@google.com (Daniel Switkin) * @author Sean Owen */ public final class CalendarResultHandler extends ResultHandler { private static final String TAG = CalendarResultHandler.class.getSimpleName(); private static int[] buttons; public CalendarResultHandler(Activity activity, ParsedResult result) { super(activity, result); buttons = new int[]{ fakeR.getId("string", "button_add_calendar") }; } @Override public int getButtonCount() { return buttons.length; } @Override public int getButtonText(int index) { return buttons[index]; } @Override public void handleButtonPress(int index) { if (index == 0) { CalendarParsedResult calendarResult = (CalendarParsedResult) getResult(); String description = calendarResult.getDescription(); String organizer = calendarResult.getOrganizer(); if (organizer != null) { // No separate Intent key, put in description if (description == null) { description = organizer; } else { description = description + '\n' + organizer; } } addCalendarEvent(calendarResult.getSummary(), calendarResult.getStart(), calendarResult.isStartAllDay(), calendarResult.getEnd(), calendarResult.getLocation(), description, calendarResult.getAttendees()); } } /** * Sends an intent to create a new calendar event by prepopulating the Add Event UI. Older * versions of the system have a bug where the event title will not be filled out. * * @param summary A description of the event * @param start The start time * @param allDay if true, event is considered to be all day starting from start time * @param end The end time (optional) * @param location a text description of the event location * @param description a text description of the event itself * @param attendees attendees to invite */ private void addCalendarEvent(String summary, Date start, boolean allDay, Date end, String location, String description, String[] attendees) { Intent intent = new Intent(Intent.ACTION_INSERT); intent.setType("vnd.android.cursor.item/event"); long startMilliseconds = start.getTime(); intent.putExtra("beginTime", startMilliseconds); if (allDay) { intent.putExtra("allDay", true); } long endMilliseconds; if (end == null) { if (allDay) { // + 1 day endMilliseconds = startMilliseconds + 24 * 60 * 60 * 1000; } else { endMilliseconds = startMilliseconds; } } else { endMilliseconds = end.getTime(); } intent.putExtra("endTime", endMilliseconds); intent.putExtra("title", summary); intent.putExtra("eventLocation", location); intent.putExtra("description", description); if (attendees != null) { intent.putExtra(Intent.EXTRA_EMAIL, attendees); // Documentation says this is either a String[] or comma-separated String, which is right? } try { // Do this manually at first rawLaunchIntent(intent); } catch (ActivityNotFoundException anfe) { Log.w(TAG, "No calendar app available that responds to " + Intent.ACTION_INSERT); // For calendar apps that don't like "INSERT": intent.setAction(Intent.ACTION_EDIT); launchIntent(intent); // Fail here for real if nothing can handle it } } @Override public CharSequence getDisplayContents() { CalendarParsedResult calResult = (CalendarParsedResult) getResult(); StringBuilder result = new StringBuilder(100); ParsedResult.maybeAppend(calResult.getSummary(), result); Date start = calResult.getStart(); ParsedResult.maybeAppend(format(calResult.isStartAllDay(), start), result); Date end = calResult.getEnd(); if (end != null) { if (calResult.isEndAllDay() && !start.equals(end)) { // Show only year/month/day // if it's all-day and this is the end date, it's exclusive, so show the user // that it ends on the day before to make more intuitive sense. // But don't do it if the event already (incorrectly?) specifies the same start/end end = new Date(end.getTime() - 24 * 60 * 60 * 1000); } ParsedResult.maybeAppend(format(calResult.isEndAllDay(), end), result); } ParsedResult.maybeAppend(calResult.getLocation(), result); ParsedResult.maybeAppend(calResult.getOrganizer(), result); ParsedResult.maybeAppend(calResult.getAttendees(), result); ParsedResult.maybeAppend(calResult.getDescription(), result); return result.toString(); } private static String format(boolean allDay, Date date) { if (date == null) { return null; } DateFormat format = allDay ? DateFormat.getDateInstance(DateFormat.MEDIUM) : DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); return format.format(date); } @Override public int getDisplayTitle() { return fakeR.getId("string", "result_calendar"); } }