Update all Java code to use Java 6

git-svn-id: https://zxing.googlecode.com/svn/trunk@2002 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2011-11-02 11:16:30 +00:00
parent 8683a96213
commit db60385d7d
320 changed files with 3116 additions and 8435 deletions

11
README
View file

@ -1,11 +0,0 @@
Please refer to the project page for more information:
http://code.google.com/p/zxing/
in particular:
http://code.google.com/p/zxing/wiki/GettingStarted
To get started, you can try building and running the command-line client;
you will need to have Apache's Ant tool installed to run this:
ant -f core/build.xml
ant -f javase/build.xml
java -cp javase/javase.jar:core/core.jar com.google.zxing.client.j2se.CommandLineRunner [URL]

View file

@ -28,8 +28,8 @@
<mkdir dir="build"/>
<javac srcdir="src"
destdir="build"
source="1.5"
target="1.5"
source="6"
target="6"
optimize="true"
debug="true"
deprecation="true"

View file

@ -20,7 +20,7 @@
<artifactId>android-integration</artifactId>
<packaging>jar</packaging>
<name>ZXing Android Integration lib</name>
<version>1.6-SNAPSHOT</version>
<version>2.0-SNAPSHOT</version>
<description>Integration helper classes for Android applications wanting to create/scan bar codes</description>
<url>http://code.google.com/p/zxing/</url>
<inceptionYear>2007</inceptionYear>

View file

@ -103,7 +103,7 @@ public final class IntentIntegrator {
static {
Method temp;
try {
temp = Intent.class.getMethod("setPackage", new Class[] {String.class});
temp = Intent.class.getMethod("setPackage", String.class);
} catch (NoSuchMethodException nsme) {
temp = null;
}
@ -212,6 +212,7 @@ public final class IntentIntegrator {
downloadDialog.setTitle(stringTitle);
downloadDialog.setMessage(stringMessage);
downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Uri uri = Uri.parse("market://search?q=pname:" + PACKAGE);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
@ -224,6 +225,7 @@ public final class IntentIntegrator {
}
});
downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {}
});
return downloadDialog.show();

View file

@ -4,7 +4,7 @@
<link rel="stylesheet" href="../style.css" type="text/css"/>
</head>
<body>
<p>Barcode Scanner continuously scans a square region shown on your screen &mdash; just line up the
<p>Barcode Scanner continuously scans a square region shown on your screen -- just line up the
phone so the barcode is completely inside the viewfinder rectangle:</p>
<p style="text-align:center">
<img src="../images/demo-yes.png" alt="Yes"/>&nbsp;&nbsp;&nbsp;<img src="../images/demo-no.png" alt="No"/>

View file

@ -88,6 +88,7 @@ public final class BeepManager {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
// When the beep has finished playing, rewind to queue up another one.
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer player) {
player.seekTo(0);
}

View file

@ -63,11 +63,11 @@ import android.widget.Toast;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
/**
* This activity opens the camera and does the actual scanning on a background thread. It draws a
@ -97,14 +97,11 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
private static final String RETURN_CODE_PLACEHOLDER = "{CODE}";
private static final String RETURN_URL_PARAM = "ret";
private static final Set<ResultMetadataType> DISPLAYABLE_METADATA_TYPES;
static {
DISPLAYABLE_METADATA_TYPES = new HashSet<ResultMetadataType>(5);
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.ISSUE_NUMBER);
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.SUGGESTED_PRICE);
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.ERROR_CORRECTION_LEVEL);
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.POSSIBLE_COUNTRY);
}
private static final Set<ResultMetadataType> DISPLAYABLE_METADATA_TYPES =
EnumSet.of(ResultMetadataType.ISSUE_NUMBER,
ResultMetadataType.SUGGESTED_PRICE,
ResultMetadataType.ERROR_CORRECTION_LEVEL,
ResultMetadataType.POSSIBLE_COUNTRY);
private enum Source {
NATIVE_APP_INTENT,
@ -123,7 +120,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
private Source source;
private String sourceUrl;
private String returnUrlTemplate;
private Vector<BarcodeFormat> decodeFormats;
private Collection<BarcodeFormat> decodeFormats;
private String characterSet;
private String versionName;
private HistoryManager historyManager;
@ -132,6 +129,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
private final DialogInterface.OnClickListener aboutListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.zxing_url)));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
@ -313,33 +311,25 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case SHARE_ID: {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
switch (item.getItemId()) {
case SHARE_ID:
intent.setClassName(this, ShareActivity.class.getName());
startActivity(intent);
break;
}
case HISTORY_ID: {
case HISTORY_ID:
AlertDialog historyAlert = historyManager.buildAlert();
historyAlert.show();
break;
}
case SETTINGS_ID: {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
case SETTINGS_ID:
intent.setClassName(this, PreferencesActivity.class.getName());
startActivity(intent);
break;
}
case HELP_ID: {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
case HELP_ID:
intent.setClassName(this, HelpActivity.class.getName());
startActivity(intent);
break;
}
case ABOUT_ID:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.title_about) + versionName);
@ -353,6 +343,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
return super.onOptionsItemSelected(item);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
@ -363,10 +354,12 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@ -440,8 +433,8 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
paint.setStrokeWidth(4.0f);
drawLine(canvas, paint, points[0], points[1]);
} else if (points.length == 4 &&
(rawResult.getBarcodeFormat().equals(BarcodeFormat.UPC_A) ||
rawResult.getBarcodeFormat().equals(BarcodeFormat.EAN_13))) {
(rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A ||
rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
// Hacky special case -- draw two lines, for the barcode and metadata
drawLine(canvas, paint, points[0], points[1]);
drawLine(canvas, paint, points[2], points[3]);
@ -488,8 +481,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
View metaTextViewLabel = findViewById(R.id.meta_text_view_label);
metaTextView.setVisibility(View.GONE);
metaTextViewLabel.setVisibility(View.GONE);
Map<ResultMetadataType,Object> metadata =
(Map<ResultMetadataType,Object>) rawResult.getResultMetadata();
Map<ResultMetadataType,Object> metadata = rawResult.getResultMetadata();
if (metadata != null) {
StringBuilder metadataText = new StringBuilder(20);
for (Map.Entry<ResultMetadataType,Object> entry : metadata.entrySet()) {

View file

@ -29,7 +29,7 @@ import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.util.Vector;
import java.util.Collection;
/**
* This class handles all the messaging which comprises the state machine for capture.
@ -50,7 +50,7 @@ public final class CaptureActivityHandler extends Handler {
DONE
}
CaptureActivityHandler(CaptureActivity activity, Vector<BarcodeFormat> decodeFormats,
CaptureActivityHandler(CaptureActivity activity, Collection<BarcodeFormat> decodeFormats,
String characterSet) {
this.activity = activity;
decodeThread = new DecodeThread(activity, decodeFormats, characterSet,
@ -112,7 +112,8 @@ public final class CaptureActivityHandler extends Handler {
Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
quit.sendToTarget();
try {
decodeThread.join();
// Wait at most half a second; should be enough time, and onPause() will timeout quickly
decodeThread.join(500L);
} catch (InterruptedException e) {
// continue
}

View file

@ -17,8 +17,9 @@
package com.google.zxing.client.android;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Vector;
import java.util.regex.Pattern;
import android.content.Intent;
@ -29,32 +30,26 @@ final class DecodeFormatManager {
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
static final Vector<BarcodeFormat> PRODUCT_FORMATS;
static final Vector<BarcodeFormat> ONE_D_FORMATS;
static final Vector<BarcodeFormat> QR_CODE_FORMATS;
static final Vector<BarcodeFormat> DATA_MATRIX_FORMATS;
static final Collection<BarcodeFormat> PRODUCT_FORMATS;
static final Collection<BarcodeFormat> ONE_D_FORMATS;
static final Collection<BarcodeFormat> QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
static final Collection<BarcodeFormat> DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);
static {
PRODUCT_FORMATS = new Vector<BarcodeFormat>(5);
PRODUCT_FORMATS.add(BarcodeFormat.UPC_A);
PRODUCT_FORMATS.add(BarcodeFormat.UPC_E);
PRODUCT_FORMATS.add(BarcodeFormat.EAN_13);
PRODUCT_FORMATS.add(BarcodeFormat.EAN_8);
PRODUCT_FORMATS.add(BarcodeFormat.RSS_14);
ONE_D_FORMATS = new Vector<BarcodeFormat>(PRODUCT_FORMATS.size() + 4);
PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A,
BarcodeFormat.UPC_E,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.RSS_14);
ONE_D_FORMATS = EnumSet.of(BarcodeFormat.CODE_39,
BarcodeFormat.CODE_93,
BarcodeFormat.CODE_128,
BarcodeFormat.ITF);
ONE_D_FORMATS.addAll(PRODUCT_FORMATS);
ONE_D_FORMATS.add(BarcodeFormat.CODE_39);
ONE_D_FORMATS.add(BarcodeFormat.CODE_93);
ONE_D_FORMATS.add(BarcodeFormat.CODE_128);
ONE_D_FORMATS.add(BarcodeFormat.ITF);
QR_CODE_FORMATS = new Vector<BarcodeFormat>(1);
QR_CODE_FORMATS.add(BarcodeFormat.QR_CODE);
DATA_MATRIX_FORMATS = new Vector<BarcodeFormat>(1);
DATA_MATRIX_FORMATS.add(BarcodeFormat.DATA_MATRIX);
}
private DecodeFormatManager() {}
static Vector<BarcodeFormat> parseDecodeFormats(Intent intent) {
static Collection<BarcodeFormat> parseDecodeFormats(Intent intent) {
List<String> scanFormats = null;
String scanFormatsString = intent.getStringExtra(Intents.Scan.FORMATS);
if (scanFormatsString != null) {
@ -63,7 +58,7 @@ final class DecodeFormatManager {
return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE));
}
static Vector<BarcodeFormat> parseDecodeFormats(Uri inputUri) {
static Collection<BarcodeFormat> parseDecodeFormats(Uri inputUri) {
List<String> formats = inputUri.getQueryParameters(Intents.Scan.FORMATS);
if (formats != null && formats.size() == 1 && formats.get(0) != null){
formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
@ -71,10 +66,10 @@ final class DecodeFormatManager {
return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE));
}
private static Vector<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats,
private static Collection<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats,
String decodeMode) {
if (scanFormats != null) {
Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>();
Collection<BarcodeFormat> formats = EnumSet.noneOf(BarcodeFormat.class);
try {
for (String format : scanFormats) {
formats.add(BarcodeFormat.valueOf(format));

View file

@ -30,7 +30,7 @@ import android.os.Looper;
import android.os.Message;
import android.util.Log;
import java.util.Hashtable;
import java.util.Map;
final class DecodeHandler extends Handler {
@ -40,7 +40,7 @@ final class DecodeHandler extends Handler {
private final MultiFormatReader multiFormatReader;
private boolean running = true;
DecodeHandler(CaptureActivity activity, Hashtable<DecodeHintType, Object> hints) {
DecodeHandler(CaptureActivity activity, Map<DecodeHintType,Object> hints) {
multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(hints);
this.activity = activity;

View file

@ -25,8 +25,10 @@ import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
/**
@ -39,24 +41,24 @@ final class DecodeThread extends Thread {
public static final String BARCODE_BITMAP = "barcode_bitmap";
private final CaptureActivity activity;
private final Hashtable<DecodeHintType, Object> hints;
private final Map<DecodeHintType,Object> hints;
private Handler handler;
private final CountDownLatch handlerInitLatch;
DecodeThread(CaptureActivity activity,
Vector<BarcodeFormat> decodeFormats,
Collection<BarcodeFormat> decodeFormats,
String characterSet,
ResultPointCallback resultPointCallback) {
this.activity = activity;
handlerInitLatch = new CountDownLatch(1);
hints = new Hashtable<DecodeHintType, Object>(3);
hints = new EnumMap<DecodeHintType,Object>(DecodeHintType.class);
// The prefs can't change while the thread is running, so pick them up once here.
if (decodeFormats == null || decodeFormats.isEmpty()) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
decodeFormats = new Vector<BarcodeFormat>();
decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, true)) {
decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
}

View file

@ -33,14 +33,17 @@ public final class FinishListener
this.activityToFinish = activityToFinish;
}
@Override
public void onCancel(DialogInterface dialogInterface) {
run();
}
@Override
public void onClick(DialogInterface dialogInterface, int i) {
run();
}
@Override
public void run() {
activityToFinish.finish();
}

View file

@ -64,12 +64,14 @@ public final class HelpActivity extends Activity {
private Button backButton;
private final Button.OnClickListener backListener = new Button.OnClickListener() {
@Override
public void onClick(View view) {
webView.goBack();
}
};
private final Button.OnClickListener doneListener = new Button.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
@ -77,6 +79,7 @@ public final class HelpActivity extends Activity {
private final DialogInterface.OnClickListener groupsListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Intent.ACTION_VIEW, BUGGY_URI);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

View file

@ -24,6 +24,7 @@ import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
@ -90,7 +91,7 @@ public final class HttpHelper {
}
}
private static String getEncoding(HttpURLConnection connection) {
private static String getEncoding(URLConnection connection) {
String contentTypeHeader = connection.getHeaderField("Content-Type");
if (contentTypeHeader != null) {
int charsetStart = contentTypeHeader.indexOf("charset=");
@ -101,7 +102,7 @@ public final class HttpHelper {
return "UTF-8";
}
private static String consume(HttpURLConnection connection) throws IOException {
private static String consume(URLConnection connection) throws IOException {
String encoding = getEncoding(connection);
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = connection.getInputStream();

View file

@ -40,7 +40,7 @@ final class InactivityTimer {
Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
private final Activity activity;
private ScheduledFuture<?> inactivityFuture = null;
private final PowerStatusReceiver powerStatusReceiver = new PowerStatusReceiver();
private final BroadcastReceiver powerStatusReceiver = new PowerStatusReceiver();
InactivityTimer(Activity activity) {
this.activity = activity;
@ -61,17 +61,20 @@ final class InactivityTimer {
}
}
public void onPause(){
public void onPause() {
cancel();
activity.unregisterReceiver(powerStatusReceiver);
}
public void onResume(){
activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
onActivity();
}
private void cancel() {
if (inactivityFuture != null) {
inactivityFuture.cancel(true);
ScheduledFuture<?> future = inactivityFuture;
if (future != null) {
future.cancel(true);
inactivityFuture = null;
}
}
@ -82,6 +85,7 @@ final class InactivityTimer {
}
private static final class DaemonThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setDaemon(true);
@ -95,9 +99,8 @@ final class InactivityTimer {
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
// 0 indicates that we're on battery
// In Android 2.0+, use BatteryManager.EXTRA_PLUGGED
if (intent.getIntExtra("plugged", -1) == 0) {
InactivityTimer.this.onActivity();
} else {
int batteryPlugged = intent.getIntExtra("plugged", -1);
if (batteryPlugged > 0) {
InactivityTimer.this.cancel();
}
}

View file

@ -68,6 +68,7 @@ public final class PreferencesActivity extends PreferenceActivity
disableLastCheckedPref();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
disableLastCheckedPref();
}

View file

@ -27,6 +27,7 @@ final class ViewfinderResultPointCallback implements ResultPointCallback {
this.viewfinderView = viewfinderView;
}
@Override
public void foundPossibleResultPoint(ResultPoint point) {
viewfinderView.addPossibleResultPoint(point);
}

View file

@ -34,6 +34,7 @@ final class BrowseBookListener implements AdapterView.OnItemClickListener {
this.items = items;
}
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
if (position < 1) {
// Clicked header, ignore it

View file

@ -82,12 +82,14 @@ public final class SearchBookContentsActivity extends Activity {
};
private final Button.OnClickListener buttonListener = new Button.OnClickListener() {
@Override
public void onClick(View view) {
launchSearch();
}
};
private final View.OnKeyListener keyListener = new View.OnKeyListener() {
@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
launchSearch();

View file

@ -35,6 +35,7 @@ final class AutoFocusCallback implements Camera.AutoFocusCallback {
this.autoFocusMessage = autoFocusMessage;
}
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (autoFocusHandler != null) {
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);

View file

@ -41,6 +41,7 @@ final class PreviewCallback implements Camera.PreviewCallback {
this.previewMessage = previewMessage;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
if (!useOneShotPreviewCallback) {

View file

@ -42,8 +42,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
/**
* This class does the work of decoding the user's request and extracting all the data
@ -104,7 +105,7 @@ final class QRCodeEncoder {
// Ignore it then
format = null;
}
if (format == null || BarcodeFormat.QR_CODE.equals(format)) {
if (format == null || format == BarcodeFormat.QR_CODE) {
String type = intent.getStringExtra(Intents.Encode.TYPE);
if (type == null || type.length() == 0) {
return false;
@ -379,10 +380,10 @@ final class QRCodeEncoder {
}
Bitmap encodeAsBitmap() throws WriterException {
Hashtable<EncodeHintType,Object> hints = null;
Map<EncodeHintType,Object> hints = null;
String encoding = guessAppropriateEncoding(contents);
if (encoding != null) {
hints = new Hashtable<EncodeHintType,Object>(2);
hints = new EnumMap<EncodeHintType,Object>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, encoding);
}
MultiFormatWriter writer = new MultiFormatWriter();

View file

@ -46,6 +46,7 @@ final class HistoryClickListener implements DialogInterface.OnClickListener {
this.items = items;
}
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (i == items.size()) {
// Share history.
@ -71,6 +72,7 @@ final class HistoryClickListener implements DialogInterface.OnClickListener {
builder.setMessage(R.string.msg_sure);
builder.setCancelable(true);
builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface2, int i2) {
historyManager.clearHistory();
}

View file

@ -30,6 +30,7 @@ import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Handles address book entries.
@ -39,10 +40,10 @@ import java.util.Date;
public final class AddressBookResultHandler extends ResultHandler {
private static final DateFormat[] DATE_FORMATS = {
new SimpleDateFormat("yyyyMMdd"),
new SimpleDateFormat("yyyyMMdd'T'HHmmss"),
new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"),
new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH),
new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH),
new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH),
};
private final boolean[] fields;
@ -167,7 +168,7 @@ public final class AddressBookResultHandler extends ResultHandler {
@Override
public CharSequence getDisplayContents() {
AddressBookParsedResult result = (AddressBookParsedResult) getResult();
StringBuffer contents = new StringBuffer(100);
StringBuilder contents = new StringBuilder(100);
ParsedResult.maybeAppend(result.getNames(), contents);
int namesLength = contents.length();

View file

@ -28,6 +28,7 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
/**
* Handles calendar entries encoded in QR Codes.
@ -36,8 +37,8 @@ import java.util.GregorianCalendar;
*/
public final class CalendarResultHandler extends ResultHandler {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
private static final int[] buttons = {
R.string.button_add_calendar
@ -72,7 +73,7 @@ public final class CalendarResultHandler extends ResultHandler {
@Override
public CharSequence getDisplayContents() {
CalendarParsedResult calResult = (CalendarParsedResult) getResult();
StringBuffer result = new StringBuffer(100);
StringBuilder result = new StringBuilder(100);
ParsedResult.maybeAppend(calResult.getSummary(), result);
appendTime(calResult.getStart(), result);
@ -89,7 +90,7 @@ public final class CalendarResultHandler extends ResultHandler {
return result.toString();
}
private static void appendTime(String when, StringBuffer result) {
private static void appendTime(String when, StringBuilder result) {
if (when.length() == 8) {
// Show only year/month/day
Date date;

View file

@ -42,6 +42,7 @@ public final class ISBNResultHandler extends ResultHandler {
public ISBNResultHandler(Activity activity, ParsedResult result, Result rawResult) {
super(activity, result, rawResult);
showGoogleShopperButton(new View.OnClickListener() {
@Override
public void onClick(View view) {
ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();
openGoogleShopper(isbnResult.getISBN());
@ -62,6 +63,7 @@ public final class ISBNResultHandler extends ResultHandler {
@Override
public void handleButtonPress(final int index) {
showNotOurResults(index, new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();
switch (index) {

View file

@ -41,6 +41,7 @@ public final class ProductResultHandler extends ResultHandler {
public ProductResultHandler(Activity activity, ParsedResult result, Result rawResult) {
super(activity, result, rawResult);
showGoogleShopperButton(new View.OnClickListener() {
@Override
public void onClick(View view) {
ProductParsedResult productResult = (ProductParsedResult) getResult();
openGoogleShopper(productResult.getNormalizedProductID());
@ -61,6 +62,7 @@ public final class ProductResultHandler extends ResultHandler {
@Override
public void handleButtonPress(final int index) {
showNotOurResults(index, new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ProductParsedResult productResult = (ProductParsedResult) getResult();
switch (index) {

View file

@ -34,6 +34,7 @@ public final class ResultButtonListener implements Button.OnClickListener {
this.index = index;
}
@Override
public void onClick(View view) {
resultHandler.handleButtonPress(index);
}

View file

@ -43,7 +43,11 @@ import android.view.View;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
/**
* A base class for the Android-specific barcode handlers. These allow the app to polymorphically
@ -61,13 +65,13 @@ public abstract class ResultHandler {
private static final DateFormat DATE_FORMAT;
static {
DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
DATE_FORMAT = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
// For dates without a time, for purposes of interacting with Android, the resulting timestamp
// needs to be midnight of that day in GMT. See:
// http://code.google.com/p/android/issues/detail?id=8330
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
}
private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
private static final String GOOGLE_SHOPPER_PACKAGE = "com.google.android.apps.shopper";
private static final String GOOGLE_SHOPPER_ACTIVITY = GOOGLE_SHOPPER_PACKAGE +
@ -105,6 +109,7 @@ public abstract class ResultHandler {
private final DialogInterface.OnClickListener shopperMarketListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(MARKET_URI_PREFIX +
GOOGLE_SHOPPER_PACKAGE + MARKET_REFERRER_SUFFIX)));

View file

@ -18,7 +18,6 @@ package com.google.zxing.client.android.result;
import com.google.zxing.Result;
import com.google.zxing.client.result.ParsedResult;
import com.google.zxing.client.result.ParsedResultType;
import com.google.zxing.client.result.ResultParser;
import android.app.Activity;
@ -34,33 +33,31 @@ public final class ResultHandlerFactory {
public static ResultHandler makeResultHandler(Activity activity, Result rawResult) {
ParsedResult result = parseResult(rawResult);
ParsedResultType type = result.getType();
if (type.equals(ParsedResultType.ADDRESSBOOK)) {
switch (result.getType()) {
case ADDRESSBOOK:
return new AddressBookResultHandler(activity, result);
} else if (type.equals(ParsedResultType.EMAIL_ADDRESS)) {
case EMAIL_ADDRESS:
return new EmailAddressResultHandler(activity, result);
} else if (type.equals(ParsedResultType.PRODUCT)) {
case PRODUCT:
return new ProductResultHandler(activity, result, rawResult);
} else if (type.equals(ParsedResultType.URI)) {
case URI:
return new URIResultHandler(activity, result);
} else if (type.equals(ParsedResultType.WIFI)) {
case WIFI:
return new WifiResultHandler(activity, result);
} else if (type.equals(ParsedResultType.TEXT)) {
case TEXT:
return new TextResultHandler(activity, result, rawResult);
} else if (type.equals(ParsedResultType.GEO)) {
case GEO:
return new GeoResultHandler(activity, result);
} else if (type.equals(ParsedResultType.TEL)) {
case TEL:
return new TelResultHandler(activity, result);
} else if (type.equals(ParsedResultType.SMS)) {
case SMS:
return new SMSResultHandler(activity, result);
} else if (type.equals(ParsedResultType.CALENDAR)) {
case CALENDAR:
return new CalendarResultHandler(activity, result);
} else if (type.equals(ParsedResultType.ISBN)) {
case ISBN:
return new ISBNResultHandler(activity, result, rawResult);
} else {
// The TextResultHandler is the fallthrough for unsupported formats.
return new TextResultHandler(activity, result, rawResult);
}
return new TextResultHandler(activity, result, rawResult);
}
private static ParsedResult parseResult(Result rawResult) {

View file

@ -65,7 +65,7 @@ public final class SMSResultHandler extends ResultHandler {
@Override
public CharSequence getDisplayContents() {
SMSParsedResult smsResult = (SMSParsedResult) getResult();
StringBuffer contents = new StringBuffer(50);
StringBuilder contents = new StringBuilder(50);
String[] rawNumbers = smsResult.getNumbers();
String[] formattedNumbers = new String[rawNumbers.length];
for (int i = 0; i < rawNumbers.length; i++) {

View file

@ -71,7 +71,7 @@ public final class WifiResultHandler extends ResultHandler {
@Override
public CharSequence getDisplayContents() {
WifiParsedResult wifiResult = (WifiParsedResult) getResult();
StringBuffer contents = new StringBuffer(50);
StringBuilder contents = new StringBuilder(50);
String wifiLabel = parent.getString(R.string.wifi_ssid_label);
ParsedResult.maybeAppend(wifiLabel + '\n' + wifiResult.getSsid(), contents);
String typeLabel = parent.getString(R.string.wifi_type_label);

View file

@ -34,6 +34,7 @@ final class KillerCallable implements Callable<Void> {
this.unit = unit;
}
@Override
public Void call() throws ExecutionException, InterruptedException {
try {
future.get(timeout, unit);

View file

@ -48,6 +48,7 @@ public abstract class SupplementalInfoRetriever implements Callable<Void> {
private static synchronized ExecutorService getExecutorService() {
if (executorInstance == null) {
executorInstance = Executors.newCachedThreadPool(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
@ -95,6 +96,7 @@ public abstract class SupplementalInfoRetriever implements Callable<Void> {
this.historyManager = historyManager;
}
@Override
public final Void call() throws IOException, InterruptedException {
retrieveSupplementalInfo();
return null;
@ -138,6 +140,7 @@ public abstract class SupplementalInfoRetriever implements Callable<Void> {
}
handler.post(new Runnable() {
@Override
public void run() {
textView.append(content);
textView.setMovementMethod(LinkMovementMethod.getInstance());

View file

@ -39,31 +39,35 @@ final class BookmarkAdapter extends BaseAdapter {
private final Context context;
private final Cursor cursor;
public BookmarkAdapter(Context context, Cursor cursor) {
BookmarkAdapter(Context context, Cursor cursor) {
this.context = context;
this.cursor = cursor;
}
@Override
public int getCount() {
return cursor.getCount();
}
@Override
public Object getItem(int index) {
// Not used, so no point in retrieving it.
return null;
}
@Override
public long getItemId(int index) {
return index;
}
@Override
public View getView(int index, View view, ViewGroup viewGroup) {
LinearLayout layout;
if (!(view instanceof LinearLayout)) {
if (view instanceof LinearLayout) {
layout = (LinearLayout) view;
} else {
LayoutInflater factory = LayoutInflater.from(context);
layout = (LinearLayout) factory.inflate(R.layout.bookmark_picker_list_item, viewGroup, false);
} else {
layout = (LinearLayout) view;
}
cursor.moveToPosition(index);

View file

@ -98,6 +98,7 @@ final class LoadPackagesAsyncTask extends AsyncTask<List<String[]>, Void, List<S
}
private static class ByFirstStringComparator implements Comparator<String[]>, Serializable {
@Override
public int compare(String[] o1, String[] o2) {
return o1[0].compareTo(o2[0]);
}

View file

@ -71,6 +71,7 @@ public final class ShareActivity extends Activity {
private Button clipboardButton;
private final Button.OnClickListener contactListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.People.CONTENT_URI);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
@ -79,6 +80,7 @@ public final class ShareActivity extends Activity {
};
private final Button.OnClickListener bookmarkListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
@ -88,6 +90,7 @@ public final class ShareActivity extends Activity {
};
private final Button.OnClickListener appListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
@ -97,6 +100,7 @@ public final class ShareActivity extends Activity {
};
private final Button.OnClickListener clipboardListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
// Should always be true, because we grey out the clipboard button in onResume() if it's empty
@ -107,6 +111,7 @@ public final class ShareActivity extends Activity {
};
private final View.OnKeyListener textListener = new View.OnKeyListener() {
@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
String text = ((TextView) view).getText().toString();

View file

@ -41,6 +41,7 @@ public final class WifiConfigManager {
final String password,
final String networkTypeString) {
Runnable configureRunnable = new Runnable() {
@Override
public void run() {
// Start WiFi, otherwise nothing will work
if (!wifiManager.isWifiEnabled()) {

View file

@ -27,12 +27,12 @@ import android.widget.TextView;
public final class BenchmarkActivity extends Activity {
private static final String TAG = BenchmarkActivity.class.getSimpleName();
private static final String PATH = "/sdcard/zxingbenchmark";
private static final String TAG = "ZXingBenchmark";
private Button mRunBenchmarkButton;
private TextView mTextView;
private BenchmarkThread mBenchmarkThread;
private Button runBenchmarkButton;
private TextView textView;
private BenchmarkThread benchmarkThread;
@Override
public void onCreate(Bundle icicle) {
@ -40,32 +40,33 @@ public final class BenchmarkActivity extends Activity {
setContentView(R.layout.benchmark);
mRunBenchmarkButton = (Button) findViewById(R.id.benchmark_run);
mRunBenchmarkButton.setOnClickListener(mRunBenchmark);
mTextView = (TextView) findViewById(R.id.benchmark_help);
runBenchmarkButton = (Button) findViewById(R.id.benchmark_run);
runBenchmarkButton.setOnClickListener(runBenchmark);
textView = (TextView) findViewById(R.id.benchmark_help);
mBenchmarkThread = null;
benchmarkThread = null;
}
public final Button.OnClickListener mRunBenchmark = new Button.OnClickListener() {
private final Button.OnClickListener runBenchmark = new Button.OnClickListener() {
@Override
public void onClick(View v) {
if (mBenchmarkThread == null) {
mRunBenchmarkButton.setEnabled(false);
mTextView.setText(R.string.benchmark_running);
mBenchmarkThread = new BenchmarkThread(BenchmarkActivity.this, PATH);
mBenchmarkThread.start();
if (benchmarkThread == null) {
runBenchmarkButton.setEnabled(false);
textView.setText(R.string.benchmark_running);
benchmarkThread = new BenchmarkThread(BenchmarkActivity.this, PATH);
benchmarkThread.start();
}
}
};
public final Handler mHandler = new Handler() {
final Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case R.id.benchmark_done:
handleBenchmarkDone(message);
mBenchmarkThread = null;
mRunBenchmarkButton.setEnabled(true);
benchmarkThread = null;
runBenchmarkButton.setEnabled(true);
break;
default:
break;
@ -86,7 +87,7 @@ public final class BenchmarkActivity extends Activity {
}
String totals = "TOTAL: Decoded " + count + " images in " + time + " us";
Log.v(TAG, totals);
mTextView.setText(totals + "\n\n" + getString(R.string.benchmark_help));
textView.setText(totals + "\n\n" + getString(R.string.benchmark_help));
}
}

View file

@ -20,49 +20,44 @@ import com.google.zxing.BarcodeFormat;
public final class BenchmarkItem {
private final String mPath;
private final int[] mTimes;
private int mPosition;
private boolean mDecoded;
private BarcodeFormat mFormat;
private final String path;
private final int[] times;
private int position;
private boolean decoded;
private BarcodeFormat format;
public BenchmarkItem(String path, int runs) {
if (runs <= 0) {
throw new IllegalArgumentException();
}
mPath = path;
mTimes = new int[runs];
mPosition = 0;
mDecoded = false;
mFormat = null;
this.path = path;
times = new int[runs];
position = 0;
decoded = false;
format = null;
}
public void addResult(int microseconds) {
mTimes[mPosition] = microseconds;
mPosition++;
times[position] = microseconds;
position++;
}
public void setDecoded(boolean decoded) {
mDecoded = decoded;
this.decoded = decoded;
}
public void setFormat(BarcodeFormat format) {
mFormat = format;
this.format = format;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append(mDecoded ? ("DECODED " + mFormat.toString() + ": ") : "FAILED: ");
result.append(mPath);
StringBuilder result = new StringBuilder(30);
result.append(decoded ? "DECODED " + format.toString() + ": " : "FAILED: ");
result.append(path);
result.append(" (");
result.append(getAverageTime());
result.append(" us average)");
// int size = mTimes.length;
// for (int x = 0; x < size; x++) {
// result.append(mTimes[x]);
// result.append(" ");
// }
return result.toString();
}
@ -72,11 +67,11 @@ public final class BenchmarkItem {
* @return The average decoding time in microseconds.
*/
public int getAverageTime() {
int size = mTimes.length;
int size = times.length;
int total = 0;
int max = mTimes[0];
int max = times[0];
for (int x = 0; x < size; x++) {
int time = mTimes[x];
int time = times[x];
total += time;
if (time > max) {
max = time;
@ -84,11 +79,7 @@ public final class BenchmarkItem {
}
total -= max;
size--;
if (size > 0) {
return total / size;
} else {
return 0;
}
return size > 0 ? total / size : 0;
}
}

View file

@ -34,43 +34,43 @@ import java.util.List;
final class BenchmarkThread extends Thread {
private static final String TAG = "BenchmarkThread";
private static final String TAG = BenchmarkThread.class.getSimpleName();
private static final int RUNS = 10;
private final BenchmarkActivity mActivity;
private final String mPath;
private MultiFormatReader mMultiFormatReader;
private final BenchmarkActivity activity;
private final String path;
private MultiFormatReader multiFormatReader;
BenchmarkThread(BenchmarkActivity activity, String path) {
mActivity = activity;
mPath = path;
this.activity = activity;
this.path = path;
}
@Override
public void run() {
mMultiFormatReader = new MultiFormatReader();
mMultiFormatReader.setHints(null);
multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(null);
// Try to get in a known state before starting the benchmark
System.gc();
List<BenchmarkItem> items = new ArrayList<BenchmarkItem>();
walkTree(mPath, items);
Message message = Message.obtain(mActivity.mHandler, R.id.benchmark_done);
walkTree(path, items);
Message message = Message.obtain(activity.handler, R.id.benchmark_done);
message.obj = items;
message.sendToTarget();
}
// Recurse to allow subdirectories
private void walkTree(String path, List<BenchmarkItem> items) {
File file = new File(path);
private void walkTree(String currentPath, List<BenchmarkItem> items) {
File file = new File(currentPath);
if (file.isDirectory()) {
String[] files = file.list();
Arrays.sort(files);
for (String f : files) {
walkTree(file.getAbsolutePath() + '/' + f, items);
for (String fileName : files) {
walkTree(file.getAbsolutePath() + '/' + fileName, items);
}
} else {
BenchmarkItem item = decode(path);
BenchmarkItem item = decode(currentPath);
if (item != null) {
items.add(item);
}
@ -95,7 +95,7 @@ final class BenchmarkThread extends Thread {
long now = Debug.threadCpuTimeNanos();
try {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
result = mMultiFormatReader.decodeWithState(bitmap);
result = multiFormatReader.decodeWithState(bitmap);
success = true;
} catch (ReaderException e) {
success = false;

View file

@ -20,7 +20,6 @@ import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
@ -29,6 +28,7 @@ import android.view.SurfaceHolder;
import android.view.WindowManager;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* This object wraps the Camera service object and expects to be the only one talking to it. The
@ -38,13 +38,17 @@ import java.io.IOException;
* @author dswitkin@google.com (Daniel Switkin)
*/
final class CameraManager {
private static final String TAG = "CameraManager";
private static final String TAG = CameraManager.class.getSimpleName();
private static final int MIN_FRAME_WIDTH = 240;
private static final int MIN_FRAME_HEIGHT = 240;
private static final int MAX_FRAME_WIDTH = 480;
private static final int MAX_FRAME_HEIGHT = 360;
private static CameraManager cameraManager;
private static final Pattern SEMICOLON = Pattern.compile(";");
private Camera camera;
private final Context context;
private Point screenResolution;
@ -56,17 +60,14 @@ final class CameraManager {
private int autoFocusMessage;
private boolean initialized;
private boolean previewing;
private final boolean useOneShotPreviewCallback;
/**
* Preview frames are delivered here, which we pass on to the registered handler. Make sure to
* clear the handler so it will only receive one message.
*/
private final Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (!useOneShotPreviewCallback) {
camera.setPreviewCallback(null);
}
if (previewHandler != null) {
Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,
cameraResolution.y, data);
@ -80,6 +81,7 @@ final class CameraManager {
* Autofocus callbacks arrive here, and are dispatched to the Handler which requested them.
*/
private final Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (autoFocusHandler != null) {
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
@ -116,13 +118,6 @@ final class CameraManager {
camera = null;
initialized = false;
previewing = false;
// Camera.setOneShotPreviewCallback() has a race condition in Cupcake, so we use the older
// Camera.setPreviewCallback() on 1.5 and earlier. For Donut and later, we need to use
// the more efficient one shot callback, as the older one can swamp the system and cause it
// to run out of memory. We can't use SDK_INT because it was introduced in the Donut SDK.
//useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > Build.VERSION_CODES.CUPCAKE;
useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > 3; // 3 = Cupcake
}
/**
@ -175,9 +170,6 @@ final class CameraManager {
*/
public void stopPreview() {
if (camera != null && previewing) {
if (!useOneShotPreviewCallback) {
camera.setPreviewCallback(null);
}
camera.stopPreview();
previewHandler = null;
autoFocusHandler = null;
@ -197,11 +189,7 @@ final class CameraManager {
if (camera != null && previewing) {
previewHandler = handler;
previewMessage = message;
if (useOneShotPreviewCallback) {
camera.setOneShotPreviewCallback(previewCallback);
} else {
camera.setPreviewCallback(previewCallback);
}
}
}
@ -274,16 +262,13 @@ final class CameraManager {
Log.v(TAG, "Setting preview size: " + cameraResolution.x + ", " + cameraResolution.y);
parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
// This is the standard setting to turn the flash off that all devices should honor.
parameters.set("flash-mode", "off");
camera.setParameters(parameters);
}
private String collectCameraParameters() {
Camera.Parameters parameters = camera.getParameters();
String[] params = parameters.flatten().split(";");
StringBuilder result = new StringBuilder();
String[] params = SEMICOLON.split(parameters.flatten());
StringBuilder result = new StringBuilder(100);
result.append("Default camera parameters:");
for (String param : params) {
result.append("\n ");

View file

@ -22,6 +22,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@ -35,11 +36,13 @@ import java.io.IOException;
public final class CameraTestActivity extends Activity implements SurfaceHolder.Callback {
private static final String TAG = CameraTestActivity.class.getSimpleName();
public static final String GET_CAMERA_PARAMETERS = "GET_CAMERA_PARAMETERS";
private static final String[] EMAIL_ADDRESS = {"zxing-external@google.com"};
private SaveThread mSaveThread = null;
private boolean mGetCameraParameters;
private SaveThread saveThread;
private boolean getCameraParameters;
@Override
public void onCreate(Bundle icicle) {
@ -50,8 +53,8 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
mGetCameraParameters = getIntent().getBooleanExtra(GET_CAMERA_PARAMETERS, false);
if (mGetCameraParameters) {
getCameraParameters = getIntent().getBooleanExtra(GET_CAMERA_PARAMETERS, false);
if (getCameraParameters) {
setContentView(R.layout.camera_parameters);
} else {
setContentView(R.layout.camera_test);
@ -67,9 +70,9 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
@Override
protected void onResume() {
super.onResume();
if (mSaveThread == null && !mGetCameraParameters) {
mSaveThread = new SaveThread(this);
mSaveThread.start();
if (saveThread == null && !getCameraParameters) {
saveThread = new SaveThread(this);
saveThread.start();
}
}
@ -78,19 +81,20 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
super.onPause();
CameraManager.get().stopPreview();
if (mSaveThread != null) {
Message quit = Message.obtain(mSaveThread.mHandler, R.id.quit);
if (saveThread != null) {
Message quit = Message.obtain(saveThread.handler, R.id.quit);
quit.sendToTarget();
try {
mSaveThread.join();
saveThread.join();
} catch (InterruptedException e) {
// continue
}
mSaveThread = null;
saveThread = null;
}
CameraManager.get().closeDriver();
}
public final Handler mHandler = new Handler() {
final Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
@ -109,15 +113,15 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (!mGetCameraParameters) {
if (!getCameraParameters) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
if (event.getRepeatCount() == 0) {
CameraManager.get().requestAutoFocus(mHandler, R.id.auto_focus);
CameraManager.get().requestAutoFocus(handler, R.id.auto_focus);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_SEARCH) {
if (event.getRepeatCount() == 0) {
CameraManager.get().requestPreviewFrame(mSaveThread.mHandler, R.id.save);
CameraManager.get().requestPreviewFrame(saveThread.handler, R.id.save);
}
return true;
}
@ -125,29 +129,29 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
return super.onKeyDown(keyCode, event);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
String parameters = CameraManager.get().openDriver(holder, mGetCameraParameters);
String parameters = CameraManager.get().openDriver(holder, getCameraParameters);
CameraManager.get().startPreview();
if (mGetCameraParameters) {
if (getCameraParameters) {
collectStatsAndSendEmail(parameters);
}
} catch (IOException e) {
// IOException clause added for Android 1.5
throw new RuntimeException(e);
throw new IllegalStateException(e);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
private void collectStatsAndSendEmail(String parameters) {
StringBuilder result = new StringBuilder();
StringBuilder result = new StringBuilder(1000);
result.append("Device info:");
result.append("\n Board: ");
result.append(Build.BOARD);
@ -183,13 +187,20 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
result.append("\n\n");
result.append(parameters);
FileOutputStream stream = null;
try {
File file = new File("/sdcard/CameraParameters.txt");
FileOutputStream stream = new FileOutputStream(file);
stream = new FileOutputStream(new File("/sdcard/CameraParameters.txt"));
stream.write(result.toString().getBytes());
} catch (IOException e) {
Log.e(TAG, "Cannot write parameters file ", e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.w(TAG, e);
}
}
}
Intent intent = new Intent(Intent.ACTION_SEND);

View file

@ -55,11 +55,16 @@ public final class RGBLuminanceSource extends LuminanceSource {
int r = (pixel >> 16) & 0xff;
int g = (pixel >> 8) & 0xff;
int b = pixel & 0xff;
if (r == g && g == b) {
// Image is already greyscale, so pick any channel.
luminances[offset + x] = (byte) r;
} else {
// Calculate luminance cheaply, favoring green.
luminances[offset + x] = (byte) ((r + g + g + b) >> 2);
}
}
}
}
@Override
public byte[] getRow(int y, byte[] row) {

View file

@ -32,9 +32,9 @@ import java.util.Date;
final class SaveThread extends Thread {
private static final String TAG = "SaveThread";
private static final String TAG = SaveThread.class.getSimpleName();
public Handler mHandler;
Handler handler;
private final CameraTestActivity mActivity;
@ -45,7 +45,7 @@ final class SaveThread extends Thread {
@Override
public void run() {
Looper.prepare();
mHandler = new Handler() {
handler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
@ -90,7 +90,7 @@ final class SaveThread extends Thread {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
try {
outStream.close();
Message message = Message.obtain(mActivity.mHandler, R.id.save_succeeded);
Message message = Message.obtain(mActivity.handler, R.id.save_succeeded);
message.sendToTarget();
return;
} catch (IOException e) {
@ -98,7 +98,7 @@ final class SaveThread extends Thread {
}
}
Message message = Message.obtain(mActivity.mHandler, R.id.save_failed);
Message message = Message.obtain(mActivity.handler, R.id.save_failed);
message.sendToTarget();
}

View file

@ -26,21 +26,21 @@ import android.view.View;
public final class ViewfinderView extends View {
private final Paint mPaint;
private final Rect mBox;
private final int mMaskColor;
private final int mFrameColor;
private final Paint paint;
private final Rect box;
private final int maskColor;
private final int frameColor;
// This constructor is used when the class is built from an XML resource.
public ViewfinderView(Context context, AttributeSet attrs) {
super(context, attrs);
// Initialize these once for performance rather than calling them every time in onDraw().
mPaint = new Paint();
mBox = new Rect();
paint = new Paint();
box = new Rect();
Resources resources = getResources();
mMaskColor = resources.getColor(R.color.viewfinder_mask);
mFrameColor = resources.getColor(R.color.viewfinder_frame);
maskColor = resources.getColor(R.color.viewfinder_mask);
frameColor = resources.getColor(R.color.viewfinder_frame);
}
@Override
@ -51,26 +51,26 @@ public final class ViewfinderView extends View {
// Draw the exterior (i.e. outside the framing rect) darkened, in red to distinguish it from
// the regular barcodes app
mPaint.setColor(mMaskColor);
mBox.set(0, 0, width, frame.top);
canvas.drawRect(mBox, mPaint);
mBox.set(0, frame.top, frame.left, frame.bottom + 1);
canvas.drawRect(mBox, mPaint);
mBox.set(frame.right + 1, frame.top, width, frame.bottom + 1);
canvas.drawRect(mBox, mPaint);
mBox.set(0, frame.bottom + 1, width, height);
canvas.drawRect(mBox, mPaint);
paint.setColor(maskColor);
box.set(0, 0, width, frame.top);
canvas.drawRect(box, paint);
box.set(0, frame.top, frame.left, frame.bottom + 1);
canvas.drawRect(box, paint);
box.set(frame.right + 1, frame.top, width, frame.bottom + 1);
canvas.drawRect(box, paint);
box.set(0, frame.bottom + 1, width, height);
canvas.drawRect(box, paint);
// Draw a two pixel solid white border inside the framing rect
mPaint.setColor(mFrameColor);
mBox.set(frame.left, frame.top, frame.right + 1, frame.top + 2);
canvas.drawRect(mBox, mPaint);
mBox.set(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1);
canvas.drawRect(mBox, mPaint);
mBox.set(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1);
canvas.drawRect(mBox, mPaint);
mBox.set(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1);
canvas.drawRect(mBox, mPaint);
paint.setColor(frameColor);
box.set(frame.left, frame.top, frame.right + 1, frame.top + 2);
canvas.drawRect(box, paint);
box.set(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1);
canvas.drawRect(box, paint);
box.set(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1);
canvas.drawRect(box, paint);
box.set(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1);
canvas.drawRect(box, paint);
}
}

View file

@ -59,21 +59,22 @@ public final class ZXingTestActivity extends Activity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, ABOUT_ID, 0, R.string.about_menu)
.setIcon(android.R.drawable.ic_menu_info_details);
menu.add(0, ABOUT_ID, 0, R.string.about_menu).setIcon(android.R.drawable.ic_menu_info_details);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == ABOUT_ID) {
int versionCode = 0;
String versionName = "unknown";
int versionCode;
String versionName;
try {
PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
versionCode = info.versionCode;
versionName = info.versionName;
} catch (PackageManager.NameNotFoundException e) {
versionCode = 0;
versionName = "unknown";
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(
@ -86,7 +87,8 @@ public final class ZXingTestActivity extends Activity {
return super.onOptionsItemSelected(item);
}
public final Button.OnClickListener takeTestPhotos = new Button.OnClickListener() {
private final Button.OnClickListener takeTestPhotos = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setClassName(ZXingTestActivity.this, CameraTestActivity.class.getName());
@ -95,7 +97,8 @@ public final class ZXingTestActivity extends Activity {
}
};
public final Button.OnClickListener getCameraParameters = new Button.OnClickListener() {
private final Button.OnClickListener getCameraParameters = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setClassName(ZXingTestActivity.this, CameraTestActivity.class.getName());
@ -104,7 +107,8 @@ public final class ZXingTestActivity extends Activity {
}
};
public final Button.OnClickListener runBenchmark = new Button.OnClickListener() {
private final Button.OnClickListener runBenchmark = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setClassName(ZXingTestActivity.this, BenchmarkActivity.class.getName());
@ -112,7 +116,8 @@ public final class ZXingTestActivity extends Activity {
}
};
public final Button.OnClickListener scanProduct = new Button.OnClickListener() {
private final Button.OnClickListener scanProduct = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
@ -122,7 +127,8 @@ public final class ZXingTestActivity extends Activity {
}
};
public final Button.OnClickListener scanQRCode = new Button.OnClickListener() {
private final Button.OnClickListener scanQRCode = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
@ -130,14 +136,16 @@ public final class ZXingTestActivity extends Activity {
}
};
public final Button.OnClickListener scanAnything = new Button.OnClickListener() {
private final Button.OnClickListener scanAnything = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
startActivityForResult(intent, 0);
}
};
public final Button.OnClickListener searchBookContents = new Button.OnClickListener() {
private final Button.OnClickListener searchBookContents = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.google.zxing.client.android.SEARCH_BOOK_CONTENTS");
intent.putExtra("ISBN", "9780441014989");
@ -159,31 +167,36 @@ public final class ZXingTestActivity extends Activity {
}
}
public final Button.OnClickListener encodeURL = new Button.OnClickListener() {
private final Button.OnClickListener encodeURL = new Button.OnClickListener() {
@Override
public void onClick(View v) {
encodeBarcode("TEXT_TYPE", "http://www.nytimes.com");
}
};
public final Button.OnClickListener encodeEmail = new Button.OnClickListener() {
private final Button.OnClickListener encodeEmail = new Button.OnClickListener() {
@Override
public void onClick(View v) {
encodeBarcode("EMAIL_TYPE", "foo@example.com");
}
};
public final Button.OnClickListener encodePhone = new Button.OnClickListener() {
private final Button.OnClickListener encodePhone = new Button.OnClickListener() {
@Override
public void onClick(View v) {
encodeBarcode("PHONE_TYPE", "2125551212");
}
};
public final Button.OnClickListener encodeSMS = new Button.OnClickListener() {
private final Button.OnClickListener encodeSMS = new Button.OnClickListener() {
@Override
public void onClick(View v) {
encodeBarcode("SMS_TYPE", "2125551212");
}
};
public final Button.OnClickListener encodeContact = new Button.OnClickListener() {
private final Button.OnClickListener encodeContact = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putString(Contacts.Intents.Insert.NAME, "Jenny");
@ -194,7 +207,8 @@ public final class ZXingTestActivity extends Activity {
}
};
public final Button.OnClickListener encodeLocation = new Button.OnClickListener() {
private final Button.OnClickListener encodeLocation = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putFloat("LAT", 40.829208f);
@ -203,7 +217,8 @@ public final class ZXingTestActivity extends Activity {
}
};
public final Button.OnClickListener encodeHiddenData = new Button.OnClickListener() {
private final Button.OnClickListener encodeHiddenData = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
@ -213,13 +228,15 @@ public final class ZXingTestActivity extends Activity {
}
};
public final Button.OnClickListener encodeBadData = new Button.OnClickListener() {
private final Button.OnClickListener encodeBadData = new Button.OnClickListener() {
@Override
public void onClick(View v) {
encodeBarcode(null, "bar");
}
};
public final Button.OnClickListener shareViaBarcode = new Button.OnClickListener() {
private final Button.OnClickListener shareViaBarcode = new Button.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent("com.google.zxing.client.android.SHARE"));
}

View file

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 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.
-->
<project name="bug" default="build">
<property file="../build.properties"/>
<target name="init">
<tstamp/>
<fail message="Please build 'core' first">
<condition>
<not>
<available file="../core/core.jar" type="file"/>
</not>
</condition>
</fail>
<fail message="Please install BUG .jar files in lib/ first">
<condition>
<not>
<available file="lib/com.buglabs.common_1.0.0.jar" type="file"/>
<!-- Actually we need even more, just checking for one -->
</not>
</condition>
</fail>
</target>
<target name="build" depends="init">
<mkdir dir="build"/>
<javac srcdir="src"
destdir="build"
source="1.5"
target="1.5"
optimize="true"
debug="true"
deprecation="true">
<classpath>
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
<pathelement location="../core/core.jar"/>
</classpath>
</javac>
<jar jarfile="bug.jar" basedir="build">
<manifest>
<attribute name="Bundle-Name" value="BugBarcode"/>
<attribute name="Bundle-Vendor" value="ZXing Project"/>
<attribute name="Bundle-SymbolicName" value="BugBarcode"/>
<attribute name="Bundle-Version" value="${version}"/>
<attribute name="Bundle-Activator" value="com.google.zxing.client.bug.Activator"/>
<attribute name="Import-Package" value="com.buglabs.application,com.buglabs.device,com.buglabs.bug.module.camera.pub,com.buglabs.bug.module.lcd.pub,com.buglabs.util,com.google.zxing,com.google.zxing.common,org.osgi.framework,org.osgi.util.tracker"/>
<attribute name="Bug-Bundle-Type" value="Application"/>
</manifest>
</jar>
</target>
<target name="clean">
<delete dir="build"/>
<delete file="bug.jar"/>
</target>
</project>

View file

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

Binary file not shown.

View file

@ -1,94 +0,0 @@
/*
* Copyright 2009 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.bug;
import com.google.zxing.LuminanceSource;
import com.google.zxing.ReaderException;
import java.awt.Image;
import java.awt.image.PixelGrabber;
/**
* An implementation based on AWT's Image representation. This can be used on CDC devices
* or other devices that do not have access to the Mobile Information Device Profile
* and thus do not have access to javax.microedition.lcdui.Image.
*
* @author dswitkin@google.com (Daniel Switkin)
* @author David Albert
* @author Sean Owen
*/
public final class AWTImageLuminanceSource extends LuminanceSource {
private final int[] pixels;
public AWTImageLuminanceSource(Image image) throws ReaderException {
super(image.getWidth(null), image.getHeight(null));
int width = getWidth();
int height = getHeight();
pixels = new int[width * height];
// Seems best in this situation to grab all pixels upfront. Grabbing any individual pixel
// entails creating a relatively expensive object and calling through several methods.
PixelGrabber grabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width);
try {
grabber.grabPixels();
} catch (InterruptedException ie) {
throw ReaderException.getInstance();
}
}
public byte[] getRow(int y, byte[] row) {
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException("Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
int offset = y * width;
for (int x = 0; x < width; x++) {
int pixel = pixels[offset + x];
int luminance = (((pixel & 0x00FF0000) >> 16) +
((pixel & 0x0000FF00) >> 7) +
(pixel & 0x000000FF )) >> 2;
row[x] = (byte) luminance;
}
return row;
}
public byte[] getMatrix() {
int width = getWidth();
int height = getHeight();
int area = width * height;
byte[] matrix = new byte[area];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
int pixel = pixels[offset + x];
int luminance = (((pixel & 0x00FF0000) >> 16) +
((pixel & 0x0000FF00) >> 7) +
(pixel & 0x000000FF )) >> 2;
matrix[x] = (byte) luminance;
}
}
return matrix;
}
}

View file

@ -1,49 +0,0 @@
/*
* Copyright 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.bug;
import com.buglabs.util.ServiceFilterGenerator;
import com.google.zxing.client.bug.servicetracker.BugBarcodeServiceTracker;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.util.tracker.ServiceTracker;
/**
* BundleActivator for BugBarcode.
*
* @author David Albert
*/
public final class Activator implements BundleActivator {
private BugBarcodeServiceTracker barcodeServiceTracker;
private ServiceTracker serviceTracker;
public void start(BundleContext context) throws InvalidSyntaxException {
barcodeServiceTracker = new BugBarcodeServiceTracker(context);
Filter filter =
context.createFilter(ServiceFilterGenerator.generateServiceFilter(barcodeServiceTracker.getServices()));
serviceTracker = new ServiceTracker(context, filter, barcodeServiceTracker);
serviceTracker.open();
}
public void stop(BundleContext context) {
barcodeServiceTracker.stop();
serviceTracker.close();
}
}

View file

@ -1,73 +0,0 @@
/*
* Copyright 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.bug;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
/**
* @author John Connolly
*/
public final class ImageCanvas extends Canvas {
private Image image;
public ImageCanvas(Image image) {
this.image = image;
}
@Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
@Override
public void update(Graphics g) {
paint(g);
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
public Dimension getPreferredSize() {
int width;
do {
width = image.getWidth(this);
} while (width < 0);
int height;
do {
height = image.getHeight(this);
} while (height < 0);
return new Dimension(width, height);
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
}

View file

@ -1,122 +0,0 @@
/*
* Copyright 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.bug.app;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Reader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.bug.AWTImageLuminanceSource;
import com.google.zxing.client.bug.ImageCanvas;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.buglabs.bug.module.camera.pub.ICameraDevice;
import com.buglabs.bug.module.camera.pub.ICameraModuleControl;
import com.buglabs.device.ButtonEvent;
import com.buglabs.device.IButtonEventListener;
import com.buglabs.device.IButtonEventProvider;
import java.awt.*;
import java.awt.image.ImageObserver;
import java.io.IOException;
/**
* @author David Albert
*/
public final class BugBarcodeApp implements IButtonEventListener, ImageObserver {
private final ICameraDevice camera;
private final ICameraModuleControl cameraControl;
private final Frame frame;
private Image image;
private ImageCanvas imageCanvas;
private Label barcodeLabel;
private boolean pictureTaken;
private final Reader reader;
public BugBarcodeApp(Frame frame,
ICameraDevice camera,
ICameraModuleControl cameraControl,
IButtonEventProvider buttonProvider) {
this.frame = frame;
this.camera = camera;
this.reader = new MultiFormatReader();
this.cameraControl = cameraControl;
pictureTaken = false;
buttonProvider.addListener(this);
createUI();
}
private void createUI() {
frame.setTitle("BugBarcode");
frame.setBackground(Color.WHITE);
frame.setLayout(new BorderLayout());
barcodeLabel = new Label("Take a picture of a barcode!", Label.CENTER);
frame.add(barcodeLabel, BorderLayout.SOUTH);
imageCanvas = new ImageCanvas(null);
frame.setVisible(true);
}
private void shoot() throws IOException {
// get image from camera for use with physical bug
cameraControl.setLEDFlash(true);
image = Toolkit.getDefaultToolkit().createImage(camera.getImage()).getScaledInstance(400, 300,
Image.SCALE_FAST);
cameraControl.setLEDFlash(false);
if (Toolkit.getDefaultToolkit().prepareImage(image, -1, -1, this)) {
drawAndScan();
}
}
private void drawAndScan() {
imageCanvas.setImage(image.getScaledInstance(216, 150, Image.SCALE_FAST));
if (!pictureTaken) {
frame.add(imageCanvas, BorderLayout.CENTER);
pictureTaken = true;
frame.setVisible(true);
}
imageCanvas.repaint();
try {
LuminanceSource source = new AWTImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
Result result = reader.decode(bitmap);
barcodeLabel.setText(result.getText());
} catch (ReaderException re) {
barcodeLabel.setText("I can't find a barcode here");
}
}
public void buttonEvent(ButtonEvent event) {
if (event.getButton() == ButtonEvent.BUTTON_HOTKEY_1 && event.getAction() == 0) {
try {
shoot();
} catch (IOException ioe) {
// continue
}
}
}
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
if ((infoflags & ALLBITS) != 0) {
drawAndScan();
return false;
}
return true;
}
}

View file

@ -1,79 +0,0 @@
/*
* Copyright 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.bug.servicetracker;
import com.buglabs.application.AbstractServiceTracker;
import com.buglabs.bug.module.camera.pub.ICameraDevice;
import com.buglabs.bug.module.camera.pub.ICameraModuleControl;
import com.buglabs.bug.module.lcd.pub.IModuleDisplay;
import com.buglabs.device.IButtonEventProvider;
import com.google.zxing.client.bug.app.BugBarcodeApp;
import org.osgi.framework.BundleContext;
import java.awt.Frame;
import java.util.Collection;
/**
* Service tracker for the BugApp Bundle
*
* @author David Albert
*/
public final class BugBarcodeServiceTracker extends AbstractServiceTracker {
private IButtonEventProvider buttonEventProvider;
private Frame frame;
private BugBarcodeApp app;
public BugBarcodeServiceTracker(BundleContext context) {
super(context);
}
@Override
public void doStart() {
IModuleDisplay display = (IModuleDisplay) getService(IModuleDisplay.class);
ICameraDevice camera = (ICameraDevice) getService(ICameraDevice.class);
ICameraModuleControl cameraControl = (ICameraModuleControl) getService(ICameraModuleControl.class);
buttonEventProvider = (IButtonEventProvider) getService(IButtonEventProvider.class);
frame = display.getFrame();
app = new BugBarcodeApp(frame, camera, cameraControl, buttonEventProvider);
}
/**
* Called when a service that this application depends is unregistered.
*/
@Override
public void doStop() {
buttonEventProvider.removeListener(app);
frame.dispose();
}
/**
* Allows the user to set the service dependencies by
* adding them to services list returned by getServices().
* i.e.nl getServices().add(MyService.class.getName());
*/
@Override
public void initServices() {
Collection<String> appServices = (Collection<String>) getServices();
appServices.add("com.buglabs.bug.module.camera.pub.ICameraDevice");
appServices.add("com.buglabs.bug.module.lcd.pub.IModuleDisplay");
appServices.add(IButtonEventProvider.class.getName());
appServices.add(ICameraModuleControl.class.getName());
}
}

View file

@ -1,31 +1,8 @@
version=1.6
version=2.0
# Set to the location where ProGuard's proguard.jar file can be found.
#proguard-jar=/usr/local/android-sdk/tools/proguard/lib/proguard.jar
# If you are building the J2ME client:
#
# Set this to a location where Sun's Java ME SDK, version 3.0 or later, has been installed.
# You can use version 2.5.2 or perhaps earlier, but will need to modify javame/build.xml to
# use different .jar paths.
# Uncomment or set appropriately:
#WTK-home=/Applications/Java_ME_SDK_3.0.app/Contents/Resources
# Set this to the location where you have installed RIM's BlackBerry JDE in order to
# create the 'rim' client. There is no Mac or Linux version, but, these platforms can still
# build by obtaining a copy of net_rim_api.jar and rapc.jar from a Windows installation,
# and creating a fake mini installation home somewhere with the following files:
# [your home]/
# bin/
# rapc.jar
# lib/
# net_rim_api.jar
# Uncomment and set appropriately
#BB-JDK-home=C:\\Program Files\\Research In Motion\\Blackberry JDE 4.3.0
#BB-JDK-home=/usr/local/bb-home
# Set this to the location where you installed the Android SDK.
#android-home=C:\\Program Files\\android-sdk-windows
#android-home=/usr/local/android-sdk

View file

@ -26,12 +26,6 @@
<ant dir="android" target="compile"/>
<ant dir="androidtest" target="compile"/>
<ant dir="android-integration" target="build"/>
<!--<ant dir="zxingorg" target="build"/>-->
</target>
<target name="buildwithoutj2me">
<ant dir="core" target="build"/>
<ant dir="javase" target="build"/>
</target>
<target name="clean">
@ -40,7 +34,6 @@
<ant dir="android" target="clean"/>
<ant dir="androidtest" target="clean"/>
<ant dir="android-integration" target="clean"/>
<ant dir="zxingorg" target="clean"/>
<delete dir="docs/javadoc"/>
</target>
@ -56,7 +49,6 @@
<exclude name="**/*.iml"/>
<include name="AUTHORS"/>
<include name="COPYING"/>
<include name="README"/>
<include name="CHANGES"/>
<include name="build.xml"/>
<include name="build.properties"/>
@ -64,18 +56,14 @@
<include name="android/**"/>
<include name="android-integration/**"/>
<include name="androidtest/**"/>
<include name="bug/**"/>
<exclude name="bug/lib/com.buglabs*"/> <!-- Cannot distributed GPLed libraries -->
<include name="core/**"/>
<include name="cpp/**"/>
<include name="iphone/**"/>
<include name="javame/**"/>
<include name="javase/**"/>
<include name="rim/**"/>
<include name="docs/**"/>
<include name="zxing.appspot.com/**"/>
<include name="zxingorg/**"/>
<exclude name="zxingorg/secrets.properties"/>
</zipfileset>
</zip>
</target>
@ -94,18 +82,7 @@
<pathelement location="zxingorg/src"/>
</sourcepath>
<classpath>
<!-- These are used with WTK 2.5.x -->
<!--
<pathelement location="${WTK-home}/lib/cldcapi11.jar"/>
<pathelement location="${WTK-home}/lib/midpapi20.jar"/>
<pathelement location="${WTK-home}/lib/mmapi.jar"/>
<pathelement location="${WTK-home}/lib/jsr234.jar"/>
-->
<pathelement location="${WTK-home}/lib/cldc_1.1.jar"/>
<pathelement location="${WTK-home}/lib/midp_2.0.jar"/>
<pathelement location="${WTK-home}/lib/jsr135_1.2.jar"/>
<pathelement location="${WTK-home}/lib/jsr234_1.0.jar"/>
<pathelement location="${android-home}/platforms/android-3/android.jar"/>
<pathelement location="${android-home}/platforms/android-10/android.jar"/>
<pathelement location="${tomcat-home}/lib/servlet-api.jar"/>
<fileset dir="zxingorg/web/WEB-INF/lib">
<include name="*.jar"/>

View file

@ -28,8 +28,8 @@
<mkdir dir="build"/>
<javac srcdir="src"
destdir="build"
source="1.2"
target="1.2"
source="6"
target="6"
optimize="true"
debug="${generate-debug}"
deprecation="true"
@ -97,13 +97,6 @@
</target>
<target name="build-test" depends="init,build">
<fail message="Please build 'javase' first">
<condition>
<not>
<available file="../javase/javase.jar" type="file"/>
</not>
</condition>
</fail>
<mkdir dir="build-test"/>
<javac srcdir="test/src"
destdir="build-test"
@ -112,7 +105,6 @@
includeantruntime="false">
<classpath>
<pathelement location="core.jar"/>
<pathelement location="../javase/javase.jar"/>
<pathelement location="lib/junit-4.8.2.jar"/>
</classpath>
</javac>
@ -147,7 +139,6 @@
<classpath>
<pathelement location="core.jar"/>
<pathelement location="build-test"/>
<pathelement location="../javase/javase.jar"/>
<pathelement location="lib/junit-4.8.2.jar"/>
</classpath>
<assertions>
@ -169,7 +160,6 @@
<classpath>
<pathelement location="core.jar"/>
<pathelement location="build-test"/>
<pathelement location="../javase/javase.jar"/>
<pathelement location="lib/junit-4.8.2.jar"/>
</classpath>
<assertions>

View file

@ -16,94 +16,62 @@
package com.google.zxing;
import java.util.Hashtable;
/**
* Enumerates barcode formats known to this package. Please keep alphabetized.
*
* @author Sean Owen
*/
public final class BarcodeFormat {
// No, we can't use an enum here. J2ME doesn't support it.
private static final Hashtable VALUES = new Hashtable();
public enum BarcodeFormat {
/** Aztec 2D barcode format. */
public static final BarcodeFormat AZTEC = new BarcodeFormat("AZTEC");
AZTEC,
/** CODABAR 1D format. */
public static final BarcodeFormat CODABAR = new BarcodeFormat("CODABAR");
CODABAR,
/** Code 39 1D format. */
public static final BarcodeFormat CODE_39 = new BarcodeFormat("CODE_39");
CODE_39,
/** Code 93 1D format. */
public static final BarcodeFormat CODE_93 = new BarcodeFormat("CODE_93");
CODE_93,
/** Code 128 1D format. */
public static final BarcodeFormat CODE_128 = new BarcodeFormat("CODE_128");
CODE_128,
/** Data Matrix 2D barcode format. */
public static final BarcodeFormat DATA_MATRIX = new BarcodeFormat("DATA_MATRIX");
DATA_MATRIX,
/** EAN-8 1D format. */
public static final BarcodeFormat EAN_8 = new BarcodeFormat("EAN_8");
EAN_8,
/** EAN-13 1D format. */
public static final BarcodeFormat EAN_13 = new BarcodeFormat("EAN_13");
EAN_13,
/** ITF (Interleaved Two of Five) 1D format. */
public static final BarcodeFormat ITF = new BarcodeFormat("ITF");
ITF,
/** MaxiCode 2D barcode format. */
public static final BarcodeFormat MAXICODE = new BarcodeFormat("MAXICODE");
MAXICODE,
/** PDF417 format. */
public static final BarcodeFormat PDF_417 = new BarcodeFormat("PDF_417");
PDF_417,
/** QR Code 2D barcode format. */
public static final BarcodeFormat QR_CODE = new BarcodeFormat("QR_CODE");
QR_CODE,
/** RSS 14 */
public static final BarcodeFormat RSS_14 = new BarcodeFormat("RSS_14");
RSS_14,
/** RSS EXPANDED */
public static final BarcodeFormat RSS_EXPANDED = new BarcodeFormat("RSS_EXPANDED");
RSS_EXPANDED,
/** UPC-A 1D format. */
public static final BarcodeFormat UPC_A = new BarcodeFormat("UPC_A");
UPC_A,
/** UPC-E 1D format. */
public static final BarcodeFormat UPC_E = new BarcodeFormat("UPC_E");
UPC_E,
/** UPC/EAN extension format. Not a stand-alone format. */
public static final BarcodeFormat UPC_EAN_EXTENSION = new BarcodeFormat("UPC_EAN_EXTENSION");
private final String name;
private BarcodeFormat(String name) {
this.name = name;
VALUES.put(name, this);
}
public String getName() {
return name;
}
public String toString() {
return name;
}
public static BarcodeFormat valueOf(String name) {
if (name == null || name.length() == 0) {
throw new IllegalArgumentException();
}
BarcodeFormat format = (BarcodeFormat) VALUES.get(name);
if (format == null) {
throw new IllegalArgumentException();
}
return format;
}
UPC_EAN_EXTENSION
}

View file

@ -74,4 +74,12 @@ public abstract class Binarizer {
*/
public abstract Binarizer createBinarizer(LuminanceSource source);
public int getWidth() {
return source.getWidth();
}
public int getHeight() {
return source.getHeight();
}
}

View file

@ -35,21 +35,20 @@ public final class BinaryBitmap {
throw new IllegalArgumentException("Binarizer must be non-null.");
}
this.binarizer = binarizer;
matrix = null;
}
/**
* @return The width of the bitmap.
*/
public int getWidth() {
return binarizer.getLuminanceSource().getWidth();
return binarizer.getWidth();
}
/**
* @return The height of the bitmap.
*/
public int getHeight() {
return binarizer.getLuminanceSource().getHeight();
return binarizer.getHeight();
}
/**

View file

@ -23,57 +23,52 @@ package com.google.zxing;
*
* @author Sean Owen
* @author dswitkin@google.com (Daniel Switkin)
* @see Reader#decode(BinaryBitmap,java.util.Hashtable)
* @see Reader#decode(BinaryBitmap,java.util.Map)
*/
public final class DecodeHintType {
// No, we can't use an enum here. J2ME doesn't support it.
public enum DecodeHintType {
/**
* Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
*/
public static final DecodeHintType OTHER = new DecodeHintType();
OTHER,
/**
* Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
public static final DecodeHintType PURE_BARCODE = new DecodeHintType();
PURE_BARCODE,
/**
* Image is known to be of one of a few possible formats.
* Maps to a {@link java.util.Vector} of {@link BarcodeFormat}s.
* Maps to a {@link java.util.List} of {@link BarcodeFormat}s.
*/
public static final DecodeHintType POSSIBLE_FORMATS = new DecodeHintType();
POSSIBLE_FORMATS,
/**
* Spend more time to try to find a barcode; optimize for accuracy, not speed.
* Doesn't matter what it maps to; use {@link Boolean#TRUE}.
*/
public static final DecodeHintType TRY_HARDER = new DecodeHintType();
TRY_HARDER,
/**
* Specifies what character encoding to use when decoding, where applicable (type String)
*/
public static final DecodeHintType CHARACTER_SET = new DecodeHintType();
CHARACTER_SET,
/**
* Allowed lengths of encoded data -- reject anything else. Maps to an int[].
*/
public static final DecodeHintType ALLOWED_LENGTHS = new DecodeHintType();
ALLOWED_LENGTHS,
/**
* Assume Code 39 codes employ a check digit. Maps to {@link Boolean}.
*/
public static final DecodeHintType ASSUME_CODE_39_CHECK_DIGIT = new DecodeHintType();
ASSUME_CODE_39_CHECK_DIGIT,
/**
* The caller needs to be notified via callback when a possible {@link ResultPoint}
* is found. Maps to a {@link ResultPointCallback}.
*/
public static final DecodeHintType NEED_RESULT_POINT_CALLBACK = new DecodeHintType();
private DecodeHintType() {
}
NEED_RESULT_POINT_CALLBACK,
}

View file

@ -21,19 +21,16 @@ package com.google.zxing;
*
* @author dswitkin@google.com (Daniel Switkin)
*/
public final class EncodeHintType {
public enum EncodeHintType {
/**
* Specifies what degree of error correction to use, for example in QR Codes (type Integer).
*/
public static final EncodeHintType ERROR_CORRECTION = new EncodeHintType();
ERROR_CORRECTION,
/**
* Specifies what character encoding to use where applicable (type String)
*/
public static final EncodeHintType CHARACTER_SET = new EncodeHintType();
private EncodeHintType() {
}
CHARACTER_SET,
}

View file

@ -91,7 +91,7 @@ public abstract class LuminanceSource {
* @return A cropped version of this object.
*/
public LuminanceSource crop(int left, int top, int width, int height) {
throw new RuntimeException("This luminance source does not support cropping.");
throw new UnsupportedOperationException("This luminance source does not support cropping.");
}
/**
@ -107,12 +107,13 @@ public abstract class LuminanceSource {
* @return A rotated version of this object.
*/
public LuminanceSource rotateCounterClockwise() {
throw new RuntimeException("This luminance source does not support rotation.");
throw new UnsupportedOperationException("This luminance source does not support rotation.");
}
@Override
public String toString() {
byte[] row = new byte[width];
StringBuffer result = new StringBuffer(height * (width + 1));
StringBuilder result = new StringBuilder(height * (width + 1));
for (int y = 0; y < height; y++) {
row = getRow(y, row);
for (int x = 0; x < width; x++) {

View file

@ -18,13 +18,15 @@ package com.google.zxing;
import com.google.zxing.aztec.AztecReader;
import com.google.zxing.datamatrix.DataMatrixReader;
import com.google.zxing.maxicode.MaxiCodeReader;
import com.google.zxing.oned.MultiFormatOneDReader;
import com.google.zxing.pdf417.PDF417Reader;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.maxicode.MaxiCodeReader;
import java.util.Hashtable;
import java.util.Vector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* MultiFormatReader is a convenience class and the main entry point into the library for most uses.
@ -36,8 +38,8 @@ import java.util.Vector;
*/
public final class MultiFormatReader implements Reader {
private Hashtable hints;
private final Vector readers = new Vector();
private Map<DecodeHintType,?> hints;
private final List<Reader> readers = new ArrayList<Reader>();
/**
* This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it
@ -48,6 +50,7 @@ public final class MultiFormatReader implements Reader {
* @return The contents of the image
* @throws NotFoundException Any errors which occurred
*/
@Override
public Result decode(BinaryBitmap image) throws NotFoundException {
setHints(null);
return decodeInternal(image);
@ -61,7 +64,8 @@ public final class MultiFormatReader implements Reader {
* @return The contents of the image
* @throws NotFoundException Any errors which occurred
*/
public Result decode(BinaryBitmap image, Hashtable hints) throws NotFoundException {
@Override
public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException {
setHints(hints);
return decodeInternal(image);
}
@ -89,11 +93,12 @@ public final class MultiFormatReader implements Reader {
*
* @param hints The set of hints to use for subsequent calls to decode(image)
*/
public void setHints(Hashtable hints) {
public void setHints(Map<DecodeHintType,?> hints) {
this.hints = hints;
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
Vector formats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
Collection<BarcodeFormat> formats =
hints == null ? null : (Collection<BarcodeFormat>) hints.get(DecodeHintType.POSSIBLE_FORMATS);
readers.clear();
if (formats != null) {
boolean addOneDReader =
@ -110,64 +115,60 @@ public final class MultiFormatReader implements Reader {
formats.contains(BarcodeFormat.RSS_EXPANDED);
// Put 1D readers upfront in "normal" mode
if (addOneDReader && !tryHarder) {
readers.addElement(new MultiFormatOneDReader(hints));
readers.add(new MultiFormatOneDReader(hints));
}
if (formats.contains(BarcodeFormat.QR_CODE)) {
readers.addElement(new QRCodeReader());
readers.add(new QRCodeReader());
}
if (formats.contains(BarcodeFormat.DATA_MATRIX)) {
readers.addElement(new DataMatrixReader());
readers.add(new DataMatrixReader());
}
if (formats.contains(BarcodeFormat.AZTEC)) {
readers.addElement(new AztecReader());
readers.add(new AztecReader());
}
if (formats.contains(BarcodeFormat.PDF_417)) {
readers.addElement(new PDF417Reader());
readers.add(new PDF417Reader());
}
if (formats.contains(BarcodeFormat.MAXICODE)) {
readers.addElement(new MaxiCodeReader());
readers.add(new MaxiCodeReader());
}
// At end in "try harder" mode
if (addOneDReader && tryHarder) {
readers.addElement(new MultiFormatOneDReader(hints));
readers.add(new MultiFormatOneDReader(hints));
}
}
if (readers.isEmpty()) {
if (!tryHarder) {
readers.addElement(new MultiFormatOneDReader(hints));
readers.add(new MultiFormatOneDReader(hints));
}
readers.addElement(new QRCodeReader());
readers.addElement(new DataMatrixReader());
readers.addElement(new AztecReader());
readers.addElement(new PDF417Reader());
readers.addElement(new MaxiCodeReader());
readers.add(new QRCodeReader());
readers.add(new DataMatrixReader());
readers.add(new AztecReader());
readers.add(new PDF417Reader());
readers.add(new MaxiCodeReader());
if (tryHarder) {
readers.addElement(new MultiFormatOneDReader(hints));
readers.add(new MultiFormatOneDReader(hints));
}
}
}
@Override
public void reset() {
int size = readers.size();
for (int i = 0; i < size; i++) {
Reader reader = (Reader) readers.elementAt(i);
for (Reader reader : readers) {
reader.reset();
}
}
private Result decodeInternal(BinaryBitmap image) throws NotFoundException {
int size = readers.size();
for (int i = 0; i < size; i++) {
Reader reader = (Reader) readers.elementAt(i);
for (Reader reader : readers) {
try {
return reader.decode(image, hints);
} catch (ReaderException re) {
// continue
}
}
throw NotFoundException.getNotFoundInstance();
}

View file

@ -27,7 +27,7 @@ import com.google.zxing.oned.UPCAWriter;
import com.google.zxing.pdf417.encoder.PDF417Writer;
import com.google.zxing.qrcode.QRCodeWriter;
import java.util.Hashtable;
import java.util.Map;
/**
* This is a factory class which finds the appropriate Writer subclass for the BarcodeFormat
@ -37,35 +37,50 @@ import java.util.Hashtable;
*/
public final class MultiFormatWriter implements Writer {
public BitMatrix encode(String contents, BarcodeFormat format, int width,
@Override
public BitMatrix encode(String contents,
BarcodeFormat format,
int width,
int height) throws WriterException {
return encode(contents, format, width, height, null);
}
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height,
Hashtable hints) throws WriterException {
@Override
public BitMatrix encode(String contents,
BarcodeFormat format,
int width, int height,
Map<EncodeHintType,?> hints) throws WriterException {
Writer writer;
if (format == BarcodeFormat.EAN_8) {
switch (format) {
case EAN_8:
writer = new EAN8Writer();
} else if (format == BarcodeFormat.EAN_13) {
break;
case EAN_13:
writer = new EAN13Writer();
} else if (format == BarcodeFormat.UPC_A) {
break;
case UPC_A:
writer = new UPCAWriter();
} else if (format == BarcodeFormat.QR_CODE) {
break;
case QR_CODE:
writer = new QRCodeWriter();
} else if (format == BarcodeFormat.CODE_39) {
break;
case CODE_39:
writer = new Code39Writer();
} else if (format == BarcodeFormat.CODE_128) {
break;
case CODE_128:
writer = new Code128Writer();
} else if (format == BarcodeFormat.ITF) {
break;
case ITF:
writer = new ITFWriter();
} else if (format == BarcodeFormat.PDF_417) {
break;
case PDF_417:
writer = new PDF417Writer();
} else if (format == BarcodeFormat.CODABAR) {
break;
case CODABAR:
writer = new CodaBarWriter();
} else {
break;
default:
throw new IllegalArgumentException("No encoder available for format " + format);
}
return writer.encode(contents, format, width, height, hints);

View file

@ -16,7 +16,7 @@
package com.google.zxing;
import java.util.Hashtable;
import java.util.Map;
/**
* Implementations of this interface can decode an image of a barcode in some format into
@ -46,14 +46,15 @@ public interface Reader {
* hints, each possibly associated to some data, which may help the implementation decode.
*
* @param image image of barcode to decode
* @param hints passed as a {@link java.util.Hashtable} from {@link com.google.zxing.DecodeHintType}
* @param hints passed as a {@link java.util.Map} from {@link com.google.zxing.DecodeHintType}
* to arbitrary data. The
* meaning of the data depends upon the hint type. The implementation may or may not do
* anything with these hints.
* @return String which the barcode encodes
* @throws NotFoundException if the barcode cannot be located or decoded for any reason
*/
Result decode(BinaryBitmap image, Hashtable hints) throws NotFoundException, ChecksumException, FormatException;
Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)
throws NotFoundException, ChecksumException, FormatException;
/**
* Resets any internal state the implementation has after a decode, to prepare it

View file

@ -25,72 +25,14 @@ package com.google.zxing;
*/
public abstract class ReaderException extends Exception {
// TODO: Currently we throw up to 400 ReaderExceptions while scanning a single 240x240 image before
// rejecting it. This involves a lot of overhead and memory allocation, and affects both performance
// and latency on continuous scan clients. In the future, we should change all the decoders not to
// throw exceptions for routine events, like not finding a barcode on a given row. Instead, we
// should return error codes back to the callers, and simply delete this class. In the mean time, I
// have altered this class to be as lightweight as possible, by ignoring the exception string, and
// by disabling the generation of stack traces, which is especially time consuming. These are just
// temporary measures, pending the big cleanup.
//private static final ReaderException instance = new ReaderException();
// EXCEPTION TRACKING SUPPORT
// Identifies who is throwing exceptions and how often. To use:
//
// 1. Uncomment these lines and the code below which uses them.
// 2. Uncomment the two corresponding lines in j2se/CommandLineRunner.decode()
// 3. Change core to build as Java 1.5 temporarily
// private static int exceptionCount = 0;
// private static Map<String,Integer> throwers = new HashMap<String,Integer>(32);
ReaderException() {
// do nothing
}
//public static ReaderException getInstance() {
// Exception e = new Exception();
// // Take the stack frame before this one.
// StackTraceElement stack = e.getStackTrace()[1];
// String key = stack.getClassName() + "." + stack.getMethodName() + "(), line " +
// stack.getLineNumber();
// if (throwers.containsKey(key)) {
// Integer value = throwers.get(key);
// value++;
// throwers.put(key, value);
// } else {
// throwers.put(key, 1);
// }
// exceptionCount++;
//return instance;
//}
// public static int getExceptionCountAndReset() {
// int temp = exceptionCount;
// exceptionCount = 0;
// return temp;
// }
//
// public static String getThrowersAndReset() {
// StringBuilder builder = new StringBuilder(1024);
// Object[] keys = throwers.keySet().toArray();
// for (int x = 0; x < keys.length; x++) {
// String key = (String) keys[x];
// Integer value = throwers.get(key);
// builder.append(key);
// builder.append(": ");
// builder.append(value);
// builder.append("\n");
// }
// throwers.clear();
// return builder.toString();
// }
// Prevent stack traces from being taken
// srowen says: huh, my IDE is saying this is not an override. native methods can't be overridden?
// This, at least, does not hurt. Because we use a singleton pattern here, it doesn't matter anyhow.
@Override
public final Throwable fillInStackTrace() {
return null;
}

View file

@ -16,8 +16,8 @@
package com.google.zxing;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.EnumMap;
import java.util.Map;
/**
* <p>Encapsulates the result of decoding a barcode within an image.</p>
@ -30,7 +30,7 @@ public final class Result {
private final byte[] rawBytes;
private ResultPoint[] resultPoints;
private final BarcodeFormat format;
private Hashtable resultMetadata;
private Map<ResultMetadataType,Object> resultMetadata;
private final long timestamp;
public Result(String text,
@ -61,7 +61,7 @@ public final class Result {
}
/**
* @return raw bytes encoded by the barcode, if applicable, otherwise <code>null</code>
* @return raw bytes encoded by the barcode, if applicable, otherwise {@code null}
*/
public byte[] getRawBytes() {
return rawBytes;
@ -84,44 +84,39 @@ public final class Result {
}
/**
* @return {@link Hashtable} mapping {@link ResultMetadataType} keys to values. May be
* <code>null</code>. This contains optional metadata about what was detected about the barcode,
* @return {@link Map} mapping {@link ResultMetadataType} keys to values. May be
* {@code null}. This contains optional metadata about what was detected about the barcode,
* like orientation.
*/
public Hashtable getResultMetadata() {
public Map<ResultMetadataType,Object> getResultMetadata() {
return resultMetadata;
}
public void putMetadata(ResultMetadataType type, Object value) {
if (resultMetadata == null) {
resultMetadata = new Hashtable(3);
resultMetadata = new EnumMap<ResultMetadataType,Object>(ResultMetadataType.class);
}
resultMetadata.put(type, value);
}
public void putAllMetadata(Hashtable metadata) {
public void putAllMetadata(Map<ResultMetadataType,Object> metadata) {
if (metadata != null) {
if (resultMetadata == null) {
resultMetadata = metadata;
} else {
Enumeration e = metadata.keys();
while (e.hasMoreElements()) {
ResultMetadataType key = (ResultMetadataType) e.nextElement();
Object value = metadata.get(key);
resultMetadata.put(key, value);
}
resultMetadata.putAll(metadata);
}
}
}
public void addResultPoints(ResultPoint[] newPoints) {
ResultPoint[] oldResultPoints = resultPoints;
if (oldResultPoints == null) {
ResultPoint[] oldPoints = resultPoints;
if (oldPoints == null) {
resultPoints = newPoints;
} else if (newPoints != null && newPoints.length > 0) {
ResultPoint[] allPoints = new ResultPoint[oldResultPoints.length + newPoints.length];
System.arraycopy(oldResultPoints, 0, allPoints, 0, oldResultPoints.length);
System.arraycopy(newPoints, 0, allPoints, oldResultPoints.length, newPoints.length);
ResultPoint[] allPoints = new ResultPoint[oldPoints.length + newPoints.length];
System.arraycopy(oldPoints, 0, allPoints, 0, oldPoints.length);
System.arraycopy(newPoints, 0, allPoints, oldPoints.length, newPoints.length);
resultPoints = allPoints;
}
}
@ -130,6 +125,7 @@ public final class Result {
return timestamp;
}
@Override
public String toString() {
return text;
}

View file

@ -16,26 +16,18 @@
package com.google.zxing;
import java.util.Hashtable;
/**
* Represents some type of metadata about the result of the decoding that the decoder
* wishes to communicate back to the caller.
*
* @author Sean Owen
*/
public final class ResultMetadataType {
// No, we can't use an enum here. J2ME doesn't support it.
private static final Hashtable VALUES = new Hashtable();
// No, we can't use an enum here. J2ME doesn't support it.
public enum ResultMetadataType {
/**
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
*/
public static final ResultMetadataType OTHER = new ResultMetadataType("OTHER");
OTHER,
/**
* Denotes the likely approximate orientation of the barcode in the image. This value
@ -44,7 +36,7 @@ public final class ResultMetadataType {
* said to have orientation "90". This key maps to an {@link Integer} whose
* value is in the range [0,360).
*/
public static final ResultMetadataType ORIENTATION = new ResultMetadataType("ORIENTATION");
ORIENTATION,
/**
* <p>2D barcode formats typically encode text, but allow for a sort of 'byte mode'
@ -52,58 +44,32 @@ public final class ResultMetadataType {
* the complete raw bytes in the barcode for these formats, it does not offer the bytes
* from the byte segments alone.</p>
*
* <p>This maps to a {@link java.util.Vector} of byte arrays corresponding to the
* <p>This maps to a {@link java.util.List} of byte arrays corresponding to the
* raw bytes in the byte segments in the barcode, in order.</p>
*/
public static final ResultMetadataType BYTE_SEGMENTS = new ResultMetadataType("BYTE_SEGMENTS");
BYTE_SEGMENTS,
/**
* Error correction level used, if applicable. The value type depends on the
* format, but is typically a String.
*/
public static final ResultMetadataType ERROR_CORRECTION_LEVEL = new ResultMetadataType("ERROR_CORRECTION_LEVEL");
ERROR_CORRECTION_LEVEL,
/**
* For some periodicals, indicates the issue number as an {@link Integer}.
*/
public static final ResultMetadataType ISSUE_NUMBER = new ResultMetadataType("ISSUE_NUMBER");
ISSUE_NUMBER,
/**
* For some products, indicates the suggested retail price in the barcode as a
* formatted {@link String}.
*/
public static final ResultMetadataType SUGGESTED_PRICE = new ResultMetadataType("SUGGESTED_PRICE");
SUGGESTED_PRICE ,
/**
* For some products, the possible country of manufacture as a {@link String} denoting the
* ISO country code. Some map to multiple possible countries, like "US/CA".
*/
public static final ResultMetadataType POSSIBLE_COUNTRY = new ResultMetadataType("POSSIBLE_COUNTRY");
private final String name;
private ResultMetadataType(String name) {
this.name = name;
VALUES.put(name, this);
}
public String getName() {
return name;
}
public String toString() {
return name;
}
public static ResultMetadataType valueOf(String name) {
if (name == null || name.length() == 0) {
throw new IllegalArgumentException();
}
ResultMetadataType format = (ResultMetadataType) VALUES.get(name);
if (format == null) {
throw new IllegalArgumentException();
}
return format;
}
POSSIBLE_COUNTRY
}

View file

@ -40,6 +40,7 @@ public class ResultPoint {
return y;
}
@Override
public boolean equals(Object other) {
if (other instanceof ResultPoint) {
ResultPoint otherPoint = (ResultPoint) other;
@ -48,12 +49,14 @@ public class ResultPoint {
return false;
}
@Override
public int hashCode() {
return 31 * Float.floatToIntBits(x) + Float.floatToIntBits(y);
}
@Override
public String toString() {
StringBuffer result = new StringBuffer(25);
StringBuilder result = new StringBuilder(25);
result.append('(');
result.append(x);
result.append(',');
@ -111,15 +114,17 @@ public class ResultPoint {
* @return distance between two points
*/
public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
float xDiff = pattern1.getX() - pattern2.getX();
float yDiff = pattern1.getY() - pattern2.getY();
float xDiff = pattern1.x - pattern2.x;
float yDiff = pattern1.y - pattern2.y;
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
}
/**
* Returns the z component of the cross product between vectors BC and BA.
*/
private static float crossProductZ(ResultPoint pointA, ResultPoint pointB, ResultPoint pointC) {
private static float crossProductZ(ResultPoint pointA,
ResultPoint pointB,
ResultPoint pointC) {
float bX = pointB.x;
float bY = pointB.y;
return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));

View file

@ -18,7 +18,7 @@ package com.google.zxing;
import com.google.zxing.common.BitMatrix;
import java.util.Hashtable;
import java.util.Map;
/**
* The base class for all objects which encode/generate a barcode image.
@ -46,7 +46,11 @@ public interface Writer {
* @param height The preferred height in pixels
* @param hints Additional parameters to supply to the encoder
*/
BitMatrix encode(String contents, BarcodeFormat format, int width, int height, Hashtable hints)
BitMatrix encode(String contents,
BarcodeFormat format,
int width,
int height,
Map<EncodeHintType,?> hints)
throws WriterException;
}

View file

@ -25,7 +25,6 @@ package com.google.zxing;
public final class WriterException extends Exception {
public WriterException() {
super();
}
public WriterException(String message) {

View file

@ -26,7 +26,11 @@ public final class AztecDetectorResult extends DetectorResult {
private final int nbDatablocks;
private final int nbLayers;
public AztecDetectorResult(BitMatrix bits, ResultPoint[] points, boolean compact, int nbDatablocks, int nbLayers) {
public AztecDetectorResult(BitMatrix bits,
ResultPoint[] points,
boolean compact,
int nbDatablocks,
int nbLayers) {
super(bits, points);
this.compact = compact;
this.nbDatablocks = nbDatablocks;

View file

@ -31,8 +31,8 @@ import com.google.zxing.common.DecoderResult;
import com.google.zxing.aztec.decoder.Decoder;
import com.google.zxing.aztec.detector.Detector;
import java.util.Hashtable;
import java.util.Vector;
import java.util.List;
import java.util.Map;
/**
* This implementation can detect and decode Aztec codes in an image.
@ -49,11 +49,13 @@ public final class AztecReader implements Reader {
* @throws FormatException if a Data Matrix code cannot be decoded
* @throws ChecksumException if error correction fails
*/
@Override
public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {
return decode(image, null);
}
public Result decode(BinaryBitmap image, Hashtable hints)
@Override
public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)
throws NotFoundException, FormatException {
AztecDetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();
@ -62,8 +64,8 @@ public final class AztecReader implements Reader {
if (hints != null) {
ResultPointCallback rpcb = (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
if (rpcb != null) {
for (int i = 0; i < points.length; i++) {
rpcb.foundPossibleResultPoint(points[i]);
for (ResultPoint point : points) {
rpcb.foundPossibleResultPoint(point);
}
}
}
@ -72,7 +74,7 @@ public final class AztecReader implements Reader {
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.AZTEC);
Vector byteSegments = decoderResult.getByteSegments();
List<byte[]> byteSegments = decoderResult.getByteSegments();
if (byteSegments != null) {
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
}
@ -84,6 +86,7 @@ public final class AztecReader implements Reader {
return result;
}
@Override
public void reset() {
// do nothing
}

View file

@ -32,12 +32,14 @@ import com.google.zxing.common.reedsolomon.ReedSolomonException;
*/
public final class Decoder {
private static final int UPPER = 0;
private static final int LOWER = 1;
private static final int MIXED = 2;
private static final int DIGIT = 3;
private static final int PUNCT = 4;
private static final int BINARY = 5;
private enum Table {
UPPER,
LOWER,
MIXED,
DIGIT,
PUNCT,
BINARY
}
private static final int[] NB_BITS_COMPACT = {
0, 104, 240, 408, 608
@ -119,10 +121,10 @@ public final class Decoder {
throw FormatException.getFormatInstance();
}
int lastTable = UPPER;
int table = UPPER;
Table lastTable = Table.UPPER;
Table table = Table.UPPER;
int startIndex = 0;
StringBuffer result = new StringBuffer(20);
StringBuilder result = new StringBuilder(20);
boolean end = false;
boolean shift = false;
boolean switchShift = false;
@ -153,7 +155,7 @@ public final class Decoder {
default:
int size = 5;
if (table == DIGIT) {
if (table == Table.DIGIT) {
size = 4;
}
@ -194,31 +196,22 @@ public final class Decoder {
/**
* gets the table corresponding to the char passed
*/
private static int getTable(char t) {
int table = UPPER;
private static Table getTable(char t) {
switch (t) {
case 'U':
table = UPPER;
break;
case 'L':
table = LOWER;
break;
return Table.LOWER;
case 'P':
table = PUNCT;
break;
return Table.PUNCT;
case 'M':
table = MIXED;
break;
return Table.MIXED;
case 'D':
table = DIGIT;
break;
return Table.DIGIT;
case 'B':
table = BINARY;
break;
return Table.BINARY;
case 'U':
default:
return Table.UPPER;
}
return table;
}
/**
@ -228,7 +221,7 @@ public final class Decoder {
* @param table the table used
* @param code the code of the character
*/
private static String getCharacter(int table, int code) {
private static String getCharacter(Table table, int code) {
switch (table) {
case UPPER:
return UPPER_TABLE[code];
@ -373,7 +366,7 @@ public final class Decoder {
}
int layer = ddata.getNbLayers();
int size = matrix.height;
int size = matrix.getHeight();
int rawbitsOffset = 0;
int matrixOffset = 0;
@ -407,21 +400,21 @@ public final class Decoder {
* Transforms an Aztec code matrix by removing the control dashed lines
*/
private static BitMatrix removeDashedLines(BitMatrix matrix) {
int nbDashed = 1+ 2* ((matrix.width - 1)/2 / 16);
BitMatrix newMatrix = new BitMatrix(matrix.width - nbDashed, matrix.height - nbDashed);
int nbDashed = 1 + 2 * ((matrix.getWidth() - 1) / 2 / 16);
BitMatrix newMatrix = new BitMatrix(matrix.getWidth() - nbDashed, matrix.getHeight() - nbDashed);
int nx = 0;
for (int x = 0; x < matrix.width; x++) {
for (int x = 0; x < matrix.getWidth(); x++) {
if ((matrix.width / 2 - x)%16 == 0) {
if ((matrix.getWidth() / 2 - x) % 16 == 0) {
continue;
}
int ny = 0;
for (int y = 0; y < matrix.height; y++) {
for (int y = 0; y < matrix.getHeight(); y++) {
if ((matrix.width / 2 - y)%16 == 0) {
if ((matrix.getWidth() / 2 - y) % 16 == 0) {
continue;
}

View file

@ -346,8 +346,8 @@ public final class Detector {
// This exception can be in case the initial rectangle is white
// In that case, surely in the bull's eye, we try to expand the rectangle.
int cx = image.width/2;
int cy = image.height/2;
int cx = image.getWidth()/2;
int cy = image.getHeight()/2;
pointA = getFirstDifferent(new Point(cx+15/2, cy-15/2), false, 1, -1).toResultPoint();
pointB = getFirstDifferent(new Point(cx+15/2, cy+15/2), false, 1, 1).toResultPoint();
pointC = getFirstDifferent(new Point(cx-15/2, cy+15/2), false, -1, 1).toResultPoint();
@ -473,7 +473,7 @@ public final class Detector {
* @param size number of bits
* @return the array of bits
*/
private boolean[] sampleLine(Point p1, Point p2,int size) {
private boolean[] sampleLine(Point p1, Point p2, int size) {
boolean[] res = new boolean[size];
float d = distance(p1,p2);
@ -497,7 +497,10 @@ public final class Detector {
* @return true if the border of the rectangle passed in parameter is compound of white points only
* or black points only
*/
private boolean isWhiteOrBlackRectangle(Point p1, Point p2, Point p3, Point p4) {
private boolean isWhiteOrBlackRectangle(Point p1,
Point p2,
Point p3,
Point p4) {
int corr = 3;
@ -610,7 +613,7 @@ public final class Detector {
}
private boolean isValid(int x, int y) {
return x >= 0 && x < image.width && y > 0 && y < image.height;
return x >= 0 && x < image.getWidth() && y > 0 && y < image.getHeight();
}
/**

View file

@ -18,7 +18,8 @@ package com.google.zxing.client.result;
import com.google.zxing.Result;
import java.util.Vector;
import java.util.ArrayList;
import java.util.List;
/**
* Implements KDDI AU's address book format. See
@ -28,12 +29,13 @@ import java.util.Vector;
*
* @author Sean Owen
*/
final class AddressBookAUResultParser extends ResultParser {
public final class AddressBookAUResultParser extends ResultParser {
public static AddressBookParsedResult parse(Result result) {
@Override
public AddressBookParsedResult parse(Result result) {
String rawText = result.getText();
// MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF
if (rawText.indexOf("MEMORY") < 0 || rawText.indexOf("\r\n") < 0) {
if (!rawText.contains("MEMORY") || !rawText.contains("\r\n")) {
return null;
}
@ -67,21 +69,21 @@ final class AddressBookAUResultParser extends ResultParser {
int max,
String rawText,
boolean trim) {
Vector values = null;
List<String> values = null;
for (int i = 1; i <= max; i++) {
String value = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', trim);
if (value == null) {
break;
}
if (values == null) {
values = new Vector(max); // lazy init
values = new ArrayList<String>(max); // lazy init
}
values.addElement(value);
values.add(value);
}
if (values == null) {
return null;
}
return toStringArray(values);
return values.toArray(new String[values.size()]);
}
}

View file

@ -33,9 +33,10 @@ import com.google.zxing.Result;
*
* @author Sean Owen
*/
final class AddressBookDoCoMoResultParser extends AbstractDoCoMoResultParser {
public final class AddressBookDoCoMoResultParser extends AbstractDoCoMoResultParser {
public static AddressBookParsedResult parse(Result result) {
@Override
public AddressBookParsedResult parse(Result result) {
String rawText = result.getText();
if (!rawText.startsWith("MECARD:")) {
return null;

View file

@ -144,8 +144,9 @@ public final class AddressBookParsedResult extends ParsedResult {
return birthday;
}
@Override
public String getDisplayResult() {
StringBuffer result = new StringBuffer(100);
StringBuilder result = new StringBuilder(100);
maybeAppend(names, result);
maybeAppend(pronunciation, result);
maybeAppend(title, result);

View file

@ -18,7 +18,8 @@ package com.google.zxing.client.result;
import com.google.zxing.Result;
import java.util.Vector;
import java.util.ArrayList;
import java.util.List;
/**
* Implements the "BIZCARD" address book entry format, though this has been
@ -27,13 +28,14 @@ import java.util.Vector;
*
* @author Sean Owen
*/
final class BizcardResultParser extends AbstractDoCoMoResultParser {
public final class BizcardResultParser extends AbstractDoCoMoResultParser {
// Yes, we extend AbstractDoCoMoResultParser since the format is very much
// like the DoCoMo MECARD format, but this is not technically one of
// DoCoMo's proposed formats
public static AddressBookParsedResult parse(Result result) {
@Override
public AddressBookParsedResult parse(Result result) {
String rawText = result.getText();
if (!rawText.startsWith("BIZCARD:")) {
return null;
@ -65,26 +67,24 @@ final class BizcardResultParser extends AbstractDoCoMoResultParser {
null);
}
private static String[] buildPhoneNumbers(String number1, String number2, String number3) {
Vector numbers = new Vector(3);
private static String[] buildPhoneNumbers(String number1,
String number2,
String number3) {
List<String> numbers = new ArrayList<String>(3);
if (number1 != null) {
numbers.addElement(number1);
numbers.add(number1);
}
if (number2 != null) {
numbers.addElement(number2);
numbers.add(number2);
}
if (number3 != null) {
numbers.addElement(number3);
numbers.add(number3);
}
int size = numbers.size();
if (size == 0) {
return null;
}
String[] result = new String[size];
for (int i = 0; i < size; i++) {
result[i] = (String) numbers.elementAt(i);
}
return result;
return numbers.toArray(new String[size]);
}
private static String buildName(String firstName, String lastName) {

View file

@ -21,12 +21,10 @@ import com.google.zxing.Result;
/**
* @author Sean Owen
*/
final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {
public final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {
private BookmarkDoCoMoResultParser() {
}
public static URIParsedResult parse(Result result) {
@Override
public URIParsedResult parse(Result result) {
String rawText = result.getText();
if (!rawText.startsWith("MEBKM:")) {
return null;
@ -37,10 +35,7 @@ final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {
return null;
}
String uri = rawUri[0];
if (!URIResultParser.isBasicallyValidURI(uri)) {
return null;
}
return new URIParsedResult(uri, title);
return URIResultParser.isBasicallyValidURI(uri) ? new URIParsedResult(uri, title) : null;
}
}

View file

@ -71,7 +71,7 @@ public final class CalendarParsedResult extends ParsedResult {
/**
* <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> See validateDate() for the return format.
* as {@code java.text.SimpleDateFormat}.</p> See validateDate() for the return format.
*
* @return start time formatted as a RFC 2445 DATE or DATE-TIME.</p>
*/
@ -106,8 +106,9 @@ public final class CalendarParsedResult extends ParsedResult {
return longitude;
}
@Override
public String getDisplayResult() {
StringBuffer result = new StringBuffer(100);
StringBuilder result = new StringBuilder(100);
maybeAppend(summary, result);
maybeAppend(start, result);
maybeAppend(end, result);
@ -123,7 +124,7 @@ public final class CalendarParsedResult extends ParsedResult {
*
* @param date The string to validate
*/
private static void validateDate(String date) {
private static void validateDate(CharSequence date) {
if (date != null) {
int length = date.length();
if (length != 8 && length != 15 && length != 16) {

View file

@ -26,7 +26,10 @@ public final class EmailAddressParsedResult extends ParsedResult {
private final String body;
private final String mailtoURI;
EmailAddressParsedResult(String emailAddress, String subject, String body, String mailtoURI) {
EmailAddressParsedResult(String emailAddress,
String subject,
String body,
String mailtoURI) {
super(ParsedResultType.EMAIL_ADDRESS);
this.emailAddress = emailAddress;
this.subject = subject;
@ -50,8 +53,9 @@ public final class EmailAddressParsedResult extends ParsedResult {
return mailtoURI;
}
@Override
public String getDisplayResult() {
StringBuffer result = new StringBuffer(30);
StringBuilder result = new StringBuilder(30);
maybeAppend(emailAddress, result);
maybeAppend(subject, result);
maybeAppend(body, result);

View file

@ -18,7 +18,7 @@ package com.google.zxing.client.result;
import com.google.zxing.Result;
import java.util.Hashtable;
import java.util.Map;
/**
* Represents a result that encodes an e-mail address, either as a plain address
@ -26,9 +26,10 @@ import java.util.Hashtable;
*
* @author Sean Owen
*/
final class EmailAddressResultParser extends ResultParser {
public final class EmailAddressResultParser extends ResultParser {
public static EmailAddressParsedResult parse(Result result) {
@Override
public EmailAddressParsedResult parse(Result result) {
String rawText = result.getText();
String emailAddress;
if (rawText.startsWith("mailto:") || rawText.startsWith("MAILTO:")) {
@ -38,15 +39,15 @@ final class EmailAddressResultParser extends ResultParser {
if (queryStart >= 0) {
emailAddress = emailAddress.substring(0, queryStart);
}
Hashtable nameValues = parseNameValuePairs(rawText);
Map<String,String> nameValues = parseNameValuePairs(rawText);
String subject = null;
String body = null;
if (nameValues != null) {
if (emailAddress.length() == 0) {
emailAddress = (String) nameValues.get("to");
emailAddress = nameValues.get("to");
}
subject = (String) nameValues.get("subject");
body = (String) nameValues.get("body");
subject = nameValues.get("subject");
body = nameValues.get("body");
}
return new EmailAddressParsedResult(emailAddress, subject, body, rawText);
} else {

View file

@ -18,6 +18,8 @@ package com.google.zxing.client.result;
import com.google.zxing.Result;
import java.util.regex.Pattern;
/**
* Implements the "MATMSG" email message entry format.
*
@ -25,12 +27,12 @@ import com.google.zxing.Result;
*
* @author Sean Owen
*/
final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
public final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
private static final char[] ATEXT_SYMBOLS =
{'@','.','!','#','$','%','&','\'','*','+','-','/','=','?','^','_','`','{','|','}','~'};
private static final Pattern ATEXT_ALPHANUMERIC = Pattern.compile("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+");
public static EmailAddressParsedResult parse(Result result) {
@Override
public EmailAddressParsedResult parse(Result result) {
String rawText = result.getText();
if (!rawText.startsWith("MATMSG:")) {
return null;
@ -50,38 +52,12 @@ final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
/**
* This implements only the most basic checking for an email address's validity -- that it contains
* an '@' contains no characters disallowed by RFC 2822. This is an overly lenient definition of
* an '@' and contains no characters disallowed by RFC 2822. This is an overly lenient definition of
* validity. We want to generally be lenient here since this class is only intended to encapsulate what's
* in a barcode, not "judge" it.
*/
static boolean isBasicallyValidEmailAddress(String email) {
if (email == null) {
return false;
}
boolean atFound = false;
for (int i = 0; i < email.length(); i++) {
char c = email.charAt(i);
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') &&
!isAtextSymbol(c)) {
return false;
}
if (c == '@') {
if (atFound) {
return false;
}
atFound = true;
}
}
return atFound;
}
private static boolean isAtextSymbol(char c) {
for (int i = 0; i < ATEXT_SYMBOLS.length; i++) {
if (c == ATEXT_SYMBOLS[i]) {
return true;
}
}
return false;
return email != null && ATEXT_ALPHANUMERIC.matcher(email).matches() && email.indexOf('@') >= 0;
}
}

View file

@ -26,13 +26,13 @@
package com.google.zxing.client.result;
import java.util.Hashtable;
import java.util.Map;
/**
* @author Antonio Manuel Benjumea Conde, Servinform, S.A.
* @author Agustín Delgado, Servinform, S.A.
*/
public class ExpandedProductParsedResult extends ParsedResult {
public final class ExpandedProductParsedResult extends ParsedResult {
public static final String KILOGRAM = "KG";
public static final String POUND = "LB";
@ -51,7 +51,7 @@ public class ExpandedProductParsedResult extends ParsedResult {
private final String priceIncrement;
private final String priceCurrency;
// For AIS that not exist in this object
private final Hashtable uncommonAIs;
private final Map<String,String> uncommonAIs;
public ExpandedProductParsedResult(String productID,
String sscc,
@ -66,7 +66,7 @@ public class ExpandedProductParsedResult extends ParsedResult {
String price,
String priceIncrement,
String priceCurrency,
Hashtable uncommonAIs) {
Map<String,String> uncommonAIs) {
super(ParsedResultType.PRODUCT);
this.productID = productID;
this.sscc = sscc;
@ -84,6 +84,7 @@ public class ExpandedProductParsedResult extends ParsedResult {
this.uncommonAIs = uncommonAIs;
}
@Override
public boolean equals(Object o){
if (!(o instanceof ExpandedProductParsedResult)) {
return false;
@ -110,6 +111,7 @@ public class ExpandedProductParsedResult extends ParsedResult {
return o1 == null ? o2 == null : o1.equals(o2);
}
@Override
public int hashCode(){
int hash = 0;
hash ^= hashNotNull(productID);
@ -184,10 +186,11 @@ public class ExpandedProductParsedResult extends ParsedResult {
return priceCurrency;
}
public Hashtable getUncommonAIs() {
public Map<String,String> getUncommonAIs() {
return uncommonAIs;
}
@Override
public String getDisplayResult() {
return String.valueOf(productID);
}

View file

@ -26,7 +26,8 @@
package com.google.zxing.client.result;
import java.util.Hashtable;
import java.util.HashMap;
import java.util.Map;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
@ -37,16 +38,12 @@ import com.google.zxing.Result;
* @author Antonio Manuel Benjumea Conde, Servinform, S.A.
* @author Agustín Delgado, Servinform, S.A.
*/
final class ExpandedProductResultParser extends ResultParser {
public final class ExpandedProductResultParser extends ResultParser {
private ExpandedProductResultParser() {
}
// Treat all RSS EXPANDED, in the sense that they are all
// product barcodes with complementary data.
public static ExpandedProductParsedResult parse(Result result) {
@Override
public ExpandedProductParsedResult parse(Result result) {
BarcodeFormat format = result.getBarcodeFormat();
if (!BarcodeFormat.RSS_EXPANDED.equals(format)) {
if (format != BarcodeFormat.RSS_EXPANDED) {
// ExtendedProductParsedResult NOT created. Not a RSS Expanded barcode
return null;
}
@ -70,7 +67,7 @@ final class ExpandedProductResultParser extends ResultParser {
String price = null;
String priceIncrement = null;
String priceCurrency = null;
Hashtable uncommonAIs = new Hashtable();
Map<String,String> uncommonAIs = new HashMap<String,String>();
int i = 0;
@ -153,7 +150,7 @@ final class ExpandedProductResultParser extends ResultParser {
}
private static String findAIvalue(int i, String rawText) {
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
char c = rawText.charAt(i);
// First character must be a open parenthesis.If not, ERROR
if (c != '(') {
@ -176,7 +173,7 @@ final class ExpandedProductResultParser extends ResultParser {
}
private static String findValue(int i, String rawText) {
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
String rawTextAux = rawText.substring(i);
for (int index = 0; index < rawTextAux.length(); index++) {

View file

@ -35,7 +35,7 @@ public final class GeoParsedResult extends ParsedResult {
}
public String getGeoURI() {
StringBuffer result = new StringBuffer();
StringBuilder result = new StringBuilder();
result.append("geo:");
result.append(latitude);
result.append(',');
@ -79,8 +79,9 @@ public final class GeoParsedResult extends ParsedResult {
return query;
}
@Override
public String getDisplayResult() {
StringBuffer result = new StringBuffer(20);
StringBuilder result = new StringBuilder(20);
result.append(latitude);
result.append(", ");
result.append(longitude);
@ -97,36 +98,4 @@ public final class GeoParsedResult extends ParsedResult {
return result.toString();
}
/**
* @return a URI link to Google Maps which display the point on the Earth described
* by this instance, and sets the zoom level in a way that roughly reflects the
* altitude, if specified
*/
/*
public String getGoogleMapsURI() {
StringBuffer result = new StringBuffer(50);
result.append("http://maps.google.com/?ll=");
result.append(latitude);
result.append(',');
result.append(longitude);
if (altitude > 0.0f) {
// Map altitude to zoom level, cleverly. Roughly, zoom level 19 is like a
// view from 1000ft, 18 is like 2000ft, 17 like 4000ft, and so on.
double altitudeInFeet = altitude * 3.28;
int altitudeInKFeet = (int) (altitudeInFeet / 1000.0);
// No Math.log() available here, so compute log base 2 the old fashioned way
// Here logBaseTwo will take on a value between 0 and 18 actually
int logBaseTwo = 0;
while (altitudeInKFeet > 1 && logBaseTwo < 18) {
altitudeInKFeet >>= 1;
logBaseTwo++;
}
int zoom = 19 - logBaseTwo;
result.append("&z=");
result.append(zoom);
}
return result.toString();
}
*/
}

View file

@ -18,6 +18,9 @@ package com.google.zxing.client.result;
import com.google.zxing.Result;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Parses a "geo:" URI result, which specifies a location on the surface of
* the Earth as well as an optional altitude above the surface. See
@ -26,50 +29,45 @@ import com.google.zxing.Result;
*
* @author Sean Owen
*/
final class GeoResultParser extends ResultParser {
public final class GeoResultParser extends ResultParser {
private GeoResultParser() {
}
private static final Pattern GEO_URL_PATTERN =
Pattern.compile("geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?", Pattern.CASE_INSENSITIVE);
public static GeoParsedResult parse(Result result) {
@Override
public GeoParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || (!rawText.startsWith("geo:") && !rawText.startsWith("GEO:"))) {
if (rawText == null) {
return null;
}
// Drop geo, query portion
int queryStart = rawText.indexOf('?', 4);
String query;
String geoURIWithoutQuery;
if (queryStart < 0) {
query = null;
geoURIWithoutQuery = rawText.substring(4);
} else {
query = rawText.substring(queryStart + 1);
geoURIWithoutQuery = rawText.substring(4, queryStart);
}
int latitudeEnd = geoURIWithoutQuery.indexOf(',');
if (latitudeEnd < 0) {
Matcher matcher = GEO_URL_PATTERN.matcher(rawText);
if (!matcher.matches()) {
return null;
}
int longitudeEnd = geoURIWithoutQuery.indexOf(',', latitudeEnd + 1);
String query = matcher.group(4);
double latitude;
double longitude;
double altitude;
try {
latitude = Double.parseDouble(geoURIWithoutQuery.substring(0, latitudeEnd));
latitude = Double.parseDouble(matcher.group(1));
if (latitude > 90.0 || latitude < -90.0) {
return null;
}
if (longitudeEnd < 0) {
longitude = Double.parseDouble(geoURIWithoutQuery.substring(latitudeEnd + 1));
longitude = Double.parseDouble(matcher.group(2));
if (longitude > 180.0 || longitude < -180.0) {
return null;
}
if (matcher.group(3) == null) {
altitude = 0.0;
} else {
longitude = Double.parseDouble(geoURIWithoutQuery.substring(latitudeEnd + 1, longitudeEnd));
altitude = Double.parseDouble(geoURIWithoutQuery.substring(longitudeEnd + 1));
}
if (longitude > 180.0 || longitude < -180.0 || altitude < 0) {
altitude = Double.parseDouble(matcher.group(3));
if (altitude < 0.0) {
return null;
}
}
} catch (NumberFormatException nfe) {
return null;
}

View file

@ -32,6 +32,7 @@ public final class ISBNParsedResult extends ParsedResult {
return isbn;
}
@Override
public String getDisplayResult() {
return isbn;
}

View file

@ -24,16 +24,15 @@ import com.google.zxing.Result;
*
* @author jbreiden@google.com (Jeff Breidenbach)
*/
public class ISBNResultParser extends ResultParser {
public final class ISBNResultParser extends ResultParser {
private ISBNResultParser() {
}
// ISBN-13 For Dummies
// http://www.bisg.org/isbn-13/for.dummies.html
public static ISBNParsedResult parse(Result result) {
/**
* See <a href="http://www.bisg.org/isbn-13/for.dummies.html">ISBN-13 For Dummies</a>
*/
@Override
public ISBNParsedResult parse(Result result) {
BarcodeFormat format = result.getBarcodeFormat();
if (!BarcodeFormat.EAN_13.equals(format)) {
if (format != BarcodeFormat.EAN_13) {
return null;
}
String rawText = result.getText();

View file

@ -43,11 +43,12 @@ public abstract class ParsedResult {
public abstract String getDisplayResult();
@Override
public String toString() {
return getDisplayResult();
}
public static void maybeAppend(String value, StringBuffer result) {
public static void maybeAppend(String value, StringBuilder result) {
if (value != null && value.length() > 0) {
// Don't add a newline before the first value
if (result.length() > 0) {
@ -57,14 +58,14 @@ public abstract class ParsedResult {
}
}
public static void maybeAppend(String[] value, StringBuffer result) {
public static void maybeAppend(String[] value, StringBuilder result) {
if (value != null) {
for (int i = 0; i < value.length; i++) {
if (value[i] != null && value[i].length() > 0) {
for (String s : value) {
if (s != null && s.length() > 0) {
if (result.length() > 0) {
result.append('\n');
}
result.append(value[i]);
result.append(s);
}
}
}

View file

@ -22,32 +22,18 @@ package com.google.zxing.client.result;
*
* @author Sean Owen
*/
public final class ParsedResultType {
public enum ParsedResultType {
public static final ParsedResultType ADDRESSBOOK = new ParsedResultType("ADDRESSBOOK");
public static final ParsedResultType EMAIL_ADDRESS = new ParsedResultType("EMAIL_ADDRESS");
public static final ParsedResultType PRODUCT = new ParsedResultType("PRODUCT");
public static final ParsedResultType URI = new ParsedResultType("URI");
public static final ParsedResultType TEXT = new ParsedResultType("TEXT");
public static final ParsedResultType ANDROID_INTENT = new ParsedResultType("ANDROID_INTENT");
public static final ParsedResultType GEO = new ParsedResultType("GEO");
public static final ParsedResultType TEL = new ParsedResultType("TEL");
public static final ParsedResultType SMS = new ParsedResultType("SMS");
public static final ParsedResultType CALENDAR = new ParsedResultType("CALENDAR");
public static final ParsedResultType WIFI = new ParsedResultType("WIFI");
// "optional" types
public static final ParsedResultType NDEF_SMART_POSTER = new ParsedResultType("NDEF_SMART_POSTER");
public static final ParsedResultType MOBILETAG_RICH_WEB = new ParsedResultType("MOBILETAG_RICH_WEB");
public static final ParsedResultType ISBN = new ParsedResultType("ISBN");
private final String name;
private ParsedResultType(String name) {
this.name = name;
}
public String toString() {
return name;
}
ADDRESSBOOK,
EMAIL_ADDRESS,
PRODUCT,
URI,
TEXT,
GEO,
TEL,
SMS,
CALENDAR,
WIFI,
ISBN,
}

View file

@ -42,6 +42,7 @@ public final class ProductParsedResult extends ParsedResult {
return normalizedProductID;
}
@Override
public String getDisplayResult() {
return productID;
}

View file

@ -25,16 +25,14 @@ import com.google.zxing.oned.UPCEReader;
*
* @author dswitkin@google.com (Daniel Switkin)
*/
final class ProductResultParser extends ResultParser {
private ProductResultParser() {
}
public final class ProductResultParser extends ResultParser {
// Treat all UPC and EAN variants as UPCs, in the sense that they are all product barcodes.
public static ProductParsedResult parse(Result result) {
@Override
public ProductParsedResult parse(Result result) {
BarcodeFormat format = result.getBarcodeFormat();
if (!(BarcodeFormat.UPC_A.equals(format) || BarcodeFormat.UPC_E.equals(format) ||
BarcodeFormat.EAN_8.equals(format) || BarcodeFormat.EAN_13.equals(format))) {
if (!(format == BarcodeFormat.UPC_A || format == BarcodeFormat.UPC_E ||
format == BarcodeFormat.EAN_8 || format == BarcodeFormat.EAN_13)) {
return null;
}
String rawText = result.getText();
@ -49,7 +47,7 @@ final class ProductResultParser extends ResultParser {
String normalizedProductID;
// Expand UPC-E for purposes of searching
if (BarcodeFormat.UPC_E.equals(format)) {
if (format == BarcodeFormat.UPC_E) {
normalizedProductID = UPCEReader.convertUPCEtoUPCA(rawText);
} else {
normalizedProductID = rawText;

View file

@ -18,13 +18,18 @@ package com.google.zxing.client.result;
import com.google.zxing.Result;
import java.util.Hashtable;
import java.util.Vector;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
* <p>Abstract class representing the result of decoding a barcode, as more than
* a String -- as some type of structured data. This might be a subclass which represents
* a URL, or an e-mail address. {@link #parseResult(com.google.zxing.Result)} will turn a raw
* a URL, or an e-mail address. {@link #parseResult(Result)} will turn a raw
* decoded string into the most appropriate type of structured representation.</p>
*
* <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
@ -34,67 +39,62 @@ import java.util.Vector;
*/
public abstract class ResultParser {
private static final ResultParser[] PARSERS = {
new BookmarkDoCoMoResultParser(),
new AddressBookDoCoMoResultParser(),
new EmailDoCoMoResultParser(),
new AddressBookAUResultParser(),
new VCardResultParser(),
new BizcardResultParser(),
new VEventResultParser(),
new EmailAddressResultParser(),
new SMTPResultParser(),
new TelResultParser(),
new SMSMMSResultParser(),
new SMSTOMMSTOResultParser(),
new GeoResultParser(),
new WifiResultParser(),
new URLTOResultParser(),
new URIResultParser(),
new ISBNResultParser(),
new ProductResultParser(),
new ExpandedProductResultParser(),
};
private static final Pattern DIGITS = Pattern.compile("\\d*");
private static final Pattern ALPHANUM = Pattern.compile("[a-zA-Z0-9]*");
private static final Pattern AMPERSAND = Pattern.compile("&");
private static final Pattern EQUALS = Pattern.compile("=");
/**
* Attempts to parse the raw {@link Result}'s contents as a particular type
* of information (email, URL, etc.) and return a {@link ParsedResult} encapsulating
* the result of parsing.
*/
public abstract ParsedResult parse(Result theResult);
public static ParsedResult parseResult(Result theResult) {
// This is a bit messy, but given limited options in MIDP / CLDC, this may well be the simplest
// way to go about this. For example, we have no reflection available, really.
// Order is important here.
ParsedResult result;
if ((result = BookmarkDoCoMoResultParser.parse(theResult)) != null) {
return result;
} else if ((result = AddressBookDoCoMoResultParser.parse(theResult)) != null) {
return result;
} else if ((result = EmailDoCoMoResultParser.parse(theResult)) != null) {
return result;
} else if ((result = AddressBookAUResultParser.parse(theResult)) != null) {
return result;
} else if ((result = VCardResultParser.parse(theResult)) != null) {
return result;
} else if ((result = BizcardResultParser.parse(theResult)) != null) {
return result;
} else if ((result = VEventResultParser.parse(theResult)) != null) {
return result;
} else if ((result = EmailAddressResultParser.parse(theResult)) != null) {
return result;
} else if ((result = SMTPResultParser.parse(theResult)) != null) {
return result;
} else if ((result = TelResultParser.parse(theResult)) != null) {
return result;
} else if ((result = SMSMMSResultParser.parse(theResult)) != null) {
return result;
} else if ((result = SMSTOMMSTOResultParser.parse(theResult)) != null) {
return result;
} else if ((result = GeoResultParser.parse(theResult)) != null) {
return result;
} else if ((result = WifiResultParser.parse(theResult)) != null) {
return result;
} else if ((result = URLTOResultParser.parse(theResult)) != null) {
return result;
} else if ((result = URIResultParser.parse(theResult)) != null) {
// URI is a catch-all for protocol: contents that we don't handle explicitly above.
return result;
} else if ((result = ISBNResultParser.parse(theResult)) != null) {
// We depend on ISBN parsing coming before UPC, as it is a subset.
return result;
} else if ((result = ProductResultParser.parse(theResult)) != null) {
return result;
} else if ((result = ExpandedProductResultParser.parse(theResult)) != null) {
for (ResultParser parser : PARSERS) {
ParsedResult result = parser.parse(theResult);
if (result != null) {
return result;
}
}
return new TextParsedResult(theResult.getText(), null);
}
protected static void maybeAppend(String value, StringBuffer result) {
protected static void maybeAppend(String value, StringBuilder result) {
if (value != null) {
result.append('\n');
result.append(value);
}
}
protected static void maybeAppend(String[] value, StringBuffer result) {
protected static void maybeAppend(String[] value, StringBuilder result) {
if (value != null) {
for (int i = 0; i < value.length; i++) {
for (String s : value) {
result.append('\n');
result.append(value[i]);
result.append(s);
}
}
}
@ -109,7 +109,7 @@ public abstract class ResultParser {
return escaped;
}
int max = escaped.length();
StringBuffer unescaped = new StringBuffer(max - 1);
StringBuilder unescaped = new StringBuilder(max - 1);
unescaped.append(escaped.toCharArray(), 0, backslash);
boolean nextIsEscaped = false;
for (int i = backslash; i < max; i++) {
@ -124,148 +124,68 @@ public abstract class ResultParser {
return unescaped.toString();
}
private static String urlDecode(String escaped) {
// No we can't use java.net.URLDecoder here. JavaME doesn't have it.
if (escaped == null) {
return null;
}
char[] escapedArray = escaped.toCharArray();
int first = findFirstEscape(escapedArray);
if (first < 0) {
return escaped;
}
int max = escapedArray.length;
// Final length is at most 2 less than original due to at least 1 unescaping.
StringBuffer unescaped = new StringBuffer(max - 2);
// Can append everything up to first escape character
unescaped.append(escapedArray, 0, first);
for (int i = first; i < max; i++) {
char c = escapedArray[i];
switch (c) {
case '+':
// + is translated directly into a space
unescaped.append(' ');
break;
case '%':
// Are there even two more chars? If not we'll just copy the escaped sequence and be done.
if (i >= max - 2) {
unescaped.append('%'); // append that % and move on
} else {
int firstDigitValue = parseHexDigit(escapedArray[++i]);
int secondDigitValue = parseHexDigit(escapedArray[++i]);
if (firstDigitValue < 0 || secondDigitValue < 0) {
// Bad digit, just move on.
unescaped.append('%');
unescaped.append(escapedArray[i - 1]);
unescaped.append(escapedArray[i]);
}
unescaped.append((char) ((firstDigitValue << 4) + secondDigitValue));
}
break;
default:
unescaped.append(c);
break;
}
}
return unescaped.toString();
}
private static int findFirstEscape(char[] escapedArray) {
int max = escapedArray.length;
for (int i = 0; i < max; i++) {
char c = escapedArray[i];
if (c == '+' || c == '%') {
return i;
}
}
return -1;
}
private static int parseHexDigit(char c) {
if (c >= 'a') {
if (c <= 'f') {
return 10 + (c - 'a');
}
} else if (c >= 'A') {
if (c <= 'F') {
return 10 + (c - 'A');
}
} else if (c >= '0') {
if (c <= '9') {
protected static int parseHexDigit(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'a' && c <= 'f') {
return 10 + (c - 'a');
}
if (c >= 'A' && c <= 'F') {
return 10 + (c - 'A');
}
return -1;
}
protected static boolean isStringOfDigits(String value, int length) {
if (value == null) {
return false;
}
int stringLength = value.length();
if (length != stringLength) {
return false;
}
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
protected static boolean isStringOfDigits(CharSequence value, int length) {
return value != null && length == value.length() && DIGITS.matcher(value).matches();
}
protected static boolean isSubstringOfDigits(String value, int offset, int length) {
protected static boolean isSubstringOfDigits(CharSequence value, int offset, int length) {
if (value == null) {
return false;
}
int stringLength = value.length();
int max = offset + length;
if (stringLength < max) {
return false;
}
for (int i = offset; i < max; i++) {
char c = value.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
return value.length() >= max && DIGITS.matcher(value.subSequence(offset, max)).matches();
}
static Hashtable parseNameValuePairs(String uri) {
protected static boolean isSubstringOfAlphaNumeric(CharSequence value, int offset, int length) {
if (value == null) {
return false;
}
int max = offset + length;
return value.length() >= max && ALPHANUM.matcher(value.subSequence(offset, max)).matches();
}
static Map<String,String> parseNameValuePairs(String uri) {
int paramStart = uri.indexOf('?');
if (paramStart < 0) {
return null;
}
Hashtable result = new Hashtable(3);
paramStart++;
int paramEnd;
while ((paramEnd = uri.indexOf('&', paramStart)) >= 0) {
appendKeyValue(uri, paramStart, paramEnd, result);
paramStart = paramEnd + 1;
Map<String,String> result = new HashMap<String,String>(3);
for (String keyValue : AMPERSAND.split(uri.substring(paramStart + 1))) {
appendKeyValue(keyValue, result);
}
appendKeyValue(uri, paramStart, uri.length(), result);
return result;
}
private static void appendKeyValue(String uri, int paramStart, int paramEnd, Hashtable result) {
int separator = uri.indexOf('=', paramStart);
if (separator >= 0) {
// key = value
String key = uri.substring(paramStart, separator);
String value = uri.substring(separator + 1, paramEnd);
value = urlDecode(value);
private static void appendKeyValue(CharSequence keyValue,
Map<String,String> result) {
String[] keyValueTokens = EQUALS.split(keyValue, 2);
if (keyValueTokens.length == 2) {
String key = keyValueTokens[0];
String value = keyValueTokens[1];
try {
value = URLDecoder.decode(value, "UTF-8");
} catch (UnsupportedEncodingException uee) {
throw new IllegalStateException(uee); // can't happen
}
result.put(key, value);
}
// Can't put key, null into a hashtable
}
static String[] matchPrefixedField(String prefix, String rawText, char endChar, boolean trim) {
Vector matches = null;
List<String> matches = null;
int i = 0;
int max = rawText.length();
while (i < max) {
@ -275,35 +195,35 @@ public abstract class ResultParser {
}
i += prefix.length(); // Skip past this prefix we found to start
int start = i; // Found the start of a match here
boolean done = false;
while (!done) {
boolean more = true;
while (more) {
i = rawText.indexOf((int) endChar, i);
if (i < 0) {
// No terminating end character? uh, done. Set i such that loop terminates and break
i = rawText.length();
done = true;
more = false;
} else if (rawText.charAt(i - 1) == '\\') {
// semicolon was escaped so continue
i++;
} else {
// found a match
if (matches == null) {
matches = new Vector(3); // lazy init
matches = new ArrayList<String>(3); // lazy init
}
String element = unescapeBackslash(rawText.substring(start, i));
if (trim) {
element = element.trim();
}
matches.addElement(element);
matches.add(element);
i++;
done = true;
more = false;
}
}
}
if (matches == null || matches.isEmpty()) {
return null;
}
return toStringArray(matches);
return matches.toArray(new String[matches.size()]);
}
static String matchSinglePrefixedField(String prefix, String rawText, char endChar, boolean trim) {
@ -311,13 +231,4 @@ public abstract class ResultParser {
return matches == null ? null : matches[0];
}
static String[] toStringArray(Vector strings) {
int size = strings.size();
String[] result = new String[size];
for (int j = 0; j < size; j++) {
result[j] = (String) strings.elementAt(j);
}
return result;
}
}

View file

@ -18,8 +18,10 @@ package com.google.zxing.client.result;
import com.google.zxing.Result;
import java.util.Hashtable;
import java.util.Vector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* <p>Parses an "sms:" URI result, which specifies a number to SMS.
@ -36,12 +38,10 @@ import java.util.Vector;
*
* @author Sean Owen
*/
final class SMSMMSResultParser extends ResultParser {
public final class SMSMMSResultParser extends ResultParser {
private SMSMMSResultParser() {
}
public static SMSParsedResult parse(Result result) {
@Override
public SMSParsedResult parse(Result result) {
String rawText = result.getText();
if (!(rawText.startsWith("sms:") || rawText.startsWith("SMS:") ||
rawText.startsWith("mms:") || rawText.startsWith("MMS:"))) {
@ -49,13 +49,13 @@ final class SMSMMSResultParser extends ResultParser {
}
// Check up front if this is a URI syntax string with query arguments
Hashtable nameValuePairs = parseNameValuePairs(rawText);
Map<String,String> nameValuePairs = parseNameValuePairs(rawText);
String subject = null;
String body = null;
boolean querySyntax = false;
if (nameValuePairs != null && !nameValuePairs.isEmpty()) {
subject = (String) nameValuePairs.get("subject");
body = (String) nameValuePairs.get("body");
subject = nameValuePairs.get("subject");
body = nameValuePairs.get("body");
querySyntax = true;
}
@ -71,8 +71,8 @@ final class SMSMMSResultParser extends ResultParser {
int lastComma = -1;
int comma;
Vector numbers = new Vector(1);
Vector vias = new Vector(1);
List<String> numbers = new ArrayList<String>(1);
List<String> vias = new ArrayList<String>(1);
while ((comma = smsURIWithoutQuery.indexOf(',', lastComma + 1)) > lastComma) {
String numberPart = smsURIWithoutQuery.substring(lastComma + 1, comma);
addNumberVia(numbers, vias, numberPart);
@ -80,16 +80,21 @@ final class SMSMMSResultParser extends ResultParser {
}
addNumberVia(numbers, vias, smsURIWithoutQuery.substring(lastComma + 1));
return new SMSParsedResult(toStringArray(numbers), toStringArray(vias), subject, body);
return new SMSParsedResult(numbers.toArray(new String[numbers.size()]),
vias.toArray(new String[vias.size()]),
subject,
body);
}
private static void addNumberVia(Vector numbers, Vector vias, String numberPart) {
private static void addNumberVia(Collection<String> numbers,
Collection<String> vias,
String numberPart) {
int numberEnd = numberPart.indexOf(';');
if (numberEnd < 0) {
numbers.addElement(numberPart);
vias.addElement(null);
numbers.add(numberPart);
vias.add(null);
} else {
numbers.addElement(numberPart.substring(0, numberEnd));
numbers.add(numberPart.substring(0, numberEnd));
String maybeVia = numberPart.substring(numberEnd + 1);
String via;
if (maybeVia.startsWith("via=")) {
@ -97,7 +102,7 @@ final class SMSMMSResultParser extends ResultParser {
} else {
via = null;
}
vias.addElement(via);
vias.add(via);
}
}

View file

@ -26,7 +26,10 @@ public final class SMSParsedResult extends ParsedResult {
private final String subject;
private final String body;
public SMSParsedResult(String number, String via, String subject, String body) {
public SMSParsedResult(String number,
String via,
String subject,
String body) {
super(ParsedResultType.SMS);
this.numbers = new String[] {number};
this.vias = new String[] {via};
@ -34,7 +37,10 @@ public final class SMSParsedResult extends ParsedResult {
this.body = body;
}
public SMSParsedResult(String[] numbers, String[] vias, String subject, String body) {
public SMSParsedResult(String[] numbers,
String[] vias,
String subject,
String body) {
super(ParsedResultType.SMS);
this.numbers = numbers;
this.vias = vias;
@ -43,7 +49,7 @@ public final class SMSParsedResult extends ParsedResult {
}
public String getSMSURI() {
StringBuffer result = new StringBuffer();
StringBuilder result = new StringBuilder();
result.append("sms:");
boolean first = true;
for (int i = 0; i < numbers.length; i++) {
@ -93,8 +99,9 @@ public final class SMSParsedResult extends ParsedResult {
return body;
}
@Override
public String getDisplayResult() {
StringBuffer result = new StringBuffer(100);
StringBuilder result = new StringBuilder(100);
maybeAppend(numbers, result);
maybeAppend(subject, result);
maybeAppend(body, result);

View file

@ -20,7 +20,7 @@ import com.google.zxing.Result;
/**
* <p>Parses an "smsto:" URI result, whose format is not standardized but appears to be like:
* <code>smsto:number(:body)</code>.</p>
* {@code smsto:number(:body)}.</p>
*
* <p>This actually also parses URIs starting with "smsto:", "mmsto:", "SMSTO:", and
* "MMSTO:", and treats them all the same way, and effectively converts them to an "sms:" URI
@ -28,12 +28,10 @@ import com.google.zxing.Result;
*
* @author Sean Owen
*/
final class SMSTOMMSTOResultParser extends ResultParser {
public final class SMSTOMMSTOResultParser extends ResultParser {
private SMSTOMMSTOResultParser() {
}
public static SMSParsedResult parse(Result result) {
@Override
public SMSParsedResult parse(Result result) {
String rawText = result.getText();
if (!(rawText.startsWith("smsto:") || rawText.startsWith("SMSTO:") ||
rawText.startsWith("mmsto:") || rawText.startsWith("MMSTO:"))) {

Some files were not shown because too many files have changed in this diff Show more