diff --git a/android/src/com/google/zxing/client/android/result/CalendarResultHandler.java b/android/src/com/google/zxing/client/android/result/CalendarResultHandler.java index eb028d7df..24585db91 100644 --- a/android/src/com/google/zxing/client/android/result/CalendarResultHandler.java +++ b/android/src/com/google/zxing/client/android/result/CalendarResultHandler.java @@ -54,14 +54,26 @@ public final class CalendarResultHandler extends ResultHandler { @Override public void handleButtonPress(int index) { - CalendarParsedResult calendarResult = (CalendarParsedResult) getResult(); 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(), - calendarResult.getDescription()); + description, + calendarResult.getAttendees()); } } @@ -75,13 +87,15 @@ public final class CalendarResultHandler extends ResultHandler { * @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 description, + String[] attendees) { Intent intent = new Intent(Intent.ACTION_INSERT); intent.setType("vnd.android.cursor.item/event"); long startMilliseconds = start.getTime(); @@ -104,6 +118,10 @@ public final class CalendarResultHandler extends ResultHandler { 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? + } launchIntent(intent); } @@ -132,7 +150,8 @@ public final class CalendarResultHandler extends ResultHandler { } ParsedResult.maybeAppend(calResult.getLocation(), result); - ParsedResult.maybeAppend(calResult.getAttendee(), result); + ParsedResult.maybeAppend(calResult.getOrganizer(), result); + ParsedResult.maybeAppend(calResult.getAttendees(), result); ParsedResult.maybeAppend(calResult.getDescription(), result); return result.toString(); } diff --git a/core/src/com/google/zxing/client/result/CalendarParsedResult.java b/core/src/com/google/zxing/client/result/CalendarParsedResult.java index e3ee0b698..46c1d7802 100644 --- a/core/src/com/google/zxing/client/result/CalendarParsedResult.java +++ b/core/src/com/google/zxing/client/result/CalendarParsedResult.java @@ -48,7 +48,8 @@ public final class CalendarParsedResult extends ParsedResult { private final Date end; private final boolean endAllDay; private final String location; - private final String attendee; + private final String organizer; + private final String[] attendees; private final String description; private final double latitude; private final double longitude; @@ -57,7 +58,8 @@ public final class CalendarParsedResult extends ParsedResult { String startString, String endString, String location, - String attendee, + String organizer, + String[] attendees, String description, double latitude, double longitude) { @@ -72,7 +74,8 @@ public final class CalendarParsedResult extends ParsedResult { this.startAllDay = startString.length() == 8; this.endAllDay = endString != null && endString.length() == 8; this.location = location; - this.attendee = attendee; + this.organizer = organizer; + this.attendees = attendees; this.description = description; this.latitude = latitude; this.longitude = longitude; @@ -115,8 +118,12 @@ public final class CalendarParsedResult extends ParsedResult { return location; } - public String getAttendee() { - return attendee; + public String getOrganizer() { + return organizer; + } + + public String[] getAttendees() { + return attendees; } public String getDescription() { @@ -138,7 +145,8 @@ public final class CalendarParsedResult extends ParsedResult { maybeAppend(format(startAllDay, start), result); maybeAppend(format(endAllDay, end), result); maybeAppend(location, result); - maybeAppend(attendee, result); + maybeAppend(organizer, result); + maybeAppend(attendees, result); maybeAppend(description, result); return result.toString(); } diff --git a/core/src/com/google/zxing/client/result/VCardResultParser.java b/core/src/com/google/zxing/client/result/VCardResultParser.java index 5c82fe8a7..8f52b4f1d 100644 --- a/core/src/com/google/zxing/client/result/VCardResultParser.java +++ b/core/src/com/google/zxing/client/result/VCardResultParser.java @@ -87,10 +87,10 @@ public final class VCardResultParser extends ResultParser { toPrimaryValue(url)); } - private static List> matchVCardPrefixedField(CharSequence prefix, - String rawText, - boolean trim, - boolean parseFieldDivider) { + static List> matchVCardPrefixedField(CharSequence prefix, + String rawText, + boolean trim, + boolean parseFieldDivider) { List> matches = null; int i = 0; int max = rawText.length(); diff --git a/core/src/com/google/zxing/client/result/VEventResultParser.java b/core/src/com/google/zxing/client/result/VEventResultParser.java index 21f1394c1..72a7d9746 100644 --- a/core/src/com/google/zxing/client/result/VEventResultParser.java +++ b/core/src/com/google/zxing/client/result/VEventResultParser.java @@ -43,6 +43,14 @@ public final class VEventResultParser extends ResultParser { } String end = matchSingleVCardPrefixedField("DTEND", rawText, true); String location = matchSingleVCardPrefixedField("LOCATION", rawText, true); + String organizer = stripMailto(matchSingleVCardPrefixedField("ORGANIZER", rawText, true)); + + String[] attendees = matchVCardPrefixedField("ATTENDEE", rawText, true); + if (attendees != null) { + for (int i = 0; i < attendees.length; i++) { + attendees[i] = stripMailto(attendees[i]); + } + } String description = matchSingleVCardPrefixedField("DESCRIPTION", rawText, true); String geoString = matchSingleVCardPrefixedField("GEO", rawText, true); @@ -62,7 +70,15 @@ public final class VEventResultParser extends ResultParser { } try { - return new CalendarParsedResult(summary, start, end, location, null, description, latitude, longitude); + return new CalendarParsedResult(summary, + start, + end, + location, + organizer, + attendees, + description, + latitude, + longitude); } catch (IllegalArgumentException iae) { return null; } @@ -75,4 +91,24 @@ public final class VEventResultParser extends ResultParser { return values == null || values.isEmpty() ? null : values.get(0); } + private static String[] matchVCardPrefixedField(CharSequence prefix, String rawText, boolean trim) { + List> values = VCardResultParser.matchVCardPrefixedField(prefix, rawText, trim, false); + if (values == null || values.isEmpty()) { + return null; + } + int size = values.size(); + String[] result = new String[size]; + for (int i = 0; i < size; i++) { + result[i] = values.get(i).get(0); + } + return result; + } + + private static String stripMailto(String s) { + if (s != null && (s.startsWith("mailto:") || s.startsWith("MAILTO:"))) { + s = s.substring(7); + } + return s; + } + } \ No newline at end of file diff --git a/core/test/src/com/google/zxing/client/result/CalendarParsedResultTestCase.java b/core/test/src/com/google/zxing/client/result/CalendarParsedResultTestCase.java index 239632a4e..05e798758 100644 --- a/core/test/src/com/google/zxing/client/result/CalendarParsedResultTestCase.java +++ b/core/test/src/com/google/zxing/client/result/CalendarParsedResultTestCase.java @@ -24,6 +24,7 @@ import org.junit.Test; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Locale; import java.util.TimeZone; @@ -119,7 +120,29 @@ public final class CalendarParsedResultTestCase extends Assert { "DTSTART:20080504T123456Z\r\n" + "GEO:-12.345;-45.678\r\n" + "END:VEVENT\r\nEND:VCALENDAR", - null, null, null, "20080504T123456Z", null, null, -12.345, -45.678); + null, null, null, "20080504T123456Z", null, null, null, -12.345, -45.678); + } + + @Test + public void testOrganizer() { + doTest( + "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" + + "DTSTART:20080504T123456Z\r\n" + + "ORGANIZER:mailto:bob@example.org\r\n" + + "END:VEVENT\r\nEND:VCALENDAR", + null, null, null, "20080504T123456Z", null, "bob@example.org", null, Double.NaN, Double.NaN); + } + + @Test + public void testAttendees() { + doTest( + "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" + + "DTSTART:20080504T123456Z\r\n" + + "ATTENDEE:mailto:bob@example.org\r\n" + + "ATTENDEE:mailto:alice@example.org\r\n" + + "END:VEVENT\r\nEND:VCALENDAR", + null, null, null, "20080504T123456Z", null, null, + new String[] {"bob@example.org", "alice@example.org"}, Double.NaN, Double.NaN); } @Test @@ -161,7 +184,7 @@ public final class CalendarParsedResultTestCase extends Assert { String location, String startString, String endString) { - doTest(contents, description, summary, location, startString, endString, null, Double.NaN, Double.NaN); + doTest(contents, description, summary, location, startString, endString, null, null, Double.NaN, Double.NaN); } private static void doTest(String contents, @@ -170,7 +193,8 @@ public final class CalendarParsedResultTestCase extends Assert { String location, String startString, String endString, - String attendee, + String organizer, + String[] attendees, double latitude, double longitude) { Result fakeResult = new Result(contents, null, null, BarcodeFormat.QR_CODE); @@ -182,7 +206,9 @@ public final class CalendarParsedResultTestCase extends Assert { assertEquals(location, calResult.getLocation()); assertEquals(startString, DATE_TIME_FORMAT.format(calResult.getStart())); assertEquals(endString, calResult.getEnd() == null ? null : DATE_TIME_FORMAT.format(calResult.getEnd())); - assertEquals(attendee, calResult.getAttendee()); + assertEquals(organizer, calResult.getOrganizer()); + assertTrue((attendees == null && calResult.getAttendees() == null) || + Arrays.equals(attendees, calResult.getAttendees())); assertEqualOrNaN(latitude, calResult.getLatitude()); assertEqualOrNaN(longitude, calResult.getLongitude()); }