Files
phonegap-plugins/BlackBerry/BarcodeScanner/EncodeAction.java
2011-10-26 09:55:37 -05:00

271 lines
9.8 KiB
Java

/*
* PhoneGap is available under *either* the terms of the modified BSD license *or* the
* MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
*
* Copyright (c) 2011, IBM Corporation
*/
package com.phonegap.plugins.barcodescanner;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import net.rim.device.api.io.Base64OutputStream;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.PNGEncodedImage;
import com.phonegap.api.PluginResult;
import com.phonegap.json4j.JSONArray;
import com.phonegap.json4j.JSONException;
/**
* Handles the common code for the barcode encode action. Implements argument
* processing and text encoding formatting and generation of return data. An OS
* specific implementation is used to perform the actual encoding of text.
*/
class EncodeAction {
// Types of text content which can be encoded in a barcode.
private static String ENCODE_CONTACT = "CONTACT";
private static String ENCODE_EMAIL = "EMAIL";
private static String ENCODE_LOCATION = "LOCATION";
private static String ENCODE_PHONE = "PHONE";
private static String ENCODE_SMS = "SMS";
private static String ENCODE_TEXT = "TEXT";
// Common argument parameters.
private static final int ARG_ENCODE_TYPE = 0;
private static final int ARG_ENCODE_DEST = 1;
private static final int ARG_ENCODE_WIDTH = 2;
private static final int ARG_ENCODE_HEIGHT = 3;
// Argument containing data for ENCODE_EMAIL, ENCODE_PHONE, ENCODE_SMS,
// ENCODE_TEXT content type.
private static final int ARG_ENCODE_TEXT = 4;
// Arguments containing data for ENCODE_CONTACT content type.
private static final int ARG_ENCODE_CONTACT_ADDRESS = 4;
private static final int ARG_ENCODE_CONTACT_BIRTHDAY = 5;
private static final int ARG_ENCODE_CONTACT_EMAIL = 6;
private static final int ARG_ENCODE_CONTACT_NAME = 7;
private static final int ARG_ENCODE_CONTACT_NICKNAME = 8;
private static final int ARG_ENCODE_CONTACT_NOTE = 9;
private static final int ARG_ENCODE_CONTACT_TELEPHONE = 10;
private static final int ARG_ENCODE_CONTACT_URL = 11;
// Arguments containing data for ENCODE_LOCATION content type.
private static final int ARG_ENCODE_LOCATION_LAT = 4;
private static final int ARG_ENCODE_LOCATION_LONG = 5;
/** Return the result as a Base-64 encoded string. */
private static final int DESTINATION_DATA_URL = 0;
/** Return the result as a file URI. */
private static final int DESTINATION_FILE_URI = 1;
/**
* Parses the passed in arguments and formats the arguments into a text
* string that can be encoded. Calls the OS specific implementation to
* encode the text string then passes the result (based64 encoded string or
* file URI) back to the caller.
*
* @param args
* JSON array of arguments containing encoding options and data.
* @return a success or error result.
*/
PluginResult encode(JSONArray args) {
String text = null;
// Default the width and height of barcode image to 200x200.
int width = 200;
int height = 200;
int destination = DESTINATION_DATA_URL;
// Parse the arguments specified.
if (args != null && args.length() > 0) {
// Default to simple text encoding if not specified.
String encodeType = ENCODE_TEXT;
try {
if (!args.isNull(ARG_ENCODE_TYPE)) {
encodeType = args.getString(ARG_ENCODE_TYPE).toUpperCase();
}
if (!args.isNull(ARG_ENCODE_DEST)) {
int destType = args.getInt(ARG_ENCODE_DEST);
if (destType == DESTINATION_FILE_URI) {
destination = DESTINATION_FILE_URI;
}
}
if (!args.isNull(ARG_ENCODE_WIDTH)) {
int tmp = args.getInt(ARG_ENCODE_WIDTH);
if (tmp > 0) {
width = tmp;
}
}
if (!args.isNull(ARG_ENCODE_HEIGHT)) {
int tmp = args.getInt(ARG_ENCODE_HEIGHT);
if (tmp > 0) {
height = tmp;
}
}
text = getEncodeText(encodeType, args);
} catch (JSONException e) {
return new PluginResult(PluginResult.Status.JSON_EXCEPTION,
"One of the barcodescanner encode options is not valid JSON.");
}
}
// Ensure there is something to encode.
if (text == null || text.length() == 0) {
return new PluginResult(PluginResult.Status.ERROR,
"User did not specify data to encode");
}
Bitmap bitmap = null;
try {
// Invoke OS specific encoder to encode the data.
bitmap = Encoder.createBitmap(Encoder.QR_CODE, text, width,
height);
} catch (Exception e) {
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
}
// Return the encoding in the proper format, either a base64 encoded
// string or a file URI to where the image is stored.
PluginResult result = null;
if (destination == DESTINATION_DATA_URL) {
String imageData = null;
try {
imageData = encodeImage(bitmap);
result = new PluginResult(PluginResult.Status.OK, imageData);
} catch (IOException e) {
result = new PluginResult(PluginResult.Status.IO_EXCEPTION,
e.getMessage());
}
}
return result;
}
/**
* Parses the arguments based on the specified format type to build a string
* that can be properly encoded.
*
* @param type
* the type of data to encode.
* @param args
* the arguments passed to the encode method.
* @return a formatted string ready to be encoded.
* @throws JSONException
*/
private String getEncodeText(String type, JSONArray args)
throws JSONException {
String text = null;
// Build the string for a contact as specified in the NTT DoCoMo
// document for MECARD.
// http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/function/application/addressbook/index.html
if (ENCODE_CONTACT.equals(type)) {
StringBuffer contactData = new StringBuffer();
contactData.append("MECARD:");
String data = args.getString(ARG_ENCODE_CONTACT_ADDRESS);
if (data != null) {
contactData.append("ADR:").append(data.trim()).append(';');
}
data = args.getString(ARG_ENCODE_CONTACT_BIRTHDAY);
if (data != null) {
contactData.append("BDAY:").append(data.trim()).append(';');
}
data = args.getString(ARG_ENCODE_CONTACT_EMAIL);
if (data != null) {
contactData.append("EMAIL:").append(data.trim()).append(';');
}
data = args.getString(ARG_ENCODE_CONTACT_NAME);
if (data != null) {
contactData.append("N:").append(data.trim()).append(';');
}
data = args.getString(ARG_ENCODE_CONTACT_NICKNAME);
if (data != null) {
contactData.append("NICKNAME:").append(data.trim()).append(';');
}
data = args.getString(ARG_ENCODE_CONTACT_NOTE);
if (data != null) {
contactData.append("NOTE:").append(data.trim()).append(';');
}
data = args.getString(ARG_ENCODE_CONTACT_TELEPHONE);
if (data != null) {
contactData.append("TEL:").append(data.trim()).append(';');
}
data = args.getString(ARG_ENCODE_CONTACT_URL);
if (data != null) {
contactData.append("URL:").append(data.trim()).append(';');
}
if (contactData.length() > 0) {
contactData.append(';');
text = contactData.toString();
}
} else if (ENCODE_EMAIL.equals(type)) {
text = "mailto:" + args.getString(ARG_ENCODE_TEXT);
} else if (ENCODE_LOCATION.equals(type)) {
String latitude = args.getString(ARG_ENCODE_LOCATION_LAT);
String longitude = args.getString(ARG_ENCODE_LOCATION_LONG);
if (latitude != null && longitude != null) {
text = "geo:" + latitude + ',' + longitude;
}
} else if (ENCODE_PHONE.equals(type)) {
text = "tel:" + args.getString(ARG_ENCODE_TEXT);
} else if (ENCODE_SMS.equals(type)) {
text = "sms:" + args.getString(ARG_ENCODE_TEXT);
} else if (ENCODE_TEXT.equals(type)) {
text = args.getString(ARG_ENCODE_TEXT);
}
return text;
}
/**
* Converts the specified Bitmap contents to a Base64-encoded string.
*
* @param bitmap
* Bitmap to convert.
* @return Bitmap contents as a Base64-encoded String
*/
private String encodeImage(Bitmap bitmap) throws IOException {
String imageData = null;
PNGEncodedImage image = PNGEncodedImage.encode(bitmap);
byte[] bytes = image.getData();
ByteArrayOutputStream byteArrayOS = null;
try {
// encode file contents using BASE64 encoding
byteArrayOS = new ByteArrayOutputStream();
Base64OutputStream base64OS = new Base64OutputStream(byteArrayOS);
base64OS.write(bytes);
base64OS.flush();
base64OS.close();
imageData = byteArrayOS.toString();
} finally {
if (byteArrayOS != null)
byteArrayOS.close();
}
return imageData;
}
}