Added preliminary support for MobileTag formats; not enabled yet.

Added "sms:" URI support.

git-svn-id: https://zxing.googlecode.com/svn/trunk@380 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-05-02 18:39:03 +00:00
parent 2db1ea526f
commit 188c7fbecb
21 changed files with 1246 additions and 28 deletions

View file

@ -22,7 +22,19 @@ import android.provider.Contacts;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.google.zxing.client.result.*;
import com.google.zxing.client.result.AddressBookAUParsedResult;
import com.google.zxing.client.result.AddressBookDoCoMoParsedResult;
import com.google.zxing.client.result.BookmarkDoCoMoParsedResult;
import com.google.zxing.client.result.EmailAddressParsedResult;
import com.google.zxing.client.result.EmailDoCoMoParsedResult;
import com.google.zxing.client.result.GeoParsedResult;
import com.google.zxing.client.result.ParsedReaderResult;
import com.google.zxing.client.result.ParsedReaderResultType;
import com.google.zxing.client.result.SMSParsedResult;
import com.google.zxing.client.result.TelParsedResult;
import com.google.zxing.client.result.UPCParsedResult;
import com.google.zxing.client.result.URIParsedResult;
import com.google.zxing.client.result.URLTOParsedResult;
import java.net.URISyntaxException;
@ -89,6 +101,12 @@ final class ResultHandler implements Button.OnClickListener {
intent = new Intent(Intent.SENDTO_ACTION, new ContentURI("mailto:" + emailResult.getEmailAddress()));
} catch (URISyntaxException e) {
}
} else if (type.equals(ParsedReaderResultType.SMS)) {
SMSParsedResult smsResult = (SMSParsedResult) result;
try {
intent = new Intent(Intent.SENDTO_ACTION, new ContentURI(smsResult.getSMSURI()));
} catch (URISyntaxException e) {
}
} else if (type.equals(ParsedReaderResultType.TEL)) {
TelParsedResult telResult = (TelParsedResult) result;
try {

View file

@ -19,10 +19,21 @@ package com.google.zxing.client.android;
import android.content.Intent;
import android.net.Uri;
import android.provider.Contacts;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.google.zxing.client.result.*;
import com.google.zxing.client.result.AddressBookAUParsedResult;
import com.google.zxing.client.result.AddressBookDoCoMoParsedResult;
import com.google.zxing.client.result.BookmarkDoCoMoParsedResult;
import com.google.zxing.client.result.EmailAddressParsedResult;
import com.google.zxing.client.result.EmailDoCoMoParsedResult;
import com.google.zxing.client.result.GeoParsedResult;
import com.google.zxing.client.result.ParsedReaderResult;
import com.google.zxing.client.result.ParsedReaderResultType;
import com.google.zxing.client.result.SMSParsedResult;
import com.google.zxing.client.result.TelParsedResult;
import com.google.zxing.client.result.UPCParsedResult;
import com.google.zxing.client.result.URIParsedResult;
import com.google.zxing.client.result.URLTOParsedResult;
/**
* Handles the result of barcode decoding in the context of the Android platform,
@ -31,7 +42,7 @@ import com.google.zxing.client.result.*;
* @author srowen@google.com (Sean Owen)
* @author dswitkin@google.com (Daniel Switkin)
*/
final class ResultHandler implements Button.OnClickListener {
final class ResultHandler implements Button.OnClickListenear {
private static final String TAG = "ResultHandler";
@ -75,6 +86,9 @@ final class ResultHandler implements Button.OnClickListener {
} else if (type.equals(ParsedReaderResultType.EMAIL_ADDRESS)) {
EmailAddressParsedResult emailResult = (EmailAddressParsedResult) result;
intent = new Intent(Intent.SENDTO_ACTION, Uri.parse("mailto:" + emailResult.getEmailAddress()));
} else if (type.equals(ParsedReaderResultType.SMS)) {
SMSParsedResult smsResult = (SMSParsedResult) result;
intent = new Intent(Intent.SENDTO_ACTION, Uri.parse(smsResult.getSMSURI()));
} else if (type.equals(ParsedReaderResultType.TEL)) {
TelParsedResult telResult = (TelParsedResult) result;
intent = new Intent(Intent.DIAL_ACTION, Uri.parse("tel:" + telResult.getNumber()));

View file

@ -93,13 +93,6 @@ abstract class AbstractDoCoMoParsedResult extends ParsedReaderResult {
return matches == null ? null : matches[0];
}
static void maybeAppend(String value, StringBuffer result) {
if (value != null) {
result.append('\n');
result.append(value);
}
}
static void maybeAppend(String[] value, StringBuffer result) {
if (value != null) {
for (int i = 0; i < value.length; i++) {

View file

@ -48,27 +48,28 @@ public final class GeoParsedResult extends ParsedReaderResult {
}
// Drop geo, query portion
int queryStart = rawText.indexOf('?', 4);
String geoURIWithoutQuery;
if (queryStart < 0) {
rawText = rawText.substring(4);
geoURIWithoutQuery = rawText.substring(4);
} else {
rawText = rawText.substring(4, queryStart);
geoURIWithoutQuery = rawText.substring(4, queryStart);
}
int latitudeEnd = rawText.indexOf(',');
int latitudeEnd = geoURIWithoutQuery.indexOf(',');
if (latitudeEnd < 0) {
return null;
}
float latitude = Float.parseFloat(rawText.substring(0, latitudeEnd));
int longitudeEnd = rawText.indexOf(',', latitudeEnd + 1);
float latitude = Float.parseFloat(geoURIWithoutQuery.substring(0, latitudeEnd));
int longitudeEnd = geoURIWithoutQuery.indexOf(',', latitudeEnd + 1);
float longitude;
float altitude; // in meters
if (longitudeEnd < 0) {
longitude = Float.parseFloat(rawText.substring(latitudeEnd + 1));
longitude = Float.parseFloat(geoURIWithoutQuery.substring(latitudeEnd + 1));
altitude = 0.0f;
} else {
longitude = Float.parseFloat(rawText.substring(latitudeEnd + 1, longitudeEnd));
altitude = Float.parseFloat(rawText.substring(longitudeEnd + 1));
longitude = Float.parseFloat(geoURIWithoutQuery.substring(latitudeEnd + 1, longitudeEnd));
altitude = Float.parseFloat(geoURIWithoutQuery.substring(longitudeEnd + 1));
}
return new GeoParsedResult("geo:" + rawText, latitude, longitude, altitude);
return new GeoParsedResult(rawText, latitude, longitude, altitude);
}
public String getGeoURI() {

View file

@ -60,6 +60,8 @@ public abstract class ParsedReaderResult {
return result;
} else if ((result = TelParsedResult.parse(theResult)) != null) {
return result;
} else if ((result = SMSParsedResult.parse(theResult)) != null) {
return result;
} else if ((result = GeoParsedResult.parse(theResult)) != null) {
return result;
} else if ((result = URLTOParsedResult.parse(theResult)) != null) {
@ -82,7 +84,14 @@ public abstract class ParsedReaderResult {
return getDisplayResult();
}
static String unescapeBackslash(String escaped) {
protected static void maybeAppend(String value, StringBuffer result) {
if (value != null) {
result.append('\n');
result.append(value);
}
}
protected static String unescapeBackslash(String escaped) {
if (escaped != null) {
int backslash = escaped.indexOf((int) '\\');
if (backslash >= 0) {

View file

@ -36,10 +36,21 @@ public final class ParsedReaderResultType {
public static final ParsedReaderResultType ANDROID_INTENT = new ParsedReaderResultType("ANDROID_INTENT");
public static final ParsedReaderResultType GEO = new ParsedReaderResultType("GEO");
public static final ParsedReaderResultType TEL = new ParsedReaderResultType("TEL");
// TODO later, add the NDEF types to those actually processed by the clients
public static final ParsedReaderResultType SMS = new ParsedReaderResultType("SMS");
// "optional" types
public static final ParsedReaderResultType NDEF_TEXT = new ParsedReaderResultType("NDEF_TEXT");
public static final ParsedReaderResultType NDEF_URI = new ParsedReaderResultType("NDEF_URI");
public static final ParsedReaderResultType NDEF_SMART_POSTER = new ParsedReaderResultType("NDEF_SMART_POSTER");
public static final ParsedReaderResultType MOBILETAG_TEL = new ParsedReaderResultType("MOBILETAG_TEL");
public static final ParsedReaderResultType MOBILETAG_SMS = new ParsedReaderResultType("MOBILETAG_SMS");
public static final ParsedReaderResultType MOBILETAG_MMS = new ParsedReaderResultType("MOBILETAG_MMS");
public static final ParsedReaderResultType MOBILETAG_SIMPLE_WEB = new ParsedReaderResultType("MOBILETAG_SIMPLE_WEB");
public static final ParsedReaderResultType MOBILETAG_SIMPLE_CONTACT =
new ParsedReaderResultType("MOBILETAG_SIMPLE_CONTACT");
public static final ParsedReaderResultType MOBILETAG_SIMPLE_CALENDAR =
new ParsedReaderResultType("MOBILETAG_SIMPLE_CALENDAR");
public static final ParsedReaderResultType MOBILETAG_RICH_WEB = new ParsedReaderResultType("MOBILETAG_RICH_WEB");
private final String name;

View file

@ -0,0 +1,88 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result;
import com.google.zxing.Result;
/**
* Represents a "sms:" URI result, which specifies a number to SMS and optional
* "via" number. See <a href="http://gbiv.com/protocols/uri/drafts/draft-antti-gsm-sms-url-04.txt">
* the IETF draft</a> on this.
*
* @author srowen@google.com (Sean Owen)
*/
public final class SMSParsedResult extends ParsedReaderResult {
private final String smsURI;
private final String number;
private final String via;
private SMSParsedResult(String smsURI, String number, String via) {
super(ParsedReaderResultType.SMS);
this.smsURI = smsURI;
this.number = number;
this.via = via;
}
public static SMSParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || !rawText.startsWith("sms:")) {
return null;
}
// Drop sms, query portion
int queryStart = rawText.indexOf('?', 4);
String smsURIWithoutQuery;
if (queryStart < 0) {
smsURIWithoutQuery = rawText.substring(4);
} else {
smsURIWithoutQuery = rawText.substring(4, queryStart);
}
int numberEnd = smsURIWithoutQuery.indexOf(';');
String number;
String via;
if (numberEnd < 0) {
number = smsURIWithoutQuery;
via = null;
} else {
number = smsURIWithoutQuery.substring(0, numberEnd);
String maybeVia = smsURIWithoutQuery.substring(numberEnd + 1);
if (maybeVia.startsWith("via=")) {
via = maybeVia.substring(4);
} else {
via = null;
}
}
return new SMSParsedResult(rawText, number, via);
}
public String getSMSURI() {
return smsURI;
}
public String getNumber() {
return number;
}
public String getVia() {
return via;
}
public String getDisplayResult() {
return number;
}
}

View file

@ -0,0 +1,87 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.client.result.ParsedReaderResult;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Superclass for classes encapsulating reader results encoded according
* to the MobileTag Reader International Specification.</p>
*
* @author srowen@google.com (Sean Owen)
*/
abstract class AbstractMobileTagParsedResult extends ParsedReaderResult {
public static final int ACTION_DO = 1;
public static final int ACTION_EDIT = 2;
public static final int ACTION_SAVE = 4;
AbstractMobileTagParsedResult(ParsedReaderResultType type) {
super(type);
}
static String[] matchDelimitedFields(String rawText, int maxItems) {
String[] result = new String[maxItems];
int item = 0;
int i = 0;
int max = rawText.length();
while (item < maxItems && i < max) {
int start = i; // Found the start of a match here
boolean done = false;
while (!done) {
i = rawText.indexOf((int) '|', i);
if (i < 0) {
// No terminating end character? done. Set i such that loop terminates and break
i = rawText.length();
done = true;
} else if (rawText.charAt(i - 1) == '\\') {
// semicolon was escaped so continue
i++;
} else {
// found a match
if (start != i) {
result[item] = unescapeBackslash(rawText.substring(start, i));
}
item++;
i++;
done = true;
}
}
}
if (item < maxItems) {
return null;
}
return result;
}
static boolean isDigits(String s, int expectedLength) {
if (s == null) {
return true;
}
if (s.length() != expectedLength) {
return false;
}
for (int i = 0; i < expectedLength; i++) {
if (!Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.client.result.ParsedReaderResult;
import com.google.zxing.client.result.ParsedReaderResultType;
import java.io.UnsupportedEncodingException;
/**
* <p>Superclass for classes encapsulating results in the NDEF format.
* See <a href="http://www.nfc-forum.org/specs/">http://www.nfc-forum.org/specs/</a>.</p>
*
* <p>This code supports a limited subset of NDEF messages, ones that are plausibly
* useful in 2D barcode formats. This generally includes 1-record messages, no chunking,
* "short record" syntax, no ID field.</p>
*
* @author srowen@google.com (Sean Owen)
*/
abstract class AbstractNDEFParsedResult extends ParsedReaderResult {
AbstractNDEFParsedResult(ParsedReaderResultType type) {
super(type);
}
static String bytesToString(byte[] bytes, int offset, int length, String encoding) {
try {
return new String(bytes, offset, length, encoding);
} catch (UnsupportedEncodingException uee) {
// This should only be used when 'encoding' is an encoding that must necessarily
// be supported by the JVM, like UTF-8
throw new RuntimeException("Platform does not support required encoding: " + uee);
}
}
}

View file

@ -0,0 +1,91 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Represents a "MMS" result encoded according to section 4.7 of the
* MobileTag Reader International Specification.</p>
*
* @author srowen@google.com (Sean Owen)
*/
public final class MobileTagMMSParsedResult extends AbstractMobileTagParsedResult {
public static final String SERVICE_TYPE = "05";
private final String to;
private final String subject;
private final String body;
private final String title;
private MobileTagMMSParsedResult(String to, String subject, String body, String title) {
super(ParsedReaderResultType.MOBILETAG_MMS);
this.to = to;
this.subject = subject;
this.body = body;
this.title = title;
}
public static MobileTagMMSParsedResult parse(Result result) {
if (!result.getBarcodeFormat().equals(BarcodeFormat.DATAMATRIX)) {
return null;
}
String rawText = result.getText();
if (!rawText.startsWith(SERVICE_TYPE)) {
return null;
}
String[] matches = matchDelimitedFields(rawText.substring(2), 4);
if (matches == null) {
return null;
}
String to = matches[0];
String subject = matches[1];
String body = matches[2];
String title = matches[3];
return new MobileTagMMSParsedResult(to, subject, body, title);
}
public String getTo() {
return to;
}
public String getSubject() {
return subject;
}
public String getBody() {
return body;
}
public String getTitle() {
return title;
}
public String getDisplayResult() {
StringBuffer result = new StringBuffer(to);
maybeAppend(subject, result);
maybeAppend(title, result);
maybeAppend(body, result);
return result.toString();
}
}

View file

@ -0,0 +1,97 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Represents a "rich web" result encoded according to section 5 of the
* MobileTag Reader International Specification.</p>
*
* @author srowen@google.com (Sean Owen)
*/
public final class MobileTagRichWebParsedResult extends AbstractMobileTagParsedResult {
public static final String SERVICE_TYPE = "54";
private static final int DEFAULT_ACTION = ACTION_DO;
// Example: "http://www.tagserver.com/script.asp?id="
private static final String TAGSERVER_URI_PREFIX = System.getProperty("zxing.mobiletag.tagserver");
private final String id;
private final int action;
private MobileTagRichWebParsedResult(String id, int action) {
super(ParsedReaderResultType.MOBILETAG_RICH_WEB);
this.id = id;
this.action = action;
}
public static MobileTagRichWebParsedResult parse(Result result) {
if (TAGSERVER_URI_PREFIX == null) {
return null;
}
if (!result.getBarcodeFormat().equals(BarcodeFormat.DATAMATRIX)) {
return null;
}
String rawText = result.getText();
if (!rawText.startsWith(SERVICE_TYPE)) {
return null;
}
int length = rawText.length();
if (!isDigits(rawText, length)) {
return null;
}
int action;
String id;
if (length == 15) {
action = DEFAULT_ACTION;
id = rawText.substring(0, 2) + action + rawText.substring(2);
} else if (length == 16) {
action = rawText.charAt(2) - '0';
id = rawText;
} else {
return null;
}
return new MobileTagRichWebParsedResult(id, action);
}
public static String getTagserverURIPrefix() {
return TAGSERVER_URI_PREFIX;
}
public String getId() {
return id;
}
public int getAction() {
return action;
}
public String getTagserverURI() {
return TAGSERVER_URI_PREFIX + id;
}
public String getDisplayResult() {
return id;
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Represents a "SMS" result encoded according to section 4.6 of the
* MobileTag Reader International Specification.</p>
*
* @author srowen@google.com (Sean Owen)
*/
public final class MobileTagSMSParsedResult extends AbstractMobileTagParsedResult {
public static final String SERVICE_TYPE = "03";
private final String to;
private final String body;
private final String title;
private MobileTagSMSParsedResult(String to, String body, String title) {
super(ParsedReaderResultType.MOBILETAG_SMS);
this.to = to;
this.body = body;
this.title = title;
}
public static MobileTagSMSParsedResult parse(Result result) {
if (!result.getBarcodeFormat().equals(BarcodeFormat.DATAMATRIX)) {
return null;
}
String rawText = result.getText();
if (!rawText.startsWith(SERVICE_TYPE)) {
return null;
}
String[] matches = matchDelimitedFields(rawText.substring(2), 3);
if (matches == null) {
return null;
}
String to = matches[0];
String body = matches[1];
String title = matches[2];
return new MobileTagSMSParsedResult(to, body, title);
}
public String getTo() {
return to;
}
public String getBody() {
return body;
}
public String getTitle() {
return title;
}
public String getDisplayResult() {
StringBuffer result = new StringBuffer(to);
maybeAppend(title, result);
maybeAppend(body, result);
return result.toString();
}
}

View file

@ -0,0 +1,131 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Represents a "simple calendar" result encoded according to section 4.9 of the
* MobileTag Reader International Specification.</p>
*
* @author srowen@google.com (Sean Owen)
*/
public final class MobileTagSimpleCalendarParsedResult extends AbstractMobileTagParsedResult {
public static final String SERVICE_TYPE = "07";
private final String summary;
private final String start;
private final String end;
private final String location;
private final String attendee;
private final String title;
private MobileTagSimpleCalendarParsedResult(String summary,
String start,
String end,
String location,
String attendee,
String title) {
super(ParsedReaderResultType.MOBILETAG_SIMPLE_CALENDAR);
this.summary = summary;
this.start = start;
this.end = end;
this.location = location;
this.attendee = attendee;
this.title = title;
}
public static MobileTagSimpleCalendarParsedResult parse(Result result) {
if (!result.getBarcodeFormat().equals(BarcodeFormat.DATAMATRIX)) {
return null;
}
String rawText = result.getText();
if (!rawText.startsWith(SERVICE_TYPE)) {
return null;
}
String[] matches = matchDelimitedFields(rawText.substring(2), 6);
if (matches == null || !isDigits(matches[1], 10) || !isDigits(matches[2], 10)) {
return null;
}
String summary = matches[0];
String start = expandDateString(matches[1]);
String end = expandDateString(matches[2]);
String location = matches[3];
String attendee = matches[4];
String title = matches[5];
return new MobileTagSimpleCalendarParsedResult(summary, start, end, location, attendee, title);
}
public String getSummary() {
return summary;
}
/**
* <p>We would return the start and end date as a {@link java.util.Date} except that this code
* needs to work under JavaME / MIDP and there is no date parsing library available there, such
* as <code>java.text.SimpleDateFormat</code>.</p>
*
* <p>However we do translate the date from its encoded format of, say, "0602212156" to its full
* text representation of "20060221T215600Z", per the specification.</p>
*/
public String getStart() {
return start;
}
/**
* @see #getStart()
*/
public String getEnd() {
return end;
}
public String getLocation() {
return location;
}
public String getAttendee() {
return attendee;
}
public String getTitle() {
return title;
}
public String getDisplayResult() {
StringBuffer result = new StringBuffer(summary);
maybeAppend(start, result);
maybeAppend(end, result);
maybeAppend(location, result);
maybeAppend(attendee, result);
maybeAppend(title, result);
return result.toString();
}
private static String expandDateString(String date) {
if (date == null) {
return null;
}
// Input is of form YYMMddHHmmss, and needs to be YYYYMMdd'T'HHmmss'Z'
return "20" + date.substring(0, 6) + 'T' + date.substring(6) + "00Z";
}
}

View file

@ -0,0 +1,148 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Represents a "simple contact" result encoded according to section 4.8 of the
* MobileTag Reader International Specification.</p>
*
* @author srowen@google.com (Sean Owen)
*/
public final class MobileTagSimpleContactParsedResult extends AbstractMobileTagParsedResult {
public static final String SERVICE_TYPE = "02";
private final String fullName;
private final String telephoneCell;
private final String telephone;
private final String email1;
private final String email2;
private final String address;
private final String org;
private final String birthday;
private final String title;
private MobileTagSimpleContactParsedResult(String fullName,
String telephoneCell,
String telephone,
String email1,
String email2,
String address,
String org,
String birthday,
String title) {
super(ParsedReaderResultType.MOBILETAG_SIMPLE_CONTACT);
this.fullName = fullName;
this.telephoneCell = telephoneCell;
this.telephone = telephone;
this.email1 = email1;
this.email2 = email2;
this.address = address;
this.org = org;
this.birthday = birthday;
this.title = title;
}
public static MobileTagSimpleContactParsedResult parse(Result result) {
if (!result.getBarcodeFormat().equals(BarcodeFormat.DATAMATRIX)) {
return null;
}
String rawText = result.getText();
if (!rawText.startsWith(SERVICE_TYPE)) {
return null;
}
String[] matches = matchDelimitedFields(rawText.substring(2), 9);
if (matches == null || !isDigits(matches[7], 8)) {
return null;
}
String fullName = matches[0];
String telephoneCell = matches[1];
String telephone = matches[2];
String email1 = matches[3];
String email2 = matches[4];
String address = matches[5];
String org = matches[6];
String birthday = matches[7];
String title = matches[8];
return new MobileTagSimpleContactParsedResult(fullName,
telephoneCell,
telephone,
email1,
email2,
address,
org,
birthday,
title);
}
public String getFullName() {
return fullName;
}
public String getTelephoneCell() {
return telephoneCell;
}
public String getTelephone() {
return telephone;
}
public String getEmail1() {
return email1;
}
public String getEmail2() {
return email2;
}
public String getAddress() {
return address;
}
public String getOrg() {
return org;
}
public String getBirthday() {
return birthday;
}
public String getTitle() {
return title;
}
public String getDisplayResult() {
StringBuffer result = new StringBuffer(fullName);
maybeAppend(telephoneCell, result);
maybeAppend(telephone, result);
maybeAppend(email1, result);
maybeAppend(email2, result);
maybeAppend(address, result);
maybeAppend(org, result);
maybeAppend(birthday, result);
maybeAppend(title, result);
return result.toString();
}
}

View file

@ -0,0 +1,96 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Represents a "simple web" result encoded according to section 4.11 of the
* MobileTag Reader International Specification.</p>
*
* @author srowen@google.com (Sean Owen)
*/
public final class MobileTagSimpleWebParsedResult extends AbstractMobileTagParsedResult {
public static final String SERVICE_TYPE = "04";
private static final String[] URI_PREFIXES = {
null,
"http://",
"http://www.",
"https://",
"https://www.",
"rtsp://",
};
private final String title;
private final String uri;
private MobileTagSimpleWebParsedResult(String title, String uri) {
super(ParsedReaderResultType.MOBILETAG_SIMPLE_WEB);
this.title = title;
this.uri = uri;
}
public static MobileTagSimpleWebParsedResult parse(Result result) {
if (!result.getBarcodeFormat().equals(BarcodeFormat.DATAMATRIX)) {
return null;
}
String rawText = result.getText();
if (!rawText.startsWith(SERVICE_TYPE)) {
return null;
}
String[] matches = matchDelimitedFields(rawText.substring(2), 2);
if (matches == null) {
return null;
}
String uri = matches[0];
String title = matches[1];
char maybePrefixChar = uri.charAt(2);
if (maybePrefixChar >= '0' && maybePrefixChar <= '9') {
int prefixIndex = maybePrefixChar - '0';
// Note that '0' is reserved
if (prefixIndex >= 1 && prefixIndex < URI_PREFIXES.length) {
uri = URI_PREFIXES[prefixIndex] + uri.substring(1);
} else {
uri = uri.substring(1);
}
}
return new MobileTagSimpleWebParsedResult(title, uri);
}
public String getTitle() {
return title;
}
public String getURI() {
return uri;
}
public String getDisplayResult() {
if (title == null) {
return uri;
} else {
return title + '\n' + uri;
}
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Represents a "TEL" result encoded according to section 4.4 of the
* MobileTag Reader International Specification.</p>
*
* @author srowen@google.com (Sean Owen)
*/
public final class MobileTagTelParsedResult extends AbstractMobileTagParsedResult {
public static final String SERVICE_TYPE = "01";
private final String number;
private final String title;
private MobileTagTelParsedResult(String number, String title) {
super(ParsedReaderResultType.MOBILETAG_TEL);
this.number = number;
this.title = title;
}
public static MobileTagTelParsedResult parse(Result result) {
if (!result.getBarcodeFormat().equals(BarcodeFormat.DATAMATRIX)) {
return null;
}
String rawText = result.getText();
if (!rawText.startsWith(SERVICE_TYPE)) {
return null;
}
String[] matches = matchDelimitedFields(rawText.substring(2), 2);
if (matches == null) {
return null;
}
String number = matches[0];
String title = matches[1];
return new MobileTagTelParsedResult(number, title);
}
public String getNumber() {
return number;
}
public String getTitle() {
return title;
}
public String getDisplayResult() {
if (title == null) {
return number;
} else {
return title + '\n' + number;
}
}
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.zxing.client.result;
package com.google.zxing.client.result.optional;
/**
* <p>Represents a record in an NDEF message. This class only supports certain types

View file

@ -0,0 +1,113 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* <p>Recognizes an NDEF message that encodes information according to the
* "Smart Poster Record Type Definition" specification.</p>
*
* <p>This actually only supports some parts of the Smart Poster format: title,
* URI, and action records. Icon records are not supported because the size
* of these records are infeasibly large for barcodes. Size and type records
* are not supported. Multiple titles are not supported.</p>
*
* @author srowen@google.com (Sean Owen)
*/
public final class NDEFSmartPosterParsedResult extends AbstractNDEFParsedResult {
public static final int ACTION_UNSPECIFIED = -1;
public static final int ACTION_DO = 0;
public static final int ACTION_SAVE = 1;
public static final int ACTION_OPEN = 2;
private String title;
private String uri;
private int action;
private NDEFSmartPosterParsedResult() {
super(ParsedReaderResultType.NDEF_SMART_POSTER);
action = ACTION_UNSPECIFIED;
}
public static NDEFSmartPosterParsedResult parse(Result result) {
byte[] bytes = result.getRawBytes();
if (bytes == null) {
return null;
}
NDEFRecord headerRecord = NDEFRecord.readRecord(bytes, 0);
// Yes, header record starts and ends a message
if (headerRecord == null || !headerRecord.isMessageBegin() || !headerRecord.isMessageEnd()) {
return null;
}
if (!headerRecord.getType().equals(NDEFRecord.SMART_POSTER_WELL_KNOWN_TYPE)) {
return null;
}
int offset = 0;
int recordNumber = 0;
NDEFRecord ndefRecord = null;
byte[] payload = headerRecord.getPayload();
NDEFSmartPosterParsedResult smartPosterParsedResult = new NDEFSmartPosterParsedResult();
while (offset < payload.length && (ndefRecord = NDEFRecord.readRecord(payload, offset)) != null) {
if (recordNumber == 0 && !ndefRecord.isMessageBegin()) {
return null;
}
String type = ndefRecord.getType();
if (NDEFRecord.TEXT_WELL_KNOWN_TYPE.equals(type)) {
String[] languageText = NDEFTextParsedResult.decodeTextPayload(ndefRecord.getPayload());
smartPosterParsedResult.title = languageText[1];
} else if (NDEFRecord.URI_WELL_KNOWN_TYPE.equals(type)) {
smartPosterParsedResult.uri = NDEFURIParsedResult.decodeURIPayload(ndefRecord.getPayload());
} else if (NDEFRecord.ACTION_WELL_KNOWN_TYPE.equals(type)) {
smartPosterParsedResult.action = ndefRecord.getPayload()[0];
}
recordNumber++;
offset += ndefRecord.getTotalRecordLength();
}
if (recordNumber == 0 || (ndefRecord != null && !ndefRecord.isMessageEnd())) {
return null;
}
return smartPosterParsedResult;
}
public String getTitle() {
return title;
}
public String getURI() {
return uri;
}
public int getAction() {
return action;
}
public String getDisplayResult() {
if (title == null) {
return uri;
} else {
return title + '\n' + uri;
}
}
}

View file

@ -14,9 +14,10 @@
* limitations under the License.
*/
package com.google.zxing.client.result;
package com.google.zxing.client.result.optional;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* Recognizes an NDEF message that encodes text according to the
@ -26,7 +27,6 @@ import com.google.zxing.Result;
*/
public final class NDEFTextParsedResult extends AbstractNDEFParsedResult {
private final String language;
private final String text;

View file

@ -0,0 +1,110 @@
/*
* Copyright 2008 Google Inc.
*
* 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.result.optional;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedReaderResultType;
/**
* Recognizes an NDEF message that encodes a URI according to the
* "URI Record Type Definition" specification.
*
* @author srowen@google.com (Sean Owen)
*/
public final class NDEFURIParsedResult extends AbstractNDEFParsedResult {
private static final String[] URI_PREFIXES = {
null,
"http://www.",
"https://www.",
"http://",
"https://",
"tel:",
"mailto:",
"ftp://anonymous:anonymous@",
"ftp://ftp.",
"ftps://",
"sftp://",
"smb://",
"nfs://",
"ftp://",
"dav://",
"news:",
"telnet://",
"imap:",
"rtsp://",
"urn:",
"pop:",
"sip:",
"sips:",
"tftp:",
"btspp://",
"btl2cap://",
"btgoep://",
"tcpobex://",
"irdaobex://",
"file://",
"urn:epc:id:",
"urn:epc:tag:",
"urn:epc:pat:",
"urn:epc:raw:",
"urn:epc:",
"urn:nfc:",
};
private final String uri;
private NDEFURIParsedResult(String uri) {
super(ParsedReaderResultType.NDEF_URI);
this.uri = uri;
}
public static NDEFURIParsedResult parse(Result result) {
byte[] bytes = result.getRawBytes();
if (bytes == null) {
return null;
}
NDEFRecord ndefRecord = NDEFRecord.readRecord(bytes, 0);
if (ndefRecord == null || !ndefRecord.isMessageBegin() || !ndefRecord.isMessageEnd()) {
return null;
}
if (!ndefRecord.getType().equals(NDEFRecord.URI_WELL_KNOWN_TYPE)) {
return null;
}
String fullURI = decodeURIPayload(ndefRecord.getPayload());
return new NDEFURIParsedResult(fullURI);
}
static String decodeURIPayload(byte[] payload) {
int identifierCode = payload[0] & 0xFF;
String prefix = null;
if (identifierCode < URI_PREFIXES.length) {
prefix = URI_PREFIXES[identifierCode];
}
String restOfURI = bytesToString(payload, 1, payload.length - 1, "UTF-8");
return prefix == null ? restOfURI : prefix + restOfURI;
}
public String getURI() {
return uri;
}
public String getDisplayResult() {
return uri;
}
}

View file

@ -22,6 +22,7 @@ import com.google.zxing.client.result.EmailAddressParsedResult;
import com.google.zxing.client.result.EmailDoCoMoParsedResult;
import com.google.zxing.client.result.ParsedReaderResult;
import com.google.zxing.client.result.ParsedReaderResultType;
import com.google.zxing.client.result.SMSParsedResult;
import com.google.zxing.client.result.TelParsedResult;
import com.google.zxing.client.result.UPCParsedResult;
import com.google.zxing.client.result.URIParsedResult;
@ -209,9 +210,9 @@ public final class ZXingMIDlet extends MIDlet {
} else if (type.equals(ParsedReaderResultType.EMAIL_ADDRESS)) {
String email = ((EmailAddressParsedResult) result).getEmailAddress();
showOpenURL("Compose E-mail?", email, "mailto:" + email);
//} else if (type.equals(ParsedReaderResultType.GEO)) {
// GeoParsedResult geoResult = (GeoParsedResult) result;
// showOpenURL("Open In Google Maps?", geoResult.getDisplayResult(), geoResult.getGoogleMapsURI());
} else if (type.equals(ParsedReaderResultType.SMS)) {
SMSParsedResult smsResult = (SMSParsedResult) result;
showOpenURL("Compose SMS?", smsResult.getNumber(), smsResult.getSMSURI());
} else if (type.equals(ParsedReaderResultType.UPC)) {
String upc = ((UPCParsedResult) result).getUPC();
String uri = "http://www.upcdatabase.com/item.asp?upc=" + upc;