mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
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:
parent
8683a96213
commit
db60385d7d
11
README
11
README
|
@ -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]
|
|
|
@ -28,8 +28,8 @@
|
||||||
<mkdir dir="build"/>
|
<mkdir dir="build"/>
|
||||||
<javac srcdir="src"
|
<javac srcdir="src"
|
||||||
destdir="build"
|
destdir="build"
|
||||||
source="1.5"
|
source="6"
|
||||||
target="1.5"
|
target="6"
|
||||||
optimize="true"
|
optimize="true"
|
||||||
debug="true"
|
debug="true"
|
||||||
deprecation="true"
|
deprecation="true"
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<artifactId>android-integration</artifactId>
|
<artifactId>android-integration</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>ZXing Android Integration lib</name>
|
<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>
|
<description>Integration helper classes for Android applications wanting to create/scan bar codes</description>
|
||||||
<url>http://code.google.com/p/zxing/</url>
|
<url>http://code.google.com/p/zxing/</url>
|
||||||
<inceptionYear>2007</inceptionYear>
|
<inceptionYear>2007</inceptionYear>
|
||||||
|
|
|
@ -103,7 +103,7 @@ public final class IntentIntegrator {
|
||||||
static {
|
static {
|
||||||
Method temp;
|
Method temp;
|
||||||
try {
|
try {
|
||||||
temp = Intent.class.getMethod("setPackage", new Class[] {String.class});
|
temp = Intent.class.getMethod("setPackage", String.class);
|
||||||
} catch (NoSuchMethodException nsme) {
|
} catch (NoSuchMethodException nsme) {
|
||||||
temp = null;
|
temp = null;
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,7 @@ public final class IntentIntegrator {
|
||||||
downloadDialog.setTitle(stringTitle);
|
downloadDialog.setTitle(stringTitle);
|
||||||
downloadDialog.setMessage(stringMessage);
|
downloadDialog.setMessage(stringMessage);
|
||||||
downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
|
downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
Uri uri = Uri.parse("market://search?q=pname:" + PACKAGE);
|
Uri uri = Uri.parse("market://search?q=pname:" + PACKAGE);
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
|
@ -224,6 +225,7 @@ public final class IntentIntegrator {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
|
downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {}
|
public void onClick(DialogInterface dialogInterface, int i) {}
|
||||||
});
|
});
|
||||||
return downloadDialog.show();
|
return downloadDialog.show();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<link rel="stylesheet" href="../style.css" type="text/css"/>
|
<link rel="stylesheet" href="../style.css" type="text/css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>Barcode Scanner continuously scans a square region shown on your screen — 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>
|
phone so the barcode is completely inside the viewfinder rectangle:</p>
|
||||||
<p style="text-align:center">
|
<p style="text-align:center">
|
||||||
<img src="../images/demo-yes.png" alt="Yes"/> <img src="../images/demo-no.png" alt="No"/>
|
<img src="../images/demo-yes.png" alt="Yes"/> <img src="../images/demo-no.png" alt="No"/>
|
||||||
|
|
|
@ -88,6 +88,7 @@ public final class BeepManager {
|
||||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||||
// When the beep has finished playing, rewind to queue up another one.
|
// When the beep has finished playing, rewind to queue up another one.
|
||||||
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
||||||
|
@Override
|
||||||
public void onCompletion(MediaPlayer player) {
|
public void onCompletion(MediaPlayer player) {
|
||||||
player.seekTo(0);
|
player.seekTo(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,11 +63,11 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
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
|
* 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_CODE_PLACEHOLDER = "{CODE}";
|
||||||
private static final String RETURN_URL_PARAM = "ret";
|
private static final String RETURN_URL_PARAM = "ret";
|
||||||
|
|
||||||
private static final Set<ResultMetadataType> DISPLAYABLE_METADATA_TYPES;
|
private static final Set<ResultMetadataType> DISPLAYABLE_METADATA_TYPES =
|
||||||
static {
|
EnumSet.of(ResultMetadataType.ISSUE_NUMBER,
|
||||||
DISPLAYABLE_METADATA_TYPES = new HashSet<ResultMetadataType>(5);
|
ResultMetadataType.SUGGESTED_PRICE,
|
||||||
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.ISSUE_NUMBER);
|
ResultMetadataType.ERROR_CORRECTION_LEVEL,
|
||||||
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.SUGGESTED_PRICE);
|
ResultMetadataType.POSSIBLE_COUNTRY);
|
||||||
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.ERROR_CORRECTION_LEVEL);
|
|
||||||
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.POSSIBLE_COUNTRY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum Source {
|
private enum Source {
|
||||||
NATIVE_APP_INTENT,
|
NATIVE_APP_INTENT,
|
||||||
|
@ -123,7 +120,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
|
||||||
private Source source;
|
private Source source;
|
||||||
private String sourceUrl;
|
private String sourceUrl;
|
||||||
private String returnUrlTemplate;
|
private String returnUrlTemplate;
|
||||||
private Vector<BarcodeFormat> decodeFormats;
|
private Collection<BarcodeFormat> decodeFormats;
|
||||||
private String characterSet;
|
private String characterSet;
|
||||||
private String versionName;
|
private String versionName;
|
||||||
private HistoryManager historyManager;
|
private HistoryManager historyManager;
|
||||||
|
@ -132,6 +129,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
|
||||||
|
|
||||||
private final DialogInterface.OnClickListener aboutListener =
|
private final DialogInterface.OnClickListener aboutListener =
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.zxing_url)));
|
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.zxing_url)));
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||||
|
@ -313,33 +311,25 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case SHARE_ID: {
|
case SHARE_ID:
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
|
||||||
intent.setClassName(this, ShareActivity.class.getName());
|
intent.setClassName(this, ShareActivity.class.getName());
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
break;
|
break;
|
||||||
}
|
case HISTORY_ID:
|
||||||
case HISTORY_ID: {
|
|
||||||
AlertDialog historyAlert = historyManager.buildAlert();
|
AlertDialog historyAlert = historyManager.buildAlert();
|
||||||
historyAlert.show();
|
historyAlert.show();
|
||||||
break;
|
break;
|
||||||
}
|
case SETTINGS_ID:
|
||||||
case SETTINGS_ID: {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
|
||||||
intent.setClassName(this, PreferencesActivity.class.getName());
|
intent.setClassName(this, PreferencesActivity.class.getName());
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
break;
|
break;
|
||||||
}
|
case HELP_ID:
|
||||||
case HELP_ID: {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
|
||||||
intent.setClassName(this, HelpActivity.class.getName());
|
intent.setClassName(this, HelpActivity.class.getName());
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ABOUT_ID:
|
case ABOUT_ID:
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(getString(R.string.title_about) + versionName);
|
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);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
if (holder == null) {
|
if (holder == null) {
|
||||||
Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
|
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) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
hasSurface = false;
|
hasSurface = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
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);
|
paint.setStrokeWidth(4.0f);
|
||||||
drawLine(canvas, paint, points[0], points[1]);
|
drawLine(canvas, paint, points[0], points[1]);
|
||||||
} else if (points.length == 4 &&
|
} else if (points.length == 4 &&
|
||||||
(rawResult.getBarcodeFormat().equals(BarcodeFormat.UPC_A) ||
|
(rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A ||
|
||||||
rawResult.getBarcodeFormat().equals(BarcodeFormat.EAN_13))) {
|
rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
|
||||||
// Hacky special case -- draw two lines, for the barcode and metadata
|
// Hacky special case -- draw two lines, for the barcode and metadata
|
||||||
drawLine(canvas, paint, points[0], points[1]);
|
drawLine(canvas, paint, points[0], points[1]);
|
||||||
drawLine(canvas, paint, points[2], points[3]);
|
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);
|
View metaTextViewLabel = findViewById(R.id.meta_text_view_label);
|
||||||
metaTextView.setVisibility(View.GONE);
|
metaTextView.setVisibility(View.GONE);
|
||||||
metaTextViewLabel.setVisibility(View.GONE);
|
metaTextViewLabel.setVisibility(View.GONE);
|
||||||
Map<ResultMetadataType,Object> metadata =
|
Map<ResultMetadataType,Object> metadata = rawResult.getResultMetadata();
|
||||||
(Map<ResultMetadataType,Object>) rawResult.getResultMetadata();
|
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
StringBuilder metadataText = new StringBuilder(20);
|
StringBuilder metadataText = new StringBuilder(20);
|
||||||
for (Map.Entry<ResultMetadataType,Object> entry : metadata.entrySet()) {
|
for (Map.Entry<ResultMetadataType,Object> entry : metadata.entrySet()) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.Log;
|
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.
|
* This class handles all the messaging which comprises the state machine for capture.
|
||||||
|
@ -50,7 +50,7 @@ public final class CaptureActivityHandler extends Handler {
|
||||||
DONE
|
DONE
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureActivityHandler(CaptureActivity activity, Vector<BarcodeFormat> decodeFormats,
|
CaptureActivityHandler(CaptureActivity activity, Collection<BarcodeFormat> decodeFormats,
|
||||||
String characterSet) {
|
String characterSet) {
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
decodeThread = new DecodeThread(activity, decodeFormats, characterSet,
|
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);
|
Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
|
||||||
quit.sendToTarget();
|
quit.sendToTarget();
|
||||||
try {
|
try {
|
||||||
decodeThread.join();
|
// Wait at most half a second; should be enough time, and onPause() will timeout quickly
|
||||||
|
decodeThread.join(500L);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
package com.google.zxing.client.android;
|
package com.google.zxing.client.android;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -29,32 +30,26 @@ final class DecodeFormatManager {
|
||||||
|
|
||||||
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
||||||
|
|
||||||
static final Vector<BarcodeFormat> PRODUCT_FORMATS;
|
static final Collection<BarcodeFormat> PRODUCT_FORMATS;
|
||||||
static final Vector<BarcodeFormat> ONE_D_FORMATS;
|
static final Collection<BarcodeFormat> ONE_D_FORMATS;
|
||||||
static final Vector<BarcodeFormat> QR_CODE_FORMATS;
|
static final Collection<BarcodeFormat> QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
|
||||||
static final Vector<BarcodeFormat> DATA_MATRIX_FORMATS;
|
static final Collection<BarcodeFormat> DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);
|
||||||
static {
|
static {
|
||||||
PRODUCT_FORMATS = new Vector<BarcodeFormat>(5);
|
PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A,
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.UPC_A);
|
BarcodeFormat.UPC_E,
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.UPC_E);
|
BarcodeFormat.EAN_13,
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.EAN_13);
|
BarcodeFormat.EAN_8,
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.EAN_8);
|
BarcodeFormat.RSS_14);
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.RSS_14);
|
ONE_D_FORMATS = EnumSet.of(BarcodeFormat.CODE_39,
|
||||||
ONE_D_FORMATS = new Vector<BarcodeFormat>(PRODUCT_FORMATS.size() + 4);
|
BarcodeFormat.CODE_93,
|
||||||
|
BarcodeFormat.CODE_128,
|
||||||
|
BarcodeFormat.ITF);
|
||||||
ONE_D_FORMATS.addAll(PRODUCT_FORMATS);
|
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() {}
|
private DecodeFormatManager() {}
|
||||||
|
|
||||||
static Vector<BarcodeFormat> parseDecodeFormats(Intent intent) {
|
static Collection<BarcodeFormat> parseDecodeFormats(Intent intent) {
|
||||||
List<String> scanFormats = null;
|
List<String> scanFormats = null;
|
||||||
String scanFormatsString = intent.getStringExtra(Intents.Scan.FORMATS);
|
String scanFormatsString = intent.getStringExtra(Intents.Scan.FORMATS);
|
||||||
if (scanFormatsString != null) {
|
if (scanFormatsString != null) {
|
||||||
|
@ -63,7 +58,7 @@ final class DecodeFormatManager {
|
||||||
return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE));
|
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);
|
List<String> formats = inputUri.getQueryParameters(Intents.Scan.FORMATS);
|
||||||
if (formats != null && formats.size() == 1 && formats.get(0) != null){
|
if (formats != null && formats.size() == 1 && formats.get(0) != null){
|
||||||
formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
|
formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
|
||||||
|
@ -71,10 +66,10 @@ final class DecodeFormatManager {
|
||||||
return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE));
|
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) {
|
String decodeMode) {
|
||||||
if (scanFormats != null) {
|
if (scanFormats != null) {
|
||||||
Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>();
|
Collection<BarcodeFormat> formats = EnumSet.noneOf(BarcodeFormat.class);
|
||||||
try {
|
try {
|
||||||
for (String format : scanFormats) {
|
for (String format : scanFormats) {
|
||||||
formats.add(BarcodeFormat.valueOf(format));
|
formats.add(BarcodeFormat.valueOf(format));
|
||||||
|
|
|
@ -30,7 +30,7 @@ import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Map;
|
||||||
|
|
||||||
final class DecodeHandler extends Handler {
|
final class DecodeHandler extends Handler {
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ final class DecodeHandler extends Handler {
|
||||||
private final MultiFormatReader multiFormatReader;
|
private final MultiFormatReader multiFormatReader;
|
||||||
private boolean running = true;
|
private boolean running = true;
|
||||||
|
|
||||||
DecodeHandler(CaptureActivity activity, Hashtable<DecodeHintType, Object> hints) {
|
DecodeHandler(CaptureActivity activity, Map<DecodeHintType,Object> hints) {
|
||||||
multiFormatReader = new MultiFormatReader();
|
multiFormatReader = new MultiFormatReader();
|
||||||
multiFormatReader.setHints(hints);
|
multiFormatReader.setHints(hints);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
|
|
|
@ -25,8 +25,10 @@ import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Collection;
|
||||||
import java.util.Vector;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,24 +41,24 @@ final class DecodeThread extends Thread {
|
||||||
public static final String BARCODE_BITMAP = "barcode_bitmap";
|
public static final String BARCODE_BITMAP = "barcode_bitmap";
|
||||||
|
|
||||||
private final CaptureActivity activity;
|
private final CaptureActivity activity;
|
||||||
private final Hashtable<DecodeHintType, Object> hints;
|
private final Map<DecodeHintType,Object> hints;
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
private final CountDownLatch handlerInitLatch;
|
private final CountDownLatch handlerInitLatch;
|
||||||
|
|
||||||
DecodeThread(CaptureActivity activity,
|
DecodeThread(CaptureActivity activity,
|
||||||
Vector<BarcodeFormat> decodeFormats,
|
Collection<BarcodeFormat> decodeFormats,
|
||||||
String characterSet,
|
String characterSet,
|
||||||
ResultPointCallback resultPointCallback) {
|
ResultPointCallback resultPointCallback) {
|
||||||
|
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
handlerInitLatch = new CountDownLatch(1);
|
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.
|
// The prefs can't change while the thread is running, so pick them up once here.
|
||||||
if (decodeFormats == null || decodeFormats.isEmpty()) {
|
if (decodeFormats == null || decodeFormats.isEmpty()) {
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||||
decodeFormats = new Vector<BarcodeFormat>();
|
decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
|
||||||
if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, true)) {
|
if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, true)) {
|
||||||
decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
|
decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,14 +33,17 @@ public final class FinishListener
|
||||||
this.activityToFinish = activityToFinish;
|
this.activityToFinish = activityToFinish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onCancel(DialogInterface dialogInterface) {
|
public void onCancel(DialogInterface dialogInterface) {
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
activityToFinish.finish();
|
activityToFinish.finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,12 +64,14 @@ public final class HelpActivity extends Activity {
|
||||||
private Button backButton;
|
private Button backButton;
|
||||||
|
|
||||||
private final Button.OnClickListener backListener = new Button.OnClickListener() {
|
private final Button.OnClickListener backListener = new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
webView.goBack();
|
webView.goBack();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final Button.OnClickListener doneListener = new Button.OnClickListener() {
|
private final Button.OnClickListener doneListener = new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
@ -77,6 +79,7 @@ public final class HelpActivity extends Activity {
|
||||||
|
|
||||||
private final DialogInterface.OnClickListener groupsListener =
|
private final DialogInterface.OnClickListener groupsListener =
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, BUGGY_URI);
|
Intent intent = new Intent(Intent.ACTION_VIEW, BUGGY_URI);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -41,7 +42,7 @@ public final class HttpHelper {
|
||||||
|
|
||||||
private HttpHelper() {
|
private HttpHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ContentType {
|
public enum ContentType {
|
||||||
/** HTML-like content type, including HTML, XHTML, etc. */
|
/** HTML-like content type, including HTML, XHTML, etc. */
|
||||||
HTML,
|
HTML,
|
||||||
|
@ -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");
|
String contentTypeHeader = connection.getHeaderField("Content-Type");
|
||||||
if (contentTypeHeader != null) {
|
if (contentTypeHeader != null) {
|
||||||
int charsetStart = contentTypeHeader.indexOf("charset=");
|
int charsetStart = contentTypeHeader.indexOf("charset=");
|
||||||
|
@ -101,7 +102,7 @@ public final class HttpHelper {
|
||||||
return "UTF-8";
|
return "UTF-8";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String consume(HttpURLConnection connection) throws IOException {
|
private static String consume(URLConnection connection) throws IOException {
|
||||||
String encoding = getEncoding(connection);
|
String encoding = getEncoding(connection);
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
InputStream in = connection.getInputStream();
|
InputStream in = connection.getInputStream();
|
||||||
|
|
|
@ -40,7 +40,7 @@ final class InactivityTimer {
|
||||||
Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
|
Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
|
||||||
private final Activity activity;
|
private final Activity activity;
|
||||||
private ScheduledFuture<?> inactivityFuture = null;
|
private ScheduledFuture<?> inactivityFuture = null;
|
||||||
private final PowerStatusReceiver powerStatusReceiver = new PowerStatusReceiver();
|
private final BroadcastReceiver powerStatusReceiver = new PowerStatusReceiver();
|
||||||
|
|
||||||
InactivityTimer(Activity activity) {
|
InactivityTimer(Activity activity) {
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
|
@ -61,17 +61,20 @@ final class InactivityTimer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPause(){
|
public void onPause() {
|
||||||
|
cancel();
|
||||||
activity.unregisterReceiver(powerStatusReceiver);
|
activity.unregisterReceiver(powerStatusReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onResume(){
|
public void onResume(){
|
||||||
activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||||
|
onActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancel() {
|
private void cancel() {
|
||||||
if (inactivityFuture != null) {
|
ScheduledFuture<?> future = inactivityFuture;
|
||||||
inactivityFuture.cancel(true);
|
if (future != null) {
|
||||||
|
future.cancel(true);
|
||||||
inactivityFuture = null;
|
inactivityFuture = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,6 +85,7 @@ final class InactivityTimer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class DaemonThreadFactory implements ThreadFactory {
|
private static final class DaemonThreadFactory implements ThreadFactory {
|
||||||
|
@Override
|
||||||
public Thread newThread(Runnable runnable) {
|
public Thread newThread(Runnable runnable) {
|
||||||
Thread thread = new Thread(runnable);
|
Thread thread = new Thread(runnable);
|
||||||
thread.setDaemon(true);
|
thread.setDaemon(true);
|
||||||
|
@ -95,9 +99,8 @@ final class InactivityTimer {
|
||||||
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
|
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
|
||||||
// 0 indicates that we're on battery
|
// 0 indicates that we're on battery
|
||||||
// In Android 2.0+, use BatteryManager.EXTRA_PLUGGED
|
// In Android 2.0+, use BatteryManager.EXTRA_PLUGGED
|
||||||
if (intent.getIntExtra("plugged", -1) == 0) {
|
int batteryPlugged = intent.getIntExtra("plugged", -1);
|
||||||
InactivityTimer.this.onActivity();
|
if (batteryPlugged > 0) {
|
||||||
} else {
|
|
||||||
InactivityTimer.this.cancel();
|
InactivityTimer.this.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ public final class PreferencesActivity extends PreferenceActivity
|
||||||
disableLastCheckedPref();
|
disableLastCheckedPref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||||
disableLastCheckedPref();
|
disableLastCheckedPref();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ final class ViewfinderResultPointCallback implements ResultPointCallback {
|
||||||
this.viewfinderView = viewfinderView;
|
this.viewfinderView = viewfinderView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void foundPossibleResultPoint(ResultPoint point) {
|
public void foundPossibleResultPoint(ResultPoint point) {
|
||||||
viewfinderView.addPossibleResultPoint(point);
|
viewfinderView.addPossibleResultPoint(point);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ final class BrowseBookListener implements AdapterView.OnItemClickListener {
|
||||||
this.items = items;
|
this.items = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
|
||||||
if (position < 1) {
|
if (position < 1) {
|
||||||
// Clicked header, ignore it
|
// Clicked header, ignore it
|
||||||
|
|
|
@ -82,12 +82,14 @@ public final class SearchBookContentsActivity extends Activity {
|
||||||
};
|
};
|
||||||
|
|
||||||
private final Button.OnClickListener buttonListener = new Button.OnClickListener() {
|
private final Button.OnClickListener buttonListener = new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
launchSearch();
|
launchSearch();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final View.OnKeyListener keyListener = new View.OnKeyListener() {
|
private final View.OnKeyListener keyListener = new View.OnKeyListener() {
|
||||||
|
@Override
|
||||||
public boolean onKey(View view, int keyCode, KeyEvent event) {
|
public boolean onKey(View view, int keyCode, KeyEvent event) {
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
|
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
launchSearch();
|
launchSearch();
|
||||||
|
|
|
@ -35,6 +35,7 @@ final class AutoFocusCallback implements Camera.AutoFocusCallback {
|
||||||
this.autoFocusMessage = autoFocusMessage;
|
this.autoFocusMessage = autoFocusMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onAutoFocus(boolean success, Camera camera) {
|
public void onAutoFocus(boolean success, Camera camera) {
|
||||||
if (autoFocusHandler != null) {
|
if (autoFocusHandler != null) {
|
||||||
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
|
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
|
||||||
|
|
|
@ -41,6 +41,7 @@ final class PreviewCallback implements Camera.PreviewCallback {
|
||||||
this.previewMessage = previewMessage;
|
this.previewMessage = previewMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onPreviewFrame(byte[] data, Camera camera) {
|
public void onPreviewFrame(byte[] data, Camera camera) {
|
||||||
Point cameraResolution = configManager.getCameraResolution();
|
Point cameraResolution = configManager.getCameraResolution();
|
||||||
if (!useOneShotPreviewCallback) {
|
if (!useOneShotPreviewCallback) {
|
||||||
|
|
|
@ -42,8 +42,9 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashSet;
|
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
|
* 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
|
// Ignore it then
|
||||||
format = null;
|
format = null;
|
||||||
}
|
}
|
||||||
if (format == null || BarcodeFormat.QR_CODE.equals(format)) {
|
if (format == null || format == BarcodeFormat.QR_CODE) {
|
||||||
String type = intent.getStringExtra(Intents.Encode.TYPE);
|
String type = intent.getStringExtra(Intents.Encode.TYPE);
|
||||||
if (type == null || type.length() == 0) {
|
if (type == null || type.length() == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -379,10 +380,10 @@ final class QRCodeEncoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap encodeAsBitmap() throws WriterException {
|
Bitmap encodeAsBitmap() throws WriterException {
|
||||||
Hashtable<EncodeHintType,Object> hints = null;
|
Map<EncodeHintType,Object> hints = null;
|
||||||
String encoding = guessAppropriateEncoding(contents);
|
String encoding = guessAppropriateEncoding(contents);
|
||||||
if (encoding != null) {
|
if (encoding != null) {
|
||||||
hints = new Hashtable<EncodeHintType,Object>(2);
|
hints = new EnumMap<EncodeHintType,Object>(EncodeHintType.class);
|
||||||
hints.put(EncodeHintType.CHARACTER_SET, encoding);
|
hints.put(EncodeHintType.CHARACTER_SET, encoding);
|
||||||
}
|
}
|
||||||
MultiFormatWriter writer = new MultiFormatWriter();
|
MultiFormatWriter writer = new MultiFormatWriter();
|
||||||
|
|
|
@ -46,6 +46,7 @@ final class HistoryClickListener implements DialogInterface.OnClickListener {
|
||||||
this.items = items;
|
this.items = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
if (i == items.size()) {
|
if (i == items.size()) {
|
||||||
// Share history.
|
// Share history.
|
||||||
|
@ -71,6 +72,7 @@ final class HistoryClickListener implements DialogInterface.OnClickListener {
|
||||||
builder.setMessage(R.string.msg_sure);
|
builder.setMessage(R.string.msg_sure);
|
||||||
builder.setCancelable(true);
|
builder.setCancelable(true);
|
||||||
builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface2, int i2) {
|
public void onClick(DialogInterface dialogInterface2, int i2) {
|
||||||
historyManager.clearHistory();
|
historyManager.clearHistory();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.text.DateFormat;
|
||||||
import java.text.ParsePosition;
|
import java.text.ParsePosition;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles address book entries.
|
* Handles address book entries.
|
||||||
|
@ -39,10 +40,10 @@ import java.util.Date;
|
||||||
public final class AddressBookResultHandler extends ResultHandler {
|
public final class AddressBookResultHandler extends ResultHandler {
|
||||||
|
|
||||||
private static final DateFormat[] DATE_FORMATS = {
|
private static final DateFormat[] DATE_FORMATS = {
|
||||||
new SimpleDateFormat("yyyyMMdd"),
|
new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH),
|
||||||
new SimpleDateFormat("yyyyMMdd'T'HHmmss"),
|
new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH),
|
||||||
new SimpleDateFormat("yyyy-MM-dd"),
|
new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH),
|
||||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"),
|
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH),
|
||||||
};
|
};
|
||||||
|
|
||||||
private final boolean[] fields;
|
private final boolean[] fields;
|
||||||
|
@ -167,7 +168,7 @@ public final class AddressBookResultHandler extends ResultHandler {
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getDisplayContents() {
|
public CharSequence getDisplayContents() {
|
||||||
AddressBookParsedResult result = (AddressBookParsedResult) getResult();
|
AddressBookParsedResult result = (AddressBookParsedResult) getResult();
|
||||||
StringBuffer contents = new StringBuffer(100);
|
StringBuilder contents = new StringBuilder(100);
|
||||||
ParsedResult.maybeAppend(result.getNames(), contents);
|
ParsedResult.maybeAppend(result.getNames(), contents);
|
||||||
int namesLength = contents.length();
|
int namesLength = contents.length();
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles calendar entries encoded in QR Codes.
|
* Handles calendar entries encoded in QR Codes.
|
||||||
|
@ -36,8 +37,8 @@ import java.util.GregorianCalendar;
|
||||||
*/
|
*/
|
||||||
public final class CalendarResultHandler extends ResultHandler {
|
public final class CalendarResultHandler extends ResultHandler {
|
||||||
|
|
||||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
|
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
|
||||||
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 int[] buttons = {
|
private static final int[] buttons = {
|
||||||
R.string.button_add_calendar
|
R.string.button_add_calendar
|
||||||
|
@ -72,7 +73,7 @@ public final class CalendarResultHandler extends ResultHandler {
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getDisplayContents() {
|
public CharSequence getDisplayContents() {
|
||||||
CalendarParsedResult calResult = (CalendarParsedResult) getResult();
|
CalendarParsedResult calResult = (CalendarParsedResult) getResult();
|
||||||
StringBuffer result = new StringBuffer(100);
|
StringBuilder result = new StringBuilder(100);
|
||||||
ParsedResult.maybeAppend(calResult.getSummary(), result);
|
ParsedResult.maybeAppend(calResult.getSummary(), result);
|
||||||
appendTime(calResult.getStart(), result);
|
appendTime(calResult.getStart(), result);
|
||||||
|
|
||||||
|
@ -89,7 +90,7 @@ public final class CalendarResultHandler extends ResultHandler {
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void appendTime(String when, StringBuffer result) {
|
private static void appendTime(String when, StringBuilder result) {
|
||||||
if (when.length() == 8) {
|
if (when.length() == 8) {
|
||||||
// Show only year/month/day
|
// Show only year/month/day
|
||||||
Date date;
|
Date date;
|
||||||
|
|
|
@ -42,6 +42,7 @@ public final class ISBNResultHandler extends ResultHandler {
|
||||||
public ISBNResultHandler(Activity activity, ParsedResult result, Result rawResult) {
|
public ISBNResultHandler(Activity activity, ParsedResult result, Result rawResult) {
|
||||||
super(activity, result, rawResult);
|
super(activity, result, rawResult);
|
||||||
showGoogleShopperButton(new View.OnClickListener() {
|
showGoogleShopperButton(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();
|
ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();
|
||||||
openGoogleShopper(isbnResult.getISBN());
|
openGoogleShopper(isbnResult.getISBN());
|
||||||
|
@ -62,6 +63,7 @@ public final class ISBNResultHandler extends ResultHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handleButtonPress(final int index) {
|
public void handleButtonPress(final int index) {
|
||||||
showNotOurResults(index, new AlertDialog.OnClickListener() {
|
showNotOurResults(index, new AlertDialog.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();
|
ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();
|
||||||
switch (index) {
|
switch (index) {
|
||||||
|
|
|
@ -41,6 +41,7 @@ public final class ProductResultHandler extends ResultHandler {
|
||||||
public ProductResultHandler(Activity activity, ParsedResult result, Result rawResult) {
|
public ProductResultHandler(Activity activity, ParsedResult result, Result rawResult) {
|
||||||
super(activity, result, rawResult);
|
super(activity, result, rawResult);
|
||||||
showGoogleShopperButton(new View.OnClickListener() {
|
showGoogleShopperButton(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
ProductParsedResult productResult = (ProductParsedResult) getResult();
|
ProductParsedResult productResult = (ProductParsedResult) getResult();
|
||||||
openGoogleShopper(productResult.getNormalizedProductID());
|
openGoogleShopper(productResult.getNormalizedProductID());
|
||||||
|
@ -61,6 +62,7 @@ public final class ProductResultHandler extends ResultHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handleButtonPress(final int index) {
|
public void handleButtonPress(final int index) {
|
||||||
showNotOurResults(index, new AlertDialog.OnClickListener() {
|
showNotOurResults(index, new AlertDialog.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
ProductParsedResult productResult = (ProductParsedResult) getResult();
|
ProductParsedResult productResult = (ProductParsedResult) getResult();
|
||||||
switch (index) {
|
switch (index) {
|
||||||
|
|
|
@ -34,6 +34,7 @@ public final class ResultButtonListener implements Button.OnClickListener {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
resultHandler.handleButtonPress(index);
|
resultHandler.handleButtonPress(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,11 @@ import android.view.View;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.ParsePosition;
|
import java.text.ParsePosition;
|
||||||
import java.text.SimpleDateFormat;
|
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
|
* 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;
|
private static final DateFormat DATE_FORMAT;
|
||||||
static {
|
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
|
// For dates without a time, for purposes of interacting with Android, the resulting timestamp
|
||||||
// needs to be midnight of that day in GMT. See:
|
// needs to be midnight of that day in GMT. See:
|
||||||
// http://code.google.com/p/android/issues/detail?id=8330
|
// http://code.google.com/p/android/issues/detail?id=8330
|
||||||
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
|
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_PACKAGE = "com.google.android.apps.shopper";
|
||||||
private static final String GOOGLE_SHOPPER_ACTIVITY = GOOGLE_SHOPPER_PACKAGE +
|
private static final String GOOGLE_SHOPPER_ACTIVITY = GOOGLE_SHOPPER_PACKAGE +
|
||||||
|
@ -105,6 +109,7 @@ public abstract class ResultHandler {
|
||||||
|
|
||||||
private final DialogInterface.OnClickListener shopperMarketListener =
|
private final DialogInterface.OnClickListener shopperMarketListener =
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int which) {
|
public void onClick(DialogInterface dialogInterface, int which) {
|
||||||
launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(MARKET_URI_PREFIX +
|
launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(MARKET_URI_PREFIX +
|
||||||
GOOGLE_SHOPPER_PACKAGE + MARKET_REFERRER_SUFFIX)));
|
GOOGLE_SHOPPER_PACKAGE + MARKET_REFERRER_SUFFIX)));
|
||||||
|
|
|
@ -18,7 +18,6 @@ package com.google.zxing.client.android.result;
|
||||||
|
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
import com.google.zxing.client.result.ParsedResult;
|
import com.google.zxing.client.result.ParsedResult;
|
||||||
import com.google.zxing.client.result.ParsedResultType;
|
|
||||||
import com.google.zxing.client.result.ResultParser;
|
import com.google.zxing.client.result.ResultParser;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
@ -34,33 +33,31 @@ public final class ResultHandlerFactory {
|
||||||
|
|
||||||
public static ResultHandler makeResultHandler(Activity activity, Result rawResult) {
|
public static ResultHandler makeResultHandler(Activity activity, Result rawResult) {
|
||||||
ParsedResult result = parseResult(rawResult);
|
ParsedResult result = parseResult(rawResult);
|
||||||
ParsedResultType type = result.getType();
|
switch (result.getType()) {
|
||||||
if (type.equals(ParsedResultType.ADDRESSBOOK)) {
|
case ADDRESSBOOK:
|
||||||
return new AddressBookResultHandler(activity, result);
|
return new AddressBookResultHandler(activity, result);
|
||||||
} else if (type.equals(ParsedResultType.EMAIL_ADDRESS)) {
|
case EMAIL_ADDRESS:
|
||||||
return new EmailAddressResultHandler(activity, result);
|
return new EmailAddressResultHandler(activity, result);
|
||||||
} else if (type.equals(ParsedResultType.PRODUCT)) {
|
case PRODUCT:
|
||||||
return new ProductResultHandler(activity, result, rawResult);
|
return new ProductResultHandler(activity, result, rawResult);
|
||||||
} else if (type.equals(ParsedResultType.URI)) {
|
case URI:
|
||||||
return new URIResultHandler(activity, result);
|
return new URIResultHandler(activity, result);
|
||||||
} else if (type.equals(ParsedResultType.WIFI)) {
|
case WIFI:
|
||||||
return new WifiResultHandler(activity, result);
|
return new WifiResultHandler(activity, result);
|
||||||
} else if (type.equals(ParsedResultType.TEXT)) {
|
case TEXT:
|
||||||
return new TextResultHandler(activity, result, rawResult);
|
return new TextResultHandler(activity, result, rawResult);
|
||||||
} else if (type.equals(ParsedResultType.GEO)) {
|
case GEO:
|
||||||
return new GeoResultHandler(activity, result);
|
return new GeoResultHandler(activity, result);
|
||||||
} else if (type.equals(ParsedResultType.TEL)) {
|
case TEL:
|
||||||
return new TelResultHandler(activity, result);
|
return new TelResultHandler(activity, result);
|
||||||
} else if (type.equals(ParsedResultType.SMS)) {
|
case SMS:
|
||||||
return new SMSResultHandler(activity, result);
|
return new SMSResultHandler(activity, result);
|
||||||
} else if (type.equals(ParsedResultType.CALENDAR)) {
|
case CALENDAR:
|
||||||
return new CalendarResultHandler(activity, result);
|
return new CalendarResultHandler(activity, result);
|
||||||
} else if (type.equals(ParsedResultType.ISBN)) {
|
case ISBN:
|
||||||
return new ISBNResultHandler(activity, result, rawResult);
|
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) {
|
private static ParsedResult parseResult(Result rawResult) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ public final class SMSResultHandler extends ResultHandler {
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getDisplayContents() {
|
public CharSequence getDisplayContents() {
|
||||||
SMSParsedResult smsResult = (SMSParsedResult) getResult();
|
SMSParsedResult smsResult = (SMSParsedResult) getResult();
|
||||||
StringBuffer contents = new StringBuffer(50);
|
StringBuilder contents = new StringBuilder(50);
|
||||||
String[] rawNumbers = smsResult.getNumbers();
|
String[] rawNumbers = smsResult.getNumbers();
|
||||||
String[] formattedNumbers = new String[rawNumbers.length];
|
String[] formattedNumbers = new String[rawNumbers.length];
|
||||||
for (int i = 0; i < rawNumbers.length; i++) {
|
for (int i = 0; i < rawNumbers.length; i++) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ public final class WifiResultHandler extends ResultHandler {
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getDisplayContents() {
|
public CharSequence getDisplayContents() {
|
||||||
WifiParsedResult wifiResult = (WifiParsedResult) getResult();
|
WifiParsedResult wifiResult = (WifiParsedResult) getResult();
|
||||||
StringBuffer contents = new StringBuffer(50);
|
StringBuilder contents = new StringBuilder(50);
|
||||||
String wifiLabel = parent.getString(R.string.wifi_ssid_label);
|
String wifiLabel = parent.getString(R.string.wifi_ssid_label);
|
||||||
ParsedResult.maybeAppend(wifiLabel + '\n' + wifiResult.getSsid(), contents);
|
ParsedResult.maybeAppend(wifiLabel + '\n' + wifiResult.getSsid(), contents);
|
||||||
String typeLabel = parent.getString(R.string.wifi_type_label);
|
String typeLabel = parent.getString(R.string.wifi_type_label);
|
||||||
|
|
|
@ -34,6 +34,7 @@ final class KillerCallable implements Callable<Void> {
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Void call() throws ExecutionException, InterruptedException {
|
public Void call() throws ExecutionException, InterruptedException {
|
||||||
try {
|
try {
|
||||||
future.get(timeout, unit);
|
future.get(timeout, unit);
|
||||||
|
|
|
@ -48,6 +48,7 @@ public abstract class SupplementalInfoRetriever implements Callable<Void> {
|
||||||
private static synchronized ExecutorService getExecutorService() {
|
private static synchronized ExecutorService getExecutorService() {
|
||||||
if (executorInstance == null) {
|
if (executorInstance == null) {
|
||||||
executorInstance = Executors.newCachedThreadPool(new ThreadFactory() {
|
executorInstance = Executors.newCachedThreadPool(new ThreadFactory() {
|
||||||
|
@Override
|
||||||
public Thread newThread(Runnable r) {
|
public Thread newThread(Runnable r) {
|
||||||
Thread t = new Thread(r);
|
Thread t = new Thread(r);
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
|
@ -95,6 +96,7 @@ public abstract class SupplementalInfoRetriever implements Callable<Void> {
|
||||||
this.historyManager = historyManager;
|
this.historyManager = historyManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final Void call() throws IOException, InterruptedException {
|
public final Void call() throws IOException, InterruptedException {
|
||||||
retrieveSupplementalInfo();
|
retrieveSupplementalInfo();
|
||||||
return null;
|
return null;
|
||||||
|
@ -138,6 +140,7 @@ public abstract class SupplementalInfoRetriever implements Callable<Void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.post(new Runnable() {
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
textView.append(content);
|
textView.append(content);
|
||||||
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
|
|
@ -39,31 +39,35 @@ final class BookmarkAdapter extends BaseAdapter {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final Cursor cursor;
|
private final Cursor cursor;
|
||||||
|
|
||||||
public BookmarkAdapter(Context context, Cursor cursor) {
|
BookmarkAdapter(Context context, Cursor cursor) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.cursor = cursor;
|
this.cursor = cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return cursor.getCount();
|
return cursor.getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Object getItem(int index) {
|
public Object getItem(int index) {
|
||||||
// Not used, so no point in retrieving it.
|
// Not used, so no point in retrieving it.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getItemId(int index) {
|
public long getItemId(int index) {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public View getView(int index, View view, ViewGroup viewGroup) {
|
public View getView(int index, View view, ViewGroup viewGroup) {
|
||||||
LinearLayout layout;
|
LinearLayout layout;
|
||||||
if (!(view instanceof LinearLayout)) {
|
if (view instanceof LinearLayout) {
|
||||||
|
layout = (LinearLayout) view;
|
||||||
|
} else {
|
||||||
LayoutInflater factory = LayoutInflater.from(context);
|
LayoutInflater factory = LayoutInflater.from(context);
|
||||||
layout = (LinearLayout) factory.inflate(R.layout.bookmark_picker_list_item, viewGroup, false);
|
layout = (LinearLayout) factory.inflate(R.layout.bookmark_picker_list_item, viewGroup, false);
|
||||||
} else {
|
|
||||||
layout = (LinearLayout) view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.moveToPosition(index);
|
cursor.moveToPosition(index);
|
||||||
|
|
|
@ -98,6 +98,7 @@ final class LoadPackagesAsyncTask extends AsyncTask<List<String[]>, Void, List<S
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ByFirstStringComparator implements Comparator<String[]>, Serializable {
|
private static class ByFirstStringComparator implements Comparator<String[]>, Serializable {
|
||||||
|
@Override
|
||||||
public int compare(String[] o1, String[] o2) {
|
public int compare(String[] o1, String[] o2) {
|
||||||
return o1[0].compareTo(o2[0]);
|
return o1[0].compareTo(o2[0]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ public final class ShareActivity extends Activity {
|
||||||
private Button clipboardButton;
|
private Button clipboardButton;
|
||||||
|
|
||||||
private final Button.OnClickListener contactListener = new Button.OnClickListener() {
|
private final Button.OnClickListener contactListener = new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.People.CONTENT_URI);
|
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.People.CONTENT_URI);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
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() {
|
private final Button.OnClickListener bookmarkListener = new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent(Intent.ACTION_PICK);
|
Intent intent = new Intent(Intent.ACTION_PICK);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
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() {
|
private final Button.OnClickListener appListener = new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent(Intent.ACTION_PICK);
|
Intent intent = new Intent(Intent.ACTION_PICK);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
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() {
|
private final Button.OnClickListener clipboardListener = new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||||
// Should always be true, because we grey out the clipboard button in onResume() if it's empty
|
// 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() {
|
private final View.OnKeyListener textListener = new View.OnKeyListener() {
|
||||||
|
@Override
|
||||||
public boolean onKey(View view, int keyCode, KeyEvent event) {
|
public boolean onKey(View view, int keyCode, KeyEvent event) {
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
|
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
String text = ((TextView) view).getText().toString();
|
String text = ((TextView) view).getText().toString();
|
||||||
|
|
|
@ -41,6 +41,7 @@ public final class WifiConfigManager {
|
||||||
final String password,
|
final String password,
|
||||||
final String networkTypeString) {
|
final String networkTypeString) {
|
||||||
Runnable configureRunnable = new Runnable() {
|
Runnable configureRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Start WiFi, otherwise nothing will work
|
// Start WiFi, otherwise nothing will work
|
||||||
if (!wifiManager.isWifiEnabled()) {
|
if (!wifiManager.isWifiEnabled()) {
|
||||||
|
|
|
@ -27,12 +27,12 @@ import android.widget.TextView;
|
||||||
|
|
||||||
public final class BenchmarkActivity extends Activity {
|
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 PATH = "/sdcard/zxingbenchmark";
|
||||||
private static final String TAG = "ZXingBenchmark";
|
|
||||||
|
|
||||||
private Button mRunBenchmarkButton;
|
private Button runBenchmarkButton;
|
||||||
private TextView mTextView;
|
private TextView textView;
|
||||||
private BenchmarkThread mBenchmarkThread;
|
private BenchmarkThread benchmarkThread;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
|
@ -40,32 +40,33 @@ public final class BenchmarkActivity extends Activity {
|
||||||
|
|
||||||
setContentView(R.layout.benchmark);
|
setContentView(R.layout.benchmark);
|
||||||
|
|
||||||
mRunBenchmarkButton = (Button) findViewById(R.id.benchmark_run);
|
runBenchmarkButton = (Button) findViewById(R.id.benchmark_run);
|
||||||
mRunBenchmarkButton.setOnClickListener(mRunBenchmark);
|
runBenchmarkButton.setOnClickListener(runBenchmark);
|
||||||
mTextView = (TextView) findViewById(R.id.benchmark_help);
|
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) {
|
public void onClick(View v) {
|
||||||
if (mBenchmarkThread == null) {
|
if (benchmarkThread == null) {
|
||||||
mRunBenchmarkButton.setEnabled(false);
|
runBenchmarkButton.setEnabled(false);
|
||||||
mTextView.setText(R.string.benchmark_running);
|
textView.setText(R.string.benchmark_running);
|
||||||
mBenchmarkThread = new BenchmarkThread(BenchmarkActivity.this, PATH);
|
benchmarkThread = new BenchmarkThread(BenchmarkActivity.this, PATH);
|
||||||
mBenchmarkThread.start();
|
benchmarkThread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public final Handler mHandler = new Handler() {
|
final Handler handler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
switch (message.what) {
|
switch (message.what) {
|
||||||
case R.id.benchmark_done:
|
case R.id.benchmark_done:
|
||||||
handleBenchmarkDone(message);
|
handleBenchmarkDone(message);
|
||||||
mBenchmarkThread = null;
|
benchmarkThread = null;
|
||||||
mRunBenchmarkButton.setEnabled(true);
|
runBenchmarkButton.setEnabled(true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -86,7 +87,7 @@ public final class BenchmarkActivity extends Activity {
|
||||||
}
|
}
|
||||||
String totals = "TOTAL: Decoded " + count + " images in " + time + " us";
|
String totals = "TOTAL: Decoded " + count + " images in " + time + " us";
|
||||||
Log.v(TAG, totals);
|
Log.v(TAG, totals);
|
||||||
mTextView.setText(totals + "\n\n" + getString(R.string.benchmark_help));
|
textView.setText(totals + "\n\n" + getString(R.string.benchmark_help));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,49 +20,44 @@ import com.google.zxing.BarcodeFormat;
|
||||||
|
|
||||||
public final class BenchmarkItem {
|
public final class BenchmarkItem {
|
||||||
|
|
||||||
private final String mPath;
|
private final String path;
|
||||||
private final int[] mTimes;
|
private final int[] times;
|
||||||
private int mPosition;
|
private int position;
|
||||||
private boolean mDecoded;
|
private boolean decoded;
|
||||||
private BarcodeFormat mFormat;
|
private BarcodeFormat format;
|
||||||
|
|
||||||
public BenchmarkItem(String path, int runs) {
|
public BenchmarkItem(String path, int runs) {
|
||||||
if (runs <= 0) {
|
if (runs <= 0) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
mPath = path;
|
this.path = path;
|
||||||
mTimes = new int[runs];
|
times = new int[runs];
|
||||||
mPosition = 0;
|
position = 0;
|
||||||
mDecoded = false;
|
decoded = false;
|
||||||
mFormat = null;
|
format = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addResult(int microseconds) {
|
public void addResult(int microseconds) {
|
||||||
mTimes[mPosition] = microseconds;
|
times[position] = microseconds;
|
||||||
mPosition++;
|
position++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDecoded(boolean decoded) {
|
public void setDecoded(boolean decoded) {
|
||||||
mDecoded = decoded;
|
this.decoded = decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFormat(BarcodeFormat format) {
|
public void setFormat(BarcodeFormat format) {
|
||||||
mFormat = format;
|
this.format = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder(30);
|
||||||
result.append(mDecoded ? ("DECODED " + mFormat.toString() + ": ") : "FAILED: ");
|
result.append(decoded ? "DECODED " + format.toString() + ": " : "FAILED: ");
|
||||||
result.append(mPath);
|
result.append(path);
|
||||||
result.append(" (");
|
result.append(" (");
|
||||||
result.append(getAverageTime());
|
result.append(getAverageTime());
|
||||||
result.append(" us average)");
|
result.append(" us average)");
|
||||||
// int size = mTimes.length;
|
|
||||||
// for (int x = 0; x < size; x++) {
|
|
||||||
// result.append(mTimes[x]);
|
|
||||||
// result.append(" ");
|
|
||||||
// }
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,11 +67,11 @@ public final class BenchmarkItem {
|
||||||
* @return The average decoding time in microseconds.
|
* @return The average decoding time in microseconds.
|
||||||
*/
|
*/
|
||||||
public int getAverageTime() {
|
public int getAverageTime() {
|
||||||
int size = mTimes.length;
|
int size = times.length;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
int max = mTimes[0];
|
int max = times[0];
|
||||||
for (int x = 0; x < size; x++) {
|
for (int x = 0; x < size; x++) {
|
||||||
int time = mTimes[x];
|
int time = times[x];
|
||||||
total += time;
|
total += time;
|
||||||
if (time > max) {
|
if (time > max) {
|
||||||
max = time;
|
max = time;
|
||||||
|
@ -84,11 +79,7 @@ public final class BenchmarkItem {
|
||||||
}
|
}
|
||||||
total -= max;
|
total -= max;
|
||||||
size--;
|
size--;
|
||||||
if (size > 0) {
|
return size > 0 ? total / size : 0;
|
||||||
return total / size;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,43 +34,43 @@ import java.util.List;
|
||||||
|
|
||||||
final class BenchmarkThread extends Thread {
|
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 static final int RUNS = 10;
|
||||||
|
|
||||||
private final BenchmarkActivity mActivity;
|
private final BenchmarkActivity activity;
|
||||||
private final String mPath;
|
private final String path;
|
||||||
private MultiFormatReader mMultiFormatReader;
|
private MultiFormatReader multiFormatReader;
|
||||||
|
|
||||||
BenchmarkThread(BenchmarkActivity activity, String path) {
|
BenchmarkThread(BenchmarkActivity activity, String path) {
|
||||||
mActivity = activity;
|
this.activity = activity;
|
||||||
mPath = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mMultiFormatReader = new MultiFormatReader();
|
multiFormatReader = new MultiFormatReader();
|
||||||
mMultiFormatReader.setHints(null);
|
multiFormatReader.setHints(null);
|
||||||
// Try to get in a known state before starting the benchmark
|
// Try to get in a known state before starting the benchmark
|
||||||
System.gc();
|
System.gc();
|
||||||
|
|
||||||
List<BenchmarkItem> items = new ArrayList<BenchmarkItem>();
|
List<BenchmarkItem> items = new ArrayList<BenchmarkItem>();
|
||||||
walkTree(mPath, items);
|
walkTree(path, items);
|
||||||
Message message = Message.obtain(mActivity.mHandler, R.id.benchmark_done);
|
Message message = Message.obtain(activity.handler, R.id.benchmark_done);
|
||||||
message.obj = items;
|
message.obj = items;
|
||||||
message.sendToTarget();
|
message.sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recurse to allow subdirectories
|
// Recurse to allow subdirectories
|
||||||
private void walkTree(String path, List<BenchmarkItem> items) {
|
private void walkTree(String currentPath, List<BenchmarkItem> items) {
|
||||||
File file = new File(path);
|
File file = new File(currentPath);
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
String[] files = file.list();
|
String[] files = file.list();
|
||||||
Arrays.sort(files);
|
Arrays.sort(files);
|
||||||
for (String f : files) {
|
for (String fileName : files) {
|
||||||
walkTree(file.getAbsolutePath() + '/' + f, items);
|
walkTree(file.getAbsolutePath() + '/' + fileName, items);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BenchmarkItem item = decode(path);
|
BenchmarkItem item = decode(currentPath);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ final class BenchmarkThread extends Thread {
|
||||||
long now = Debug.threadCpuTimeNanos();
|
long now = Debug.threadCpuTimeNanos();
|
||||||
try {
|
try {
|
||||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||||
result = mMultiFormatReader.decodeWithState(bitmap);
|
result = multiFormatReader.decodeWithState(bitmap);
|
||||||
success = true;
|
success = true;
|
||||||
} catch (ReaderException e) {
|
} catch (ReaderException e) {
|
||||||
success = false;
|
success = false;
|
||||||
|
|
|
@ -20,7 +20,6 @@ import android.content.Context;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -29,6 +28,7 @@ import android.view.SurfaceHolder;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
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
|
* 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)
|
* @author dswitkin@google.com (Daniel Switkin)
|
||||||
*/
|
*/
|
||||||
final class CameraManager {
|
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_WIDTH = 240;
|
||||||
private static final int MIN_FRAME_HEIGHT = 240;
|
private static final int MIN_FRAME_HEIGHT = 240;
|
||||||
private static final int MAX_FRAME_WIDTH = 480;
|
private static final int MAX_FRAME_WIDTH = 480;
|
||||||
private static final int MAX_FRAME_HEIGHT = 360;
|
private static final int MAX_FRAME_HEIGHT = 360;
|
||||||
|
|
||||||
private static CameraManager cameraManager;
|
private static CameraManager cameraManager;
|
||||||
|
private static final Pattern SEMICOLON = Pattern.compile(";");
|
||||||
|
|
||||||
private Camera camera;
|
private Camera camera;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private Point screenResolution;
|
private Point screenResolution;
|
||||||
|
@ -56,17 +60,14 @@ final class CameraManager {
|
||||||
private int autoFocusMessage;
|
private int autoFocusMessage;
|
||||||
private boolean initialized;
|
private boolean initialized;
|
||||||
private boolean previewing;
|
private boolean previewing;
|
||||||
private final boolean useOneShotPreviewCallback;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preview frames are delivered here, which we pass on to the registered handler. Make sure to
|
* 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.
|
* clear the handler so it will only receive one message.
|
||||||
*/
|
*/
|
||||||
private final Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
|
private final Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
|
||||||
|
@Override
|
||||||
public void onPreviewFrame(byte[] data, Camera camera) {
|
public void onPreviewFrame(byte[] data, Camera camera) {
|
||||||
if (!useOneShotPreviewCallback) {
|
|
||||||
camera.setPreviewCallback(null);
|
|
||||||
}
|
|
||||||
if (previewHandler != null) {
|
if (previewHandler != null) {
|
||||||
Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,
|
Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,
|
||||||
cameraResolution.y, data);
|
cameraResolution.y, data);
|
||||||
|
@ -80,6 +81,7 @@ final class CameraManager {
|
||||||
* Autofocus callbacks arrive here, and are dispatched to the Handler which requested them.
|
* Autofocus callbacks arrive here, and are dispatched to the Handler which requested them.
|
||||||
*/
|
*/
|
||||||
private final Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
|
private final Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
|
||||||
|
@Override
|
||||||
public void onAutoFocus(boolean success, Camera camera) {
|
public void onAutoFocus(boolean success, Camera camera) {
|
||||||
if (autoFocusHandler != null) {
|
if (autoFocusHandler != null) {
|
||||||
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
|
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
|
||||||
|
@ -116,13 +118,6 @@ final class CameraManager {
|
||||||
camera = null;
|
camera = null;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
previewing = 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() {
|
public void stopPreview() {
|
||||||
if (camera != null && previewing) {
|
if (camera != null && previewing) {
|
||||||
if (!useOneShotPreviewCallback) {
|
|
||||||
camera.setPreviewCallback(null);
|
|
||||||
}
|
|
||||||
camera.stopPreview();
|
camera.stopPreview();
|
||||||
previewHandler = null;
|
previewHandler = null;
|
||||||
autoFocusHandler = null;
|
autoFocusHandler = null;
|
||||||
|
@ -197,11 +189,7 @@ final class CameraManager {
|
||||||
if (camera != null && previewing) {
|
if (camera != null && previewing) {
|
||||||
previewHandler = handler;
|
previewHandler = handler;
|
||||||
previewMessage = message;
|
previewMessage = message;
|
||||||
if (useOneShotPreviewCallback) {
|
camera.setOneShotPreviewCallback(previewCallback);
|
||||||
camera.setOneShotPreviewCallback(previewCallback);
|
|
||||||
} else {
|
|
||||||
camera.setPreviewCallback(previewCallback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,16 +262,13 @@ final class CameraManager {
|
||||||
Log.v(TAG, "Setting preview size: " + cameraResolution.x + ", " + cameraResolution.y);
|
Log.v(TAG, "Setting preview size: " + cameraResolution.x + ", " + cameraResolution.y);
|
||||||
parameters.setPreviewSize(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);
|
camera.setParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String collectCameraParameters() {
|
private String collectCameraParameters() {
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
Camera.Parameters parameters = camera.getParameters();
|
||||||
String[] params = parameters.flatten().split(";");
|
String[] params = SEMICOLON.split(parameters.flatten());
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder(100);
|
||||||
result.append("Default camera parameters:");
|
result.append("Default camera parameters:");
|
||||||
for (String param : params) {
|
for (String param : params) {
|
||||||
result.append("\n ");
|
result.append("\n ");
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
@ -35,11 +36,13 @@ import java.io.IOException;
|
||||||
|
|
||||||
public final class CameraTestActivity extends Activity implements SurfaceHolder.Callback {
|
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";
|
public static final String GET_CAMERA_PARAMETERS = "GET_CAMERA_PARAMETERS";
|
||||||
private static final String[] EMAIL_ADDRESS = {"zxing-external@google.com"};
|
private static final String[] EMAIL_ADDRESS = {"zxing-external@google.com"};
|
||||||
|
|
||||||
private SaveThread mSaveThread = null;
|
private SaveThread saveThread;
|
||||||
private boolean mGetCameraParameters;
|
private boolean getCameraParameters;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
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_KEEP_SCREEN_ON);
|
||||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
mGetCameraParameters = getIntent().getBooleanExtra(GET_CAMERA_PARAMETERS, false);
|
getCameraParameters = getIntent().getBooleanExtra(GET_CAMERA_PARAMETERS, false);
|
||||||
if (mGetCameraParameters) {
|
if (getCameraParameters) {
|
||||||
setContentView(R.layout.camera_parameters);
|
setContentView(R.layout.camera_parameters);
|
||||||
} else {
|
} else {
|
||||||
setContentView(R.layout.camera_test);
|
setContentView(R.layout.camera_test);
|
||||||
|
@ -67,9 +70,9 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (mSaveThread == null && !mGetCameraParameters) {
|
if (saveThread == null && !getCameraParameters) {
|
||||||
mSaveThread = new SaveThread(this);
|
saveThread = new SaveThread(this);
|
||||||
mSaveThread.start();
|
saveThread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,19 +81,20 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
CameraManager.get().stopPreview();
|
CameraManager.get().stopPreview();
|
||||||
if (mSaveThread != null) {
|
if (saveThread != null) {
|
||||||
Message quit = Message.obtain(mSaveThread.mHandler, R.id.quit);
|
Message quit = Message.obtain(saveThread.handler, R.id.quit);
|
||||||
quit.sendToTarget();
|
quit.sendToTarget();
|
||||||
try {
|
try {
|
||||||
mSaveThread.join();
|
saveThread.join();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
// continue
|
||||||
}
|
}
|
||||||
mSaveThread = null;
|
saveThread = null;
|
||||||
}
|
}
|
||||||
CameraManager.get().closeDriver();
|
CameraManager.get().closeDriver();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Handler mHandler = new Handler() {
|
final Handler handler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
switch (message.what) {
|
switch (message.what) {
|
||||||
|
@ -109,15 +113,15 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
if (!mGetCameraParameters) {
|
if (!getCameraParameters) {
|
||||||
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
|
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
|
||||||
if (event.getRepeatCount() == 0) {
|
if (event.getRepeatCount() == 0) {
|
||||||
CameraManager.get().requestAutoFocus(mHandler, R.id.auto_focus);
|
CameraManager.get().requestAutoFocus(handler, R.id.auto_focus);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_SEARCH) {
|
} else if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||||
if (event.getRepeatCount() == 0) {
|
if (event.getRepeatCount() == 0) {
|
||||||
CameraManager.get().requestPreviewFrame(mSaveThread.mHandler, R.id.save);
|
CameraManager.get().requestPreviewFrame(saveThread.handler, R.id.save);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -125,29 +129,29 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
|
||||||
return super.onKeyDown(keyCode, event);
|
return super.onKeyDown(keyCode, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
try {
|
try {
|
||||||
String parameters = CameraManager.get().openDriver(holder, mGetCameraParameters);
|
String parameters = CameraManager.get().openDriver(holder, getCameraParameters);
|
||||||
CameraManager.get().startPreview();
|
CameraManager.get().startPreview();
|
||||||
if (mGetCameraParameters) {
|
if (getCameraParameters) {
|
||||||
collectStatsAndSendEmail(parameters);
|
collectStatsAndSendEmail(parameters);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// IOException clause added for Android 1.5
|
throw new IllegalStateException(e);
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectStatsAndSendEmail(String parameters) {
|
private void collectStatsAndSendEmail(String parameters) {
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder(1000);
|
||||||
result.append("Device info:");
|
result.append("Device info:");
|
||||||
result.append("\n Board: ");
|
result.append("\n Board: ");
|
||||||
result.append(Build.BOARD);
|
result.append(Build.BOARD);
|
||||||
|
@ -183,13 +187,20 @@ public final class CameraTestActivity extends Activity implements SurfaceHolder.
|
||||||
result.append("\n\n");
|
result.append("\n\n");
|
||||||
result.append(parameters);
|
result.append(parameters);
|
||||||
|
|
||||||
|
FileOutputStream stream = null;
|
||||||
try {
|
try {
|
||||||
File file = new File("/sdcard/CameraParameters.txt");
|
stream = new FileOutputStream(new File("/sdcard/CameraParameters.txt"));
|
||||||
FileOutputStream stream = new FileOutputStream(file);
|
|
||||||
stream.write(result.toString().getBytes());
|
stream.write(result.toString().getBytes());
|
||||||
stream.close();
|
|
||||||
} catch (IOException e) {
|
} 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);
|
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||||
|
|
|
@ -55,8 +55,13 @@ public final class RGBLuminanceSource extends LuminanceSource {
|
||||||
int r = (pixel >> 16) & 0xff;
|
int r = (pixel >> 16) & 0xff;
|
||||||
int g = (pixel >> 8) & 0xff;
|
int g = (pixel >> 8) & 0xff;
|
||||||
int b = pixel & 0xff;
|
int b = pixel & 0xff;
|
||||||
// Calculate luminance cheaply, favoring green.
|
if (r == g && g == b) {
|
||||||
luminances[offset + x] = (byte) ((r + g + g + b) >> 2);
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,9 @@ import java.util.Date;
|
||||||
|
|
||||||
final class SaveThread extends Thread {
|
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;
|
private final CameraTestActivity mActivity;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ final class SaveThread extends Thread {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Looper.prepare();
|
Looper.prepare();
|
||||||
mHandler = new Handler() {
|
handler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
switch (message.what) {
|
switch (message.what) {
|
||||||
|
@ -90,7 +90,7 @@ final class SaveThread extends Thread {
|
||||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
|
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
|
||||||
try {
|
try {
|
||||||
outStream.close();
|
outStream.close();
|
||||||
Message message = Message.obtain(mActivity.mHandler, R.id.save_succeeded);
|
Message message = Message.obtain(mActivity.handler, R.id.save_succeeded);
|
||||||
message.sendToTarget();
|
message.sendToTarget();
|
||||||
return;
|
return;
|
||||||
} catch (IOException e) {
|
} 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();
|
message.sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,21 +26,21 @@ import android.view.View;
|
||||||
|
|
||||||
public final class ViewfinderView extends View {
|
public final class ViewfinderView extends View {
|
||||||
|
|
||||||
private final Paint mPaint;
|
private final Paint paint;
|
||||||
private final Rect mBox;
|
private final Rect box;
|
||||||
private final int mMaskColor;
|
private final int maskColor;
|
||||||
private final int mFrameColor;
|
private final int frameColor;
|
||||||
|
|
||||||
// This constructor is used when the class is built from an XML resource.
|
// This constructor is used when the class is built from an XML resource.
|
||||||
public ViewfinderView(Context context, AttributeSet attrs) {
|
public ViewfinderView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
|
||||||
// Initialize these once for performance rather than calling them every time in onDraw().
|
// Initialize these once for performance rather than calling them every time in onDraw().
|
||||||
mPaint = new Paint();
|
paint = new Paint();
|
||||||
mBox = new Rect();
|
box = new Rect();
|
||||||
Resources resources = getResources();
|
Resources resources = getResources();
|
||||||
mMaskColor = resources.getColor(R.color.viewfinder_mask);
|
maskColor = resources.getColor(R.color.viewfinder_mask);
|
||||||
mFrameColor = resources.getColor(R.color.viewfinder_frame);
|
frameColor = resources.getColor(R.color.viewfinder_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
// Draw the exterior (i.e. outside the framing rect) darkened, in red to distinguish it from
|
||||||
// the regular barcodes app
|
// the regular barcodes app
|
||||||
mPaint.setColor(mMaskColor);
|
paint.setColor(maskColor);
|
||||||
mBox.set(0, 0, width, frame.top);
|
box.set(0, 0, width, frame.top);
|
||||||
canvas.drawRect(mBox, mPaint);
|
canvas.drawRect(box, paint);
|
||||||
mBox.set(0, frame.top, frame.left, frame.bottom + 1);
|
box.set(0, frame.top, frame.left, frame.bottom + 1);
|
||||||
canvas.drawRect(mBox, mPaint);
|
canvas.drawRect(box, paint);
|
||||||
mBox.set(frame.right + 1, frame.top, width, frame.bottom + 1);
|
box.set(frame.right + 1, frame.top, width, frame.bottom + 1);
|
||||||
canvas.drawRect(mBox, mPaint);
|
canvas.drawRect(box, paint);
|
||||||
mBox.set(0, frame.bottom + 1, width, height);
|
box.set(0, frame.bottom + 1, width, height);
|
||||||
canvas.drawRect(mBox, mPaint);
|
canvas.drawRect(box, paint);
|
||||||
|
|
||||||
// Draw a two pixel solid white border inside the framing rect
|
// Draw a two pixel solid white border inside the framing rect
|
||||||
mPaint.setColor(mFrameColor);
|
paint.setColor(frameColor);
|
||||||
mBox.set(frame.left, frame.top, frame.right + 1, frame.top + 2);
|
box.set(frame.left, frame.top, frame.right + 1, frame.top + 2);
|
||||||
canvas.drawRect(mBox, mPaint);
|
canvas.drawRect(box, paint);
|
||||||
mBox.set(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1);
|
box.set(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1);
|
||||||
canvas.drawRect(mBox, mPaint);
|
canvas.drawRect(box, paint);
|
||||||
mBox.set(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1);
|
box.set(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1);
|
||||||
canvas.drawRect(mBox, mPaint);
|
canvas.drawRect(box, paint);
|
||||||
mBox.set(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1);
|
box.set(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1);
|
||||||
canvas.drawRect(mBox, mPaint);
|
canvas.drawRect(box, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,21 +59,22 @@ public final class ZXingTestActivity extends Activity {
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
super.onCreateOptionsMenu(menu);
|
super.onCreateOptionsMenu(menu);
|
||||||
menu.add(0, ABOUT_ID, 0, R.string.about_menu)
|
menu.add(0, ABOUT_ID, 0, R.string.about_menu).setIcon(android.R.drawable.ic_menu_info_details);
|
||||||
.setIcon(android.R.drawable.ic_menu_info_details);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (item.getItemId() == ABOUT_ID) {
|
if (item.getItemId() == ABOUT_ID) {
|
||||||
int versionCode = 0;
|
int versionCode;
|
||||||
String versionName = "unknown";
|
String versionName;
|
||||||
try {
|
try {
|
||||||
PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
|
PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
|
||||||
versionCode = info.versionCode;
|
versionCode = info.versionCode;
|
||||||
versionName = info.versionName;
|
versionName = info.versionName;
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
versionCode = 0;
|
||||||
|
versionName = "unknown";
|
||||||
}
|
}
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(
|
builder.setTitle(
|
||||||
|
@ -86,7 +87,8 @@ public final class ZXingTestActivity extends Activity {
|
||||||
return super.onOptionsItemSelected(item);
|
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) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setClassName(ZXingTestActivity.this, CameraTestActivity.class.getName());
|
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) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setClassName(ZXingTestActivity.this, CameraTestActivity.class.getName());
|
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) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setClassName(ZXingTestActivity.this, BenchmarkActivity.class.getName());
|
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) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
|
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
|
||||||
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
|
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) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
|
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
|
||||||
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
|
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) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
|
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
|
||||||
startActivityForResult(intent, 0);
|
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) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent("com.google.zxing.client.android.SEARCH_BOOK_CONTENTS");
|
Intent intent = new Intent("com.google.zxing.client.android.SEARCH_BOOK_CONTENTS");
|
||||||
intent.putExtra("ISBN", "9780441014989");
|
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) {
|
public void onClick(View v) {
|
||||||
encodeBarcode("TEXT_TYPE", "http://www.nytimes.com");
|
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) {
|
public void onClick(View v) {
|
||||||
encodeBarcode("EMAIL_TYPE", "foo@example.com");
|
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) {
|
public void onClick(View v) {
|
||||||
encodeBarcode("PHONE_TYPE", "2125551212");
|
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) {
|
public void onClick(View v) {
|
||||||
encodeBarcode("SMS_TYPE", "2125551212");
|
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) {
|
public void onClick(View v) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString(Contacts.Intents.Insert.NAME, "Jenny");
|
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) {
|
public void onClick(View v) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putFloat("LAT", 40.829208f);
|
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) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
|
Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
|
||||||
intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
|
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) {
|
public void onClick(View v) {
|
||||||
encodeBarcode(null, "bar");
|
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) {
|
public void onClick(View v) {
|
||||||
startActivity(new Intent("com.google.zxing.client.android.SHARE"));
|
startActivity(new Intent("com.google.zxing.client.android.SHARE"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
|
@ -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.
|
|
BIN
bug/lib/osgi.jar
BIN
bug/lib/osgi.jar
Binary file not shown.
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,31 +1,8 @@
|
||||||
version=1.6
|
version=2.0
|
||||||
|
|
||||||
# Set to the location where ProGuard's proguard.jar file can be found.
|
# Set to the location where ProGuard's proguard.jar file can be found.
|
||||||
#proguard-jar=/usr/local/android-sdk/tools/proguard/lib/proguard.jar
|
#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.
|
# Set this to the location where you installed the Android SDK.
|
||||||
#android-home=C:\\Program Files\\android-sdk-windows
|
#android-home=C:\\Program Files\\android-sdk-windows
|
||||||
#android-home=/usr/local/android-sdk
|
#android-home=/usr/local/android-sdk
|
||||||
|
|
25
build.xml
25
build.xml
|
@ -26,12 +26,6 @@
|
||||||
<ant dir="android" target="compile"/>
|
<ant dir="android" target="compile"/>
|
||||||
<ant dir="androidtest" target="compile"/>
|
<ant dir="androidtest" target="compile"/>
|
||||||
<ant dir="android-integration" target="build"/>
|
<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>
|
||||||
|
|
||||||
<target name="clean">
|
<target name="clean">
|
||||||
|
@ -40,7 +34,6 @@
|
||||||
<ant dir="android" target="clean"/>
|
<ant dir="android" target="clean"/>
|
||||||
<ant dir="androidtest" target="clean"/>
|
<ant dir="androidtest" target="clean"/>
|
||||||
<ant dir="android-integration" target="clean"/>
|
<ant dir="android-integration" target="clean"/>
|
||||||
<ant dir="zxingorg" target="clean"/>
|
|
||||||
<delete dir="docs/javadoc"/>
|
<delete dir="docs/javadoc"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
@ -56,7 +49,6 @@
|
||||||
<exclude name="**/*.iml"/>
|
<exclude name="**/*.iml"/>
|
||||||
<include name="AUTHORS"/>
|
<include name="AUTHORS"/>
|
||||||
<include name="COPYING"/>
|
<include name="COPYING"/>
|
||||||
<include name="README"/>
|
|
||||||
<include name="CHANGES"/>
|
<include name="CHANGES"/>
|
||||||
<include name="build.xml"/>
|
<include name="build.xml"/>
|
||||||
<include name="build.properties"/>
|
<include name="build.properties"/>
|
||||||
|
@ -64,18 +56,14 @@
|
||||||
<include name="android/**"/>
|
<include name="android/**"/>
|
||||||
<include name="android-integration/**"/>
|
<include name="android-integration/**"/>
|
||||||
<include name="androidtest/**"/>
|
<include name="androidtest/**"/>
|
||||||
<include name="bug/**"/>
|
|
||||||
<exclude name="bug/lib/com.buglabs*"/> <!-- Cannot distributed GPLed libraries -->
|
|
||||||
<include name="core/**"/>
|
<include name="core/**"/>
|
||||||
<include name="cpp/**"/>
|
<include name="cpp/**"/>
|
||||||
<include name="iphone/**"/>
|
<include name="iphone/**"/>
|
||||||
<include name="javame/**"/>
|
<include name="javame/**"/>
|
||||||
<include name="javase/**"/>
|
<include name="javase/**"/>
|
||||||
<include name="rim/**"/>
|
|
||||||
<include name="docs/**"/>
|
<include name="docs/**"/>
|
||||||
<include name="zxing.appspot.com/**"/>
|
<include name="zxing.appspot.com/**"/>
|
||||||
<include name="zxingorg/**"/>
|
<include name="zxingorg/**"/>
|
||||||
<exclude name="zxingorg/secrets.properties"/>
|
|
||||||
</zipfileset>
|
</zipfileset>
|
||||||
</zip>
|
</zip>
|
||||||
</target>
|
</target>
|
||||||
|
@ -94,18 +82,7 @@
|
||||||
<pathelement location="zxingorg/src"/>
|
<pathelement location="zxingorg/src"/>
|
||||||
</sourcepath>
|
</sourcepath>
|
||||||
<classpath>
|
<classpath>
|
||||||
<!-- These are used with WTK 2.5.x -->
|
<pathelement location="${android-home}/platforms/android-10/android.jar"/>
|
||||||
<!--
|
|
||||||
<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="${tomcat-home}/lib/servlet-api.jar"/>
|
<pathelement location="${tomcat-home}/lib/servlet-api.jar"/>
|
||||||
<fileset dir="zxingorg/web/WEB-INF/lib">
|
<fileset dir="zxingorg/web/WEB-INF/lib">
|
||||||
<include name="*.jar"/>
|
<include name="*.jar"/>
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
<mkdir dir="build"/>
|
<mkdir dir="build"/>
|
||||||
<javac srcdir="src"
|
<javac srcdir="src"
|
||||||
destdir="build"
|
destdir="build"
|
||||||
source="1.2"
|
source="6"
|
||||||
target="1.2"
|
target="6"
|
||||||
optimize="true"
|
optimize="true"
|
||||||
debug="${generate-debug}"
|
debug="${generate-debug}"
|
||||||
deprecation="true"
|
deprecation="true"
|
||||||
|
@ -97,13 +97,6 @@
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="build-test" depends="init,build">
|
<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"/>
|
<mkdir dir="build-test"/>
|
||||||
<javac srcdir="test/src"
|
<javac srcdir="test/src"
|
||||||
destdir="build-test"
|
destdir="build-test"
|
||||||
|
@ -112,7 +105,6 @@
|
||||||
includeantruntime="false">
|
includeantruntime="false">
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="core.jar"/>
|
<pathelement location="core.jar"/>
|
||||||
<pathelement location="../javase/javase.jar"/>
|
|
||||||
<pathelement location="lib/junit-4.8.2.jar"/>
|
<pathelement location="lib/junit-4.8.2.jar"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
</javac>
|
</javac>
|
||||||
|
@ -147,7 +139,6 @@
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="core.jar"/>
|
<pathelement location="core.jar"/>
|
||||||
<pathelement location="build-test"/>
|
<pathelement location="build-test"/>
|
||||||
<pathelement location="../javase/javase.jar"/>
|
|
||||||
<pathelement location="lib/junit-4.8.2.jar"/>
|
<pathelement location="lib/junit-4.8.2.jar"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
<assertions>
|
<assertions>
|
||||||
|
@ -169,7 +160,6 @@
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="core.jar"/>
|
<pathelement location="core.jar"/>
|
||||||
<pathelement location="build-test"/>
|
<pathelement location="build-test"/>
|
||||||
<pathelement location="../javase/javase.jar"/>
|
|
||||||
<pathelement location="lib/junit-4.8.2.jar"/>
|
<pathelement location="lib/junit-4.8.2.jar"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
<assertions>
|
<assertions>
|
||||||
|
|
|
@ -16,94 +16,62 @@
|
||||||
|
|
||||||
package com.google.zxing;
|
package com.google.zxing;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumerates barcode formats known to this package. Please keep alphabetized.
|
* Enumerates barcode formats known to this package. Please keep alphabetized.
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
public final class BarcodeFormat {
|
public enum BarcodeFormat {
|
||||||
|
|
||||||
// No, we can't use an enum here. J2ME doesn't support it.
|
|
||||||
|
|
||||||
private static final Hashtable VALUES = new Hashtable();
|
|
||||||
|
|
||||||
/** Aztec 2D barcode format. */
|
/** Aztec 2D barcode format. */
|
||||||
public static final BarcodeFormat AZTEC = new BarcodeFormat("AZTEC");
|
AZTEC,
|
||||||
|
|
||||||
/** CODABAR 1D format. */
|
/** CODABAR 1D format. */
|
||||||
public static final BarcodeFormat CODABAR = new BarcodeFormat("CODABAR");
|
CODABAR,
|
||||||
|
|
||||||
/** Code 39 1D format. */
|
/** Code 39 1D format. */
|
||||||
public static final BarcodeFormat CODE_39 = new BarcodeFormat("CODE_39");
|
CODE_39,
|
||||||
|
|
||||||
/** Code 93 1D format. */
|
/** Code 93 1D format. */
|
||||||
public static final BarcodeFormat CODE_93 = new BarcodeFormat("CODE_93");
|
CODE_93,
|
||||||
|
|
||||||
/** Code 128 1D format. */
|
/** Code 128 1D format. */
|
||||||
public static final BarcodeFormat CODE_128 = new BarcodeFormat("CODE_128");
|
CODE_128,
|
||||||
|
|
||||||
/** Data Matrix 2D barcode format. */
|
/** Data Matrix 2D barcode format. */
|
||||||
public static final BarcodeFormat DATA_MATRIX = new BarcodeFormat("DATA_MATRIX");
|
DATA_MATRIX,
|
||||||
|
|
||||||
/** EAN-8 1D format. */
|
/** EAN-8 1D format. */
|
||||||
public static final BarcodeFormat EAN_8 = new BarcodeFormat("EAN_8");
|
EAN_8,
|
||||||
|
|
||||||
/** EAN-13 1D format. */
|
/** EAN-13 1D format. */
|
||||||
public static final BarcodeFormat EAN_13 = new BarcodeFormat("EAN_13");
|
EAN_13,
|
||||||
|
|
||||||
/** ITF (Interleaved Two of Five) 1D format. */
|
/** ITF (Interleaved Two of Five) 1D format. */
|
||||||
public static final BarcodeFormat ITF = new BarcodeFormat("ITF");
|
ITF,
|
||||||
|
|
||||||
/** MaxiCode 2D barcode format. */
|
/** MaxiCode 2D barcode format. */
|
||||||
public static final BarcodeFormat MAXICODE = new BarcodeFormat("MAXICODE");
|
MAXICODE,
|
||||||
|
|
||||||
/** PDF417 format. */
|
/** PDF417 format. */
|
||||||
public static final BarcodeFormat PDF_417 = new BarcodeFormat("PDF_417");
|
PDF_417,
|
||||||
|
|
||||||
/** QR Code 2D barcode format. */
|
/** QR Code 2D barcode format. */
|
||||||
public static final BarcodeFormat QR_CODE = new BarcodeFormat("QR_CODE");
|
QR_CODE,
|
||||||
|
|
||||||
/** RSS 14 */
|
/** RSS 14 */
|
||||||
public static final BarcodeFormat RSS_14 = new BarcodeFormat("RSS_14");
|
RSS_14,
|
||||||
|
|
||||||
/** RSS EXPANDED */
|
/** RSS EXPANDED */
|
||||||
public static final BarcodeFormat RSS_EXPANDED = new BarcodeFormat("RSS_EXPANDED");
|
RSS_EXPANDED,
|
||||||
|
|
||||||
/** UPC-A 1D format. */
|
/** UPC-A 1D format. */
|
||||||
public static final BarcodeFormat UPC_A = new BarcodeFormat("UPC_A");
|
UPC_A,
|
||||||
|
|
||||||
/** UPC-E 1D format. */
|
/** 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. */
|
/** UPC/EAN extension format. Not a stand-alone format. */
|
||||||
public static final BarcodeFormat UPC_EAN_EXTENSION = new BarcodeFormat("UPC_EAN_EXTENSION");
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,4 +74,12 @@ public abstract class Binarizer {
|
||||||
*/
|
*/
|
||||||
public abstract Binarizer createBinarizer(LuminanceSource source);
|
public abstract Binarizer createBinarizer(LuminanceSource source);
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return source.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return source.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,21 +35,20 @@ public final class BinaryBitmap {
|
||||||
throw new IllegalArgumentException("Binarizer must be non-null.");
|
throw new IllegalArgumentException("Binarizer must be non-null.");
|
||||||
}
|
}
|
||||||
this.binarizer = binarizer;
|
this.binarizer = binarizer;
|
||||||
matrix = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The width of the bitmap.
|
* @return The width of the bitmap.
|
||||||
*/
|
*/
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return binarizer.getLuminanceSource().getWidth();
|
return binarizer.getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The height of the bitmap.
|
* @return The height of the bitmap.
|
||||||
*/
|
*/
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return binarizer.getLuminanceSource().getHeight();
|
return binarizer.getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,57 +23,52 @@ package com.google.zxing;
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
* @author dswitkin@google.com (Daniel Switkin)
|
* @author dswitkin@google.com (Daniel Switkin)
|
||||||
* @see Reader#decode(BinaryBitmap,java.util.Hashtable)
|
* @see Reader#decode(BinaryBitmap,java.util.Map)
|
||||||
*/
|
*/
|
||||||
public final class DecodeHintType {
|
public enum DecodeHintType {
|
||||||
|
|
||||||
// No, we can't use an enum here. J2ME doesn't support it.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
|
* 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;
|
* Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
|
||||||
* use {@link Boolean#TRUE}.
|
* 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.
|
* 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.
|
* 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}.
|
* 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)
|
* 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[].
|
* 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}.
|
* 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}
|
* The caller needs to be notified via callback when a possible {@link ResultPoint}
|
||||||
* is found. Maps to a {@link ResultPointCallback}.
|
* is found. Maps to a {@link ResultPointCallback}.
|
||||||
*/
|
*/
|
||||||
public static final DecodeHintType NEED_RESULT_POINT_CALLBACK = new DecodeHintType();
|
NEED_RESULT_POINT_CALLBACK,
|
||||||
|
|
||||||
private DecodeHintType() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,16 @@ package com.google.zxing;
|
||||||
*
|
*
|
||||||
* @author dswitkin@google.com (Daniel Switkin)
|
* @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).
|
* 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)
|
* Specifies what character encoding to use where applicable (type String)
|
||||||
*/
|
*/
|
||||||
public static final EncodeHintType CHARACTER_SET = new EncodeHintType();
|
CHARACTER_SET,
|
||||||
|
|
||||||
private EncodeHintType() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ public abstract class LuminanceSource {
|
||||||
* @return A cropped version of this object.
|
* @return A cropped version of this object.
|
||||||
*/
|
*/
|
||||||
public LuminanceSource crop(int left, int top, int width, int height) {
|
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.
|
* @return A rotated version of this object.
|
||||||
*/
|
*/
|
||||||
public LuminanceSource rotateCounterClockwise() {
|
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() {
|
public String toString() {
|
||||||
byte[] row = new byte[width];
|
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++) {
|
for (int y = 0; y < height; y++) {
|
||||||
row = getRow(y, row);
|
row = getRow(y, row);
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
|
|
|
@ -18,13 +18,15 @@ package com.google.zxing;
|
||||||
|
|
||||||
import com.google.zxing.aztec.AztecReader;
|
import com.google.zxing.aztec.AztecReader;
|
||||||
import com.google.zxing.datamatrix.DataMatrixReader;
|
import com.google.zxing.datamatrix.DataMatrixReader;
|
||||||
|
import com.google.zxing.maxicode.MaxiCodeReader;
|
||||||
import com.google.zxing.oned.MultiFormatOneDReader;
|
import com.google.zxing.oned.MultiFormatOneDReader;
|
||||||
import com.google.zxing.pdf417.PDF417Reader;
|
import com.google.zxing.pdf417.PDF417Reader;
|
||||||
import com.google.zxing.qrcode.QRCodeReader;
|
import com.google.zxing.qrcode.QRCodeReader;
|
||||||
import com.google.zxing.maxicode.MaxiCodeReader;
|
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.ArrayList;
|
||||||
import java.util.Vector;
|
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.
|
* 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 {
|
public final class MultiFormatReader implements Reader {
|
||||||
|
|
||||||
private Hashtable hints;
|
private Map<DecodeHintType,?> hints;
|
||||||
private final Vector readers = new Vector();
|
private final List<Reader> readers = new ArrayList<Reader>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it
|
* 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
|
* @return The contents of the image
|
||||||
* @throws NotFoundException Any errors which occurred
|
* @throws NotFoundException Any errors which occurred
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Result decode(BinaryBitmap image) throws NotFoundException {
|
public Result decode(BinaryBitmap image) throws NotFoundException {
|
||||||
setHints(null);
|
setHints(null);
|
||||||
return decodeInternal(image);
|
return decodeInternal(image);
|
||||||
|
@ -61,7 +64,8 @@ public final class MultiFormatReader implements Reader {
|
||||||
* @return The contents of the image
|
* @return The contents of the image
|
||||||
* @throws NotFoundException Any errors which occurred
|
* @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);
|
setHints(hints);
|
||||||
return decodeInternal(image);
|
return decodeInternal(image);
|
||||||
}
|
}
|
||||||
|
@ -89,85 +93,82 @@ public final class MultiFormatReader implements Reader {
|
||||||
*
|
*
|
||||||
* @param hints The set of hints to use for subsequent calls to decode(image)
|
* @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;
|
this.hints = hints;
|
||||||
|
|
||||||
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
|
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();
|
readers.clear();
|
||||||
if (formats != null) {
|
if (formats != null) {
|
||||||
boolean addOneDReader =
|
boolean addOneDReader =
|
||||||
formats.contains(BarcodeFormat.UPC_A) ||
|
formats.contains(BarcodeFormat.UPC_A) ||
|
||||||
formats.contains(BarcodeFormat.UPC_E) ||
|
formats.contains(BarcodeFormat.UPC_E) ||
|
||||||
formats.contains(BarcodeFormat.EAN_13) ||
|
formats.contains(BarcodeFormat.EAN_13) ||
|
||||||
formats.contains(BarcodeFormat.EAN_8) ||
|
formats.contains(BarcodeFormat.EAN_8) ||
|
||||||
//formats.contains(BarcodeFormat.CODABAR) ||
|
//formats.contains(BarcodeFormat.CODABAR) ||
|
||||||
formats.contains(BarcodeFormat.CODE_39) ||
|
formats.contains(BarcodeFormat.CODE_39) ||
|
||||||
formats.contains(BarcodeFormat.CODE_93) ||
|
formats.contains(BarcodeFormat.CODE_93) ||
|
||||||
formats.contains(BarcodeFormat.CODE_128) ||
|
formats.contains(BarcodeFormat.CODE_128) ||
|
||||||
formats.contains(BarcodeFormat.ITF) ||
|
formats.contains(BarcodeFormat.ITF) ||
|
||||||
formats.contains(BarcodeFormat.RSS_14) ||
|
formats.contains(BarcodeFormat.RSS_14) ||
|
||||||
formats.contains(BarcodeFormat.RSS_EXPANDED);
|
formats.contains(BarcodeFormat.RSS_EXPANDED);
|
||||||
// Put 1D readers upfront in "normal" mode
|
// Put 1D readers upfront in "normal" mode
|
||||||
if (addOneDReader && !tryHarder) {
|
if (addOneDReader && !tryHarder) {
|
||||||
readers.addElement(new MultiFormatOneDReader(hints));
|
readers.add(new MultiFormatOneDReader(hints));
|
||||||
}
|
}
|
||||||
if (formats.contains(BarcodeFormat.QR_CODE)) {
|
if (formats.contains(BarcodeFormat.QR_CODE)) {
|
||||||
readers.addElement(new QRCodeReader());
|
readers.add(new QRCodeReader());
|
||||||
}
|
}
|
||||||
if (formats.contains(BarcodeFormat.DATA_MATRIX)) {
|
if (formats.contains(BarcodeFormat.DATA_MATRIX)) {
|
||||||
readers.addElement(new DataMatrixReader());
|
readers.add(new DataMatrixReader());
|
||||||
}
|
}
|
||||||
if (formats.contains(BarcodeFormat.AZTEC)) {
|
if (formats.contains(BarcodeFormat.AZTEC)) {
|
||||||
readers.addElement(new AztecReader());
|
readers.add(new AztecReader());
|
||||||
}
|
}
|
||||||
if (formats.contains(BarcodeFormat.PDF_417)) {
|
if (formats.contains(BarcodeFormat.PDF_417)) {
|
||||||
readers.addElement(new PDF417Reader());
|
readers.add(new PDF417Reader());
|
||||||
}
|
}
|
||||||
if (formats.contains(BarcodeFormat.MAXICODE)) {
|
if (formats.contains(BarcodeFormat.MAXICODE)) {
|
||||||
readers.addElement(new MaxiCodeReader());
|
readers.add(new MaxiCodeReader());
|
||||||
}
|
}
|
||||||
// At end in "try harder" mode
|
// At end in "try harder" mode
|
||||||
if (addOneDReader && tryHarder) {
|
if (addOneDReader && tryHarder) {
|
||||||
readers.addElement(new MultiFormatOneDReader(hints));
|
readers.add(new MultiFormatOneDReader(hints));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (readers.isEmpty()) {
|
if (readers.isEmpty()) {
|
||||||
if (!tryHarder) {
|
if (!tryHarder) {
|
||||||
readers.addElement(new MultiFormatOneDReader(hints));
|
readers.add(new MultiFormatOneDReader(hints));
|
||||||
}
|
}
|
||||||
|
|
||||||
readers.addElement(new QRCodeReader());
|
readers.add(new QRCodeReader());
|
||||||
readers.addElement(new DataMatrixReader());
|
readers.add(new DataMatrixReader());
|
||||||
readers.addElement(new AztecReader());
|
readers.add(new AztecReader());
|
||||||
readers.addElement(new PDF417Reader());
|
readers.add(new PDF417Reader());
|
||||||
readers.addElement(new MaxiCodeReader());
|
readers.add(new MaxiCodeReader());
|
||||||
|
|
||||||
if (tryHarder) {
|
if (tryHarder) {
|
||||||
readers.addElement(new MultiFormatOneDReader(hints));
|
readers.add(new MultiFormatOneDReader(hints));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
int size = readers.size();
|
for (Reader reader : readers) {
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
Reader reader = (Reader) readers.elementAt(i);
|
|
||||||
reader.reset();
|
reader.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result decodeInternal(BinaryBitmap image) throws NotFoundException {
|
private Result decodeInternal(BinaryBitmap image) throws NotFoundException {
|
||||||
int size = readers.size();
|
for (Reader reader : readers) {
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
Reader reader = (Reader) readers.elementAt(i);
|
|
||||||
try {
|
try {
|
||||||
return reader.decode(image, hints);
|
return reader.decode(image, hints);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException re) {
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw NotFoundException.getNotFoundInstance();
|
throw NotFoundException.getNotFoundInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ import com.google.zxing.oned.UPCAWriter;
|
||||||
import com.google.zxing.pdf417.encoder.PDF417Writer;
|
import com.google.zxing.pdf417.encoder.PDF417Writer;
|
||||||
import com.google.zxing.qrcode.QRCodeWriter;
|
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
|
* This is a factory class which finds the appropriate Writer subclass for the BarcodeFormat
|
||||||
|
@ -37,36 +37,51 @@ import java.util.Hashtable;
|
||||||
*/
|
*/
|
||||||
public final class MultiFormatWriter implements Writer {
|
public final class MultiFormatWriter implements Writer {
|
||||||
|
|
||||||
public BitMatrix encode(String contents, BarcodeFormat format, int width,
|
@Override
|
||||||
int height) throws WriterException {
|
public BitMatrix encode(String contents,
|
||||||
|
BarcodeFormat format,
|
||||||
|
int width,
|
||||||
|
int height) throws WriterException {
|
||||||
return encode(contents, format, width, height, null);
|
return encode(contents, format, width, height, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height,
|
@Override
|
||||||
Hashtable hints) throws WriterException {
|
public BitMatrix encode(String contents,
|
||||||
|
BarcodeFormat format,
|
||||||
|
int width, int height,
|
||||||
|
Map<EncodeHintType,?> hints) throws WriterException {
|
||||||
|
|
||||||
Writer writer;
|
Writer writer;
|
||||||
if (format == BarcodeFormat.EAN_8) {
|
switch (format) {
|
||||||
writer = new EAN8Writer();
|
case EAN_8:
|
||||||
} else if (format == BarcodeFormat.EAN_13) {
|
writer = new EAN8Writer();
|
||||||
writer = new EAN13Writer();
|
break;
|
||||||
} else if (format == BarcodeFormat.UPC_A) {
|
case EAN_13:
|
||||||
writer = new UPCAWriter();
|
writer = new EAN13Writer();
|
||||||
} else if (format == BarcodeFormat.QR_CODE) {
|
break;
|
||||||
writer = new QRCodeWriter();
|
case UPC_A:
|
||||||
} else if (format == BarcodeFormat.CODE_39) {
|
writer = new UPCAWriter();
|
||||||
writer = new Code39Writer();
|
break;
|
||||||
} else if (format == BarcodeFormat.CODE_128) {
|
case QR_CODE:
|
||||||
writer = new Code128Writer();
|
writer = new QRCodeWriter();
|
||||||
} else if (format == BarcodeFormat.ITF) {
|
break;
|
||||||
writer = new ITFWriter();
|
case CODE_39:
|
||||||
} else if (format == BarcodeFormat.PDF_417) {
|
writer = new Code39Writer();
|
||||||
writer = new PDF417Writer();
|
break;
|
||||||
} else if (format == BarcodeFormat.CODABAR) {
|
case CODE_128:
|
||||||
writer = new CodaBarWriter();
|
writer = new Code128Writer();
|
||||||
} else {
|
break;
|
||||||
throw new IllegalArgumentException("No encoder available for format " + format);
|
case ITF:
|
||||||
|
writer = new ITFWriter();
|
||||||
|
break;
|
||||||
|
case PDF_417:
|
||||||
|
writer = new PDF417Writer();
|
||||||
|
break;
|
||||||
|
case CODABAR:
|
||||||
|
writer = new CodaBarWriter();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("No encoder available for format " + format);
|
||||||
}
|
}
|
||||||
return writer.encode(contents, format, width, height, hints);
|
return writer.encode(contents, format, width, height, hints);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package com.google.zxing;
|
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
|
* 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.
|
* hints, each possibly associated to some data, which may help the implementation decode.
|
||||||
*
|
*
|
||||||
* @param image image of barcode to 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
|
* to arbitrary data. The
|
||||||
* meaning of the data depends upon the hint type. The implementation may or may not do
|
* meaning of the data depends upon the hint type. The implementation may or may not do
|
||||||
* anything with these hints.
|
* anything with these hints.
|
||||||
* @return String which the barcode encodes
|
* @return String which the barcode encodes
|
||||||
* @throws NotFoundException if the barcode cannot be located or decoded for any reason
|
* @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
|
* Resets any internal state the implementation has after a decode, to prepare it
|
||||||
|
|
|
@ -25,72 +25,14 @@ package com.google.zxing;
|
||||||
*/
|
*/
|
||||||
public abstract class ReaderException extends Exception {
|
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() {
|
ReaderException() {
|
||||||
// do nothing
|
// 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
|
// Prevent stack traces from being taken
|
||||||
// srowen says: huh, my IDE is saying this is not an override. native methods can't be overridden?
|
// 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.
|
// This, at least, does not hurt. Because we use a singleton pattern here, it doesn't matter anyhow.
|
||||||
|
@Override
|
||||||
public final Throwable fillInStackTrace() {
|
public final Throwable fillInStackTrace() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
package com.google.zxing;
|
package com.google.zxing;
|
||||||
|
|
||||||
import java.util.Enumeration;
|
import java.util.EnumMap;
|
||||||
import java.util.Hashtable;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Encapsulates the result of decoding a barcode within an image.</p>
|
* <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 final byte[] rawBytes;
|
||||||
private ResultPoint[] resultPoints;
|
private ResultPoint[] resultPoints;
|
||||||
private final BarcodeFormat format;
|
private final BarcodeFormat format;
|
||||||
private Hashtable resultMetadata;
|
private Map<ResultMetadataType,Object> resultMetadata;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
|
|
||||||
public Result(String text,
|
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() {
|
public byte[] getRawBytes() {
|
||||||
return rawBytes;
|
return rawBytes;
|
||||||
|
@ -84,44 +84,39 @@ public final class Result {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link Hashtable} mapping {@link ResultMetadataType} keys to values. May be
|
* @return {@link Map} mapping {@link ResultMetadataType} keys to values. May be
|
||||||
* <code>null</code>. This contains optional metadata about what was detected about the barcode,
|
* {@code null}. This contains optional metadata about what was detected about the barcode,
|
||||||
* like orientation.
|
* like orientation.
|
||||||
*/
|
*/
|
||||||
public Hashtable getResultMetadata() {
|
public Map<ResultMetadataType,Object> getResultMetadata() {
|
||||||
return resultMetadata;
|
return resultMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putMetadata(ResultMetadataType type, Object value) {
|
public void putMetadata(ResultMetadataType type, Object value) {
|
||||||
if (resultMetadata == null) {
|
if (resultMetadata == null) {
|
||||||
resultMetadata = new Hashtable(3);
|
resultMetadata = new EnumMap<ResultMetadataType,Object>(ResultMetadataType.class);
|
||||||
}
|
}
|
||||||
resultMetadata.put(type, value);
|
resultMetadata.put(type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putAllMetadata(Hashtable metadata) {
|
public void putAllMetadata(Map<ResultMetadataType,Object> metadata) {
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
if (resultMetadata == null) {
|
if (resultMetadata == null) {
|
||||||
resultMetadata = metadata;
|
resultMetadata = metadata;
|
||||||
} else {
|
} else {
|
||||||
Enumeration e = metadata.keys();
|
resultMetadata.putAll(metadata);
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
ResultMetadataType key = (ResultMetadataType) e.nextElement();
|
|
||||||
Object value = metadata.get(key);
|
|
||||||
resultMetadata.put(key, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addResultPoints(ResultPoint[] newPoints) {
|
public void addResultPoints(ResultPoint[] newPoints) {
|
||||||
ResultPoint[] oldResultPoints = resultPoints;
|
ResultPoint[] oldPoints = resultPoints;
|
||||||
if (oldResultPoints == null) {
|
if (oldPoints == null) {
|
||||||
resultPoints = newPoints;
|
resultPoints = newPoints;
|
||||||
} else if (newPoints != null && newPoints.length > 0) {
|
} else if (newPoints != null && newPoints.length > 0) {
|
||||||
ResultPoint[] allPoints = new ResultPoint[oldResultPoints.length + newPoints.length];
|
ResultPoint[] allPoints = new ResultPoint[oldPoints.length + newPoints.length];
|
||||||
System.arraycopy(oldResultPoints, 0, allPoints, 0, oldResultPoints.length);
|
System.arraycopy(oldPoints, 0, allPoints, 0, oldPoints.length);
|
||||||
System.arraycopy(newPoints, 0, allPoints, oldResultPoints.length, newPoints.length);
|
System.arraycopy(newPoints, 0, allPoints, oldPoints.length, newPoints.length);
|
||||||
resultPoints = allPoints;
|
resultPoints = allPoints;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,6 +125,7 @@ public final class Result {
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,26 +16,18 @@
|
||||||
|
|
||||||
package com.google.zxing;
|
package com.google.zxing;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents some type of metadata about the result of the decoding that the decoder
|
* Represents some type of metadata about the result of the decoding that the decoder
|
||||||
* wishes to communicate back to the caller.
|
* wishes to communicate back to the caller.
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
public final class ResultMetadataType {
|
public enum 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.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
|
* 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
|
* 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
|
* said to have orientation "90". This key maps to an {@link Integer} whose
|
||||||
* value is in the range [0,360).
|
* 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'
|
* <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
|
* the complete raw bytes in the barcode for these formats, it does not offer the bytes
|
||||||
* from the byte segments alone.</p>
|
* 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>
|
* 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
|
* Error correction level used, if applicable. The value type depends on the
|
||||||
* format, but is typically a String.
|
* 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}.
|
* 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
|
* For some products, indicates the suggested retail price in the barcode as a
|
||||||
* formatted {@link String}.
|
* 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
|
* 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".
|
* ISO country code. Some map to multiple possible countries, like "US/CA".
|
||||||
*/
|
*/
|
||||||
public static final ResultMetadataType POSSIBLE_COUNTRY = new ResultMetadataType("POSSIBLE_COUNTRY");
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ public class ResultPoint {
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if (other instanceof ResultPoint) {
|
if (other instanceof ResultPoint) {
|
||||||
ResultPoint otherPoint = (ResultPoint) other;
|
ResultPoint otherPoint = (ResultPoint) other;
|
||||||
|
@ -48,12 +49,14 @@ public class ResultPoint {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return 31 * Float.floatToIntBits(x) + Float.floatToIntBits(y);
|
return 31 * Float.floatToIntBits(x) + Float.floatToIntBits(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer result = new StringBuffer(25);
|
StringBuilder result = new StringBuilder(25);
|
||||||
result.append('(');
|
result.append('(');
|
||||||
result.append(x);
|
result.append(x);
|
||||||
result.append(',');
|
result.append(',');
|
||||||
|
@ -111,15 +114,17 @@ public class ResultPoint {
|
||||||
* @return distance between two points
|
* @return distance between two points
|
||||||
*/
|
*/
|
||||||
public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
|
public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
|
||||||
float xDiff = pattern1.getX() - pattern2.getX();
|
float xDiff = pattern1.x - pattern2.x;
|
||||||
float yDiff = pattern1.getY() - pattern2.getY();
|
float yDiff = pattern1.y - pattern2.y;
|
||||||
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
|
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the z component of the cross product between vectors BC and BA.
|
* 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 bX = pointB.x;
|
||||||
float bY = pointB.y;
|
float bY = pointB.y;
|
||||||
return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
|
return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
|
||||||
|
|
|
@ -18,7 +18,7 @@ package com.google.zxing;
|
||||||
|
|
||||||
import com.google.zxing.common.BitMatrix;
|
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.
|
* 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 height The preferred height in pixels
|
||||||
* @param hints Additional parameters to supply to the encoder
|
* @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;
|
throws WriterException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ package com.google.zxing;
|
||||||
public final class WriterException extends Exception {
|
public final class WriterException extends Exception {
|
||||||
|
|
||||||
public WriterException() {
|
public WriterException() {
|
||||||
super();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WriterException(String message) {
|
public WriterException(String message) {
|
||||||
|
|
|
@ -26,7 +26,11 @@ public final class AztecDetectorResult extends DetectorResult {
|
||||||
private final int nbDatablocks;
|
private final int nbDatablocks;
|
||||||
private final int nbLayers;
|
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);
|
super(bits, points);
|
||||||
this.compact = compact;
|
this.compact = compact;
|
||||||
this.nbDatablocks = nbDatablocks;
|
this.nbDatablocks = nbDatablocks;
|
||||||
|
|
|
@ -31,8 +31,8 @@ import com.google.zxing.common.DecoderResult;
|
||||||
import com.google.zxing.aztec.decoder.Decoder;
|
import com.google.zxing.aztec.decoder.Decoder;
|
||||||
import com.google.zxing.aztec.detector.Detector;
|
import com.google.zxing.aztec.detector.Detector;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation can detect and decode Aztec codes in an image.
|
* 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 FormatException if a Data Matrix code cannot be decoded
|
||||||
* @throws ChecksumException if error correction fails
|
* @throws ChecksumException if error correction fails
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {
|
public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {
|
||||||
return decode(image, null);
|
return decode(image, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result decode(BinaryBitmap image, Hashtable hints)
|
@Override
|
||||||
|
public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)
|
||||||
throws NotFoundException, FormatException {
|
throws NotFoundException, FormatException {
|
||||||
|
|
||||||
AztecDetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();
|
AztecDetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();
|
||||||
|
@ -62,8 +64,8 @@ public final class AztecReader implements Reader {
|
||||||
if (hints != null) {
|
if (hints != null) {
|
||||||
ResultPointCallback rpcb = (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
|
ResultPointCallback rpcb = (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
|
||||||
if (rpcb != null) {
|
if (rpcb != null) {
|
||||||
for (int i = 0; i < points.length; i++) {
|
for (ResultPoint point : points) {
|
||||||
rpcb.foundPossibleResultPoint(points[i]);
|
rpcb.foundPossibleResultPoint(point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +74,7 @@ public final class AztecReader implements Reader {
|
||||||
|
|
||||||
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.AZTEC);
|
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.AZTEC);
|
||||||
|
|
||||||
Vector byteSegments = decoderResult.getByteSegments();
|
List<byte[]> byteSegments = decoderResult.getByteSegments();
|
||||||
if (byteSegments != null) {
|
if (byteSegments != null) {
|
||||||
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
|
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
|
||||||
}
|
}
|
||||||
|
@ -84,6 +86,7 @@ public final class AztecReader implements Reader {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,14 @@ import com.google.zxing.common.reedsolomon.ReedSolomonException;
|
||||||
*/
|
*/
|
||||||
public final class Decoder {
|
public final class Decoder {
|
||||||
|
|
||||||
private static final int UPPER = 0;
|
private enum Table {
|
||||||
private static final int LOWER = 1;
|
UPPER,
|
||||||
private static final int MIXED = 2;
|
LOWER,
|
||||||
private static final int DIGIT = 3;
|
MIXED,
|
||||||
private static final int PUNCT = 4;
|
DIGIT,
|
||||||
private static final int BINARY = 5;
|
PUNCT,
|
||||||
|
BINARY
|
||||||
|
}
|
||||||
|
|
||||||
private static final int[] NB_BITS_COMPACT = {
|
private static final int[] NB_BITS_COMPACT = {
|
||||||
0, 104, 240, 408, 608
|
0, 104, 240, 408, 608
|
||||||
|
@ -119,10 +121,10 @@ public final class Decoder {
|
||||||
throw FormatException.getFormatInstance();
|
throw FormatException.getFormatInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastTable = UPPER;
|
Table lastTable = Table.UPPER;
|
||||||
int table = UPPER;
|
Table table = Table.UPPER;
|
||||||
int startIndex = 0;
|
int startIndex = 0;
|
||||||
StringBuffer result = new StringBuffer(20);
|
StringBuilder result = new StringBuilder(20);
|
||||||
boolean end = false;
|
boolean end = false;
|
||||||
boolean shift = false;
|
boolean shift = false;
|
||||||
boolean switchShift = false;
|
boolean switchShift = false;
|
||||||
|
@ -153,7 +155,7 @@ public final class Decoder {
|
||||||
default:
|
default:
|
||||||
int size = 5;
|
int size = 5;
|
||||||
|
|
||||||
if (table == DIGIT) {
|
if (table == Table.DIGIT) {
|
||||||
size = 4;
|
size = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,31 +196,22 @@ public final class Decoder {
|
||||||
/**
|
/**
|
||||||
* gets the table corresponding to the char passed
|
* gets the table corresponding to the char passed
|
||||||
*/
|
*/
|
||||||
private static int getTable(char t) {
|
private static Table getTable(char t) {
|
||||||
int table = UPPER;
|
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case 'U':
|
|
||||||
table = UPPER;
|
|
||||||
break;
|
|
||||||
case 'L':
|
case 'L':
|
||||||
table = LOWER;
|
return Table.LOWER;
|
||||||
break;
|
|
||||||
case 'P':
|
case 'P':
|
||||||
table = PUNCT;
|
return Table.PUNCT;
|
||||||
break;
|
|
||||||
case 'M':
|
case 'M':
|
||||||
table = MIXED;
|
return Table.MIXED;
|
||||||
break;
|
|
||||||
case 'D':
|
case 'D':
|
||||||
table = DIGIT;
|
return Table.DIGIT;
|
||||||
break;
|
|
||||||
case 'B':
|
case 'B':
|
||||||
table = BINARY;
|
return Table.BINARY;
|
||||||
break;
|
case 'U':
|
||||||
|
default:
|
||||||
|
return Table.UPPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return table;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -228,7 +221,7 @@ public final class Decoder {
|
||||||
* @param table the table used
|
* @param table the table used
|
||||||
* @param code the code of the character
|
* @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) {
|
switch (table) {
|
||||||
case UPPER:
|
case UPPER:
|
||||||
return UPPER_TABLE[code];
|
return UPPER_TABLE[code];
|
||||||
|
@ -373,7 +366,7 @@ public final class Decoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
int layer = ddata.getNbLayers();
|
int layer = ddata.getNbLayers();
|
||||||
int size = matrix.height;
|
int size = matrix.getHeight();
|
||||||
int rawbitsOffset = 0;
|
int rawbitsOffset = 0;
|
||||||
int matrixOffset = 0;
|
int matrixOffset = 0;
|
||||||
|
|
||||||
|
@ -407,21 +400,21 @@ public final class Decoder {
|
||||||
* Transforms an Aztec code matrix by removing the control dashed lines
|
* Transforms an Aztec code matrix by removing the control dashed lines
|
||||||
*/
|
*/
|
||||||
private static BitMatrix removeDashedLines(BitMatrix matrix) {
|
private static BitMatrix removeDashedLines(BitMatrix matrix) {
|
||||||
int nbDashed = 1+ 2* ((matrix.width - 1)/2 / 16);
|
int nbDashed = 1 + 2 * ((matrix.getWidth() - 1) / 2 / 16);
|
||||||
BitMatrix newMatrix = new BitMatrix(matrix.width - nbDashed, matrix.height - nbDashed);
|
BitMatrix newMatrix = new BitMatrix(matrix.getWidth() - nbDashed, matrix.getHeight() - nbDashed);
|
||||||
|
|
||||||
int nx = 0;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ny = 0;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,10 @@ public final class Detector {
|
||||||
public AztecDetectorResult detect() throws NotFoundException {
|
public AztecDetectorResult detect() throws NotFoundException {
|
||||||
|
|
||||||
// 1. Get the center of the aztec matrix
|
// 1. Get the center of the aztec matrix
|
||||||
Point pCenter = getMatrixCenter();
|
Point pCenter = getMatrixCenter();
|
||||||
|
|
||||||
// 2. Get the corners of the center bull's eye
|
// 2. Get the corners of the center bull's eye
|
||||||
Point[] bullEyeCornerPoints = getBullEyeCornerPoints(pCenter);
|
Point[] bullEyeCornerPoints = getBullEyeCornerPoints(pCenter);
|
||||||
|
|
||||||
// 3. Get the size of the matrix from the bull's eye
|
// 3. Get the size of the matrix from the bull's eye
|
||||||
extractParameters(bullEyeCornerPoints);
|
extractParameters(bullEyeCornerPoints);
|
||||||
|
@ -346,8 +346,8 @@ public final class Detector {
|
||||||
|
|
||||||
// This exception can be in case the initial rectangle is white
|
// 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.
|
// In that case, surely in the bull's eye, we try to expand the rectangle.
|
||||||
int cx = image.width/2;
|
int cx = image.getWidth()/2;
|
||||||
int cy = image.height/2;
|
int cy = image.getHeight()/2;
|
||||||
pointA = getFirstDifferent(new Point(cx+15/2, cy-15/2), false, 1, -1).toResultPoint();
|
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();
|
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();
|
pointC = getFirstDifferent(new Point(cx-15/2, cy+15/2), false, -1, 1).toResultPoint();
|
||||||
|
@ -390,10 +390,10 @@ public final class Detector {
|
||||||
* Samples an Aztec matrix from an image
|
* Samples an Aztec matrix from an image
|
||||||
*/
|
*/
|
||||||
private BitMatrix sampleGrid(BitMatrix image,
|
private BitMatrix sampleGrid(BitMatrix image,
|
||||||
ResultPoint topLeft,
|
ResultPoint topLeft,
|
||||||
ResultPoint bottomLeft,
|
ResultPoint bottomLeft,
|
||||||
ResultPoint bottomRight,
|
ResultPoint bottomRight,
|
||||||
ResultPoint topRight) throws NotFoundException {
|
ResultPoint topRight) throws NotFoundException {
|
||||||
|
|
||||||
int dimension;
|
int dimension;
|
||||||
if (compact) {
|
if (compact) {
|
||||||
|
@ -473,7 +473,7 @@ public final class Detector {
|
||||||
* @param size number of bits
|
* @param size number of bits
|
||||||
* @return the array 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];
|
boolean[] res = new boolean[size];
|
||||||
float d = distance(p1,p2);
|
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
|
* @return true if the border of the rectangle passed in parameter is compound of white points only
|
||||||
* or black 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;
|
int corr = 3;
|
||||||
|
|
||||||
|
@ -610,7 +613,7 @@ public final class Detector {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValid(int x, int y) {
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,7 +18,8 @@ package com.google.zxing.client.result;
|
||||||
|
|
||||||
import com.google.zxing.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
|
* Implements KDDI AU's address book format. See
|
||||||
|
@ -28,12 +29,13 @@ import java.util.Vector;
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @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();
|
String rawText = result.getText();
|
||||||
// MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF
|
// 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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,21 +69,21 @@ final class AddressBookAUResultParser extends ResultParser {
|
||||||
int max,
|
int max,
|
||||||
String rawText,
|
String rawText,
|
||||||
boolean trim) {
|
boolean trim) {
|
||||||
Vector values = null;
|
List<String> values = null;
|
||||||
for (int i = 1; i <= max; i++) {
|
for (int i = 1; i <= max; i++) {
|
||||||
String value = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', trim);
|
String value = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', trim);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (values == null) {
|
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) {
|
if (values == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return toStringArray(values);
|
return values.toArray(new String[values.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,10 @@ import com.google.zxing.Result;
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @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();
|
String rawText = result.getText();
|
||||||
if (!rawText.startsWith("MECARD:")) {
|
if (!rawText.startsWith("MECARD:")) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -104,7 +104,7 @@ public final class AddressBookParsedResult extends ParsedResult {
|
||||||
public String[] getEmailTypes() {
|
public String[] getEmailTypes() {
|
||||||
return emailTypes;
|
return emailTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getInstantMessenger() {
|
public String getInstantMessenger() {
|
||||||
return instantMessenger;
|
return instantMessenger;
|
||||||
}
|
}
|
||||||
|
@ -144,8 +144,9 @@ public final class AddressBookParsedResult extends ParsedResult {
|
||||||
return birthday;
|
return birthday;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayResult() {
|
public String getDisplayResult() {
|
||||||
StringBuffer result = new StringBuffer(100);
|
StringBuilder result = new StringBuilder(100);
|
||||||
maybeAppend(names, result);
|
maybeAppend(names, result);
|
||||||
maybeAppend(pronunciation, result);
|
maybeAppend(pronunciation, result);
|
||||||
maybeAppend(title, result);
|
maybeAppend(title, result);
|
||||||
|
|
|
@ -18,7 +18,8 @@ package com.google.zxing.client.result;
|
||||||
|
|
||||||
import com.google.zxing.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
|
* Implements the "BIZCARD" address book entry format, though this has been
|
||||||
|
@ -27,13 +28,14 @@ import java.util.Vector;
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
final class BizcardResultParser extends AbstractDoCoMoResultParser {
|
public final class BizcardResultParser extends AbstractDoCoMoResultParser {
|
||||||
|
|
||||||
// Yes, we extend AbstractDoCoMoResultParser since the format is very much
|
// Yes, we extend AbstractDoCoMoResultParser since the format is very much
|
||||||
// like the DoCoMo MECARD format, but this is not technically one of
|
// like the DoCoMo MECARD format, but this is not technically one of
|
||||||
// DoCoMo's proposed formats
|
// DoCoMo's proposed formats
|
||||||
|
|
||||||
public static AddressBookParsedResult parse(Result result) {
|
@Override
|
||||||
|
public AddressBookParsedResult parse(Result result) {
|
||||||
String rawText = result.getText();
|
String rawText = result.getText();
|
||||||
if (!rawText.startsWith("BIZCARD:")) {
|
if (!rawText.startsWith("BIZCARD:")) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -65,26 +67,24 @@ final class BizcardResultParser extends AbstractDoCoMoResultParser {
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] buildPhoneNumbers(String number1, String number2, String number3) {
|
private static String[] buildPhoneNumbers(String number1,
|
||||||
Vector numbers = new Vector(3);
|
String number2,
|
||||||
|
String number3) {
|
||||||
|
List<String> numbers = new ArrayList<String>(3);
|
||||||
if (number1 != null) {
|
if (number1 != null) {
|
||||||
numbers.addElement(number1);
|
numbers.add(number1);
|
||||||
}
|
}
|
||||||
if (number2 != null) {
|
if (number2 != null) {
|
||||||
numbers.addElement(number2);
|
numbers.add(number2);
|
||||||
}
|
}
|
||||||
if (number3 != null) {
|
if (number3 != null) {
|
||||||
numbers.addElement(number3);
|
numbers.add(number3);
|
||||||
}
|
}
|
||||||
int size = numbers.size();
|
int size = numbers.size();
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] result = new String[size];
|
return numbers.toArray(new String[size]);
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
result[i] = (String) numbers.elementAt(i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String buildName(String firstName, String lastName) {
|
private static String buildName(String firstName, String lastName) {
|
||||||
|
|
|
@ -21,12 +21,10 @@ import com.google.zxing.Result;
|
||||||
/**
|
/**
|
||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {
|
public final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {
|
||||||
|
|
||||||
private BookmarkDoCoMoResultParser() {
|
@Override
|
||||||
}
|
public URIParsedResult parse(Result result) {
|
||||||
|
|
||||||
public static URIParsedResult parse(Result result) {
|
|
||||||
String rawText = result.getText();
|
String rawText = result.getText();
|
||||||
if (!rawText.startsWith("MEBKM:")) {
|
if (!rawText.startsWith("MEBKM:")) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -37,10 +35,7 @@ final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String uri = rawUri[0];
|
String uri = rawUri[0];
|
||||||
if (!URIResultParser.isBasicallyValidURI(uri)) {
|
return URIResultParser.isBasicallyValidURI(uri) ? new URIParsedResult(uri, title) : null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new URIParsedResult(uri, title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
* <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
|
* 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>
|
* @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;
|
return longitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayResult() {
|
public String getDisplayResult() {
|
||||||
StringBuffer result = new StringBuffer(100);
|
StringBuilder result = new StringBuilder(100);
|
||||||
maybeAppend(summary, result);
|
maybeAppend(summary, result);
|
||||||
maybeAppend(start, result);
|
maybeAppend(start, result);
|
||||||
maybeAppend(end, result);
|
maybeAppend(end, result);
|
||||||
|
@ -123,7 +124,7 @@ public final class CalendarParsedResult extends ParsedResult {
|
||||||
*
|
*
|
||||||
* @param date The string to validate
|
* @param date The string to validate
|
||||||
*/
|
*/
|
||||||
private static void validateDate(String date) {
|
private static void validateDate(CharSequence date) {
|
||||||
if (date != null) {
|
if (date != null) {
|
||||||
int length = date.length();
|
int length = date.length();
|
||||||
if (length != 8 && length != 15 && length != 16) {
|
if (length != 8 && length != 15 && length != 16) {
|
||||||
|
|
|
@ -26,7 +26,10 @@ public final class EmailAddressParsedResult extends ParsedResult {
|
||||||
private final String body;
|
private final String body;
|
||||||
private final String mailtoURI;
|
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);
|
super(ParsedResultType.EMAIL_ADDRESS);
|
||||||
this.emailAddress = emailAddress;
|
this.emailAddress = emailAddress;
|
||||||
this.subject = subject;
|
this.subject = subject;
|
||||||
|
@ -50,8 +53,9 @@ public final class EmailAddressParsedResult extends ParsedResult {
|
||||||
return mailtoURI;
|
return mailtoURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayResult() {
|
public String getDisplayResult() {
|
||||||
StringBuffer result = new StringBuffer(30);
|
StringBuilder result = new StringBuilder(30);
|
||||||
maybeAppend(emailAddress, result);
|
maybeAppend(emailAddress, result);
|
||||||
maybeAppend(subject, result);
|
maybeAppend(subject, result);
|
||||||
maybeAppend(body, result);
|
maybeAppend(body, result);
|
||||||
|
|
|
@ -18,7 +18,7 @@ package com.google.zxing.client.result;
|
||||||
|
|
||||||
import com.google.zxing.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
|
* 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
|
* @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 rawText = result.getText();
|
||||||
String emailAddress;
|
String emailAddress;
|
||||||
if (rawText.startsWith("mailto:") || rawText.startsWith("MAILTO:")) {
|
if (rawText.startsWith("mailto:") || rawText.startsWith("MAILTO:")) {
|
||||||
|
@ -38,15 +39,15 @@ final class EmailAddressResultParser extends ResultParser {
|
||||||
if (queryStart >= 0) {
|
if (queryStart >= 0) {
|
||||||
emailAddress = emailAddress.substring(0, queryStart);
|
emailAddress = emailAddress.substring(0, queryStart);
|
||||||
}
|
}
|
||||||
Hashtable nameValues = parseNameValuePairs(rawText);
|
Map<String,String> nameValues = parseNameValuePairs(rawText);
|
||||||
String subject = null;
|
String subject = null;
|
||||||
String body = null;
|
String body = null;
|
||||||
if (nameValues != null) {
|
if (nameValues != null) {
|
||||||
if (emailAddress.length() == 0) {
|
if (emailAddress.length() == 0) {
|
||||||
emailAddress = (String) nameValues.get("to");
|
emailAddress = nameValues.get("to");
|
||||||
}
|
}
|
||||||
subject = (String) nameValues.get("subject");
|
subject = nameValues.get("subject");
|
||||||
body = (String) nameValues.get("body");
|
body = nameValues.get("body");
|
||||||
}
|
}
|
||||||
return new EmailAddressParsedResult(emailAddress, subject, body, rawText);
|
return new EmailAddressParsedResult(emailAddress, subject, body, rawText);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,8 @@ package com.google.zxing.client.result;
|
||||||
|
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the "MATMSG" email message entry format.
|
* Implements the "MATMSG" email message entry format.
|
||||||
*
|
*
|
||||||
|
@ -25,12 +27,12 @@ import com.google.zxing.Result;
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @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();
|
String rawText = result.getText();
|
||||||
if (!rawText.startsWith("MATMSG:")) {
|
if (!rawText.startsWith("MATMSG:")) {
|
||||||
return null;
|
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
|
* 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
|
* validity. We want to generally be lenient here since this class is only intended to encapsulate what's
|
||||||
* in a barcode, not "judge" it.
|
* in a barcode, not "judge" it.
|
||||||
*/
|
*/
|
||||||
static boolean isBasicallyValidEmailAddress(String email) {
|
static boolean isBasicallyValidEmailAddress(String email) {
|
||||||
if (email == null) {
|
return email != null && ATEXT_ALPHANUMERIC.matcher(email).matches() && email.indexOf('@') >= 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,13 +26,13 @@
|
||||||
|
|
||||||
package com.google.zxing.client.result;
|
package com.google.zxing.client.result;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Antonio Manuel Benjumea Conde, Servinform, S.A.
|
* @author Antonio Manuel Benjumea Conde, Servinform, S.A.
|
||||||
* @author Agustín Delgado, 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 KILOGRAM = "KG";
|
||||||
public static final String POUND = "LB";
|
public static final String POUND = "LB";
|
||||||
|
@ -51,7 +51,7 @@ public class ExpandedProductParsedResult extends ParsedResult {
|
||||||
private final String priceIncrement;
|
private final String priceIncrement;
|
||||||
private final String priceCurrency;
|
private final String priceCurrency;
|
||||||
// For AIS that not exist in this object
|
// For AIS that not exist in this object
|
||||||
private final Hashtable uncommonAIs;
|
private final Map<String,String> uncommonAIs;
|
||||||
|
|
||||||
public ExpandedProductParsedResult(String productID,
|
public ExpandedProductParsedResult(String productID,
|
||||||
String sscc,
|
String sscc,
|
||||||
|
@ -66,7 +66,7 @@ public class ExpandedProductParsedResult extends ParsedResult {
|
||||||
String price,
|
String price,
|
||||||
String priceIncrement,
|
String priceIncrement,
|
||||||
String priceCurrency,
|
String priceCurrency,
|
||||||
Hashtable uncommonAIs) {
|
Map<String,String> uncommonAIs) {
|
||||||
super(ParsedResultType.PRODUCT);
|
super(ParsedResultType.PRODUCT);
|
||||||
this.productID = productID;
|
this.productID = productID;
|
||||||
this.sscc = sscc;
|
this.sscc = sscc;
|
||||||
|
@ -84,6 +84,7 @@ public class ExpandedProductParsedResult extends ParsedResult {
|
||||||
this.uncommonAIs = uncommonAIs;
|
this.uncommonAIs = uncommonAIs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(Object o){
|
public boolean equals(Object o){
|
||||||
if (!(o instanceof ExpandedProductParsedResult)) {
|
if (!(o instanceof ExpandedProductParsedResult)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -110,6 +111,7 @@ public class ExpandedProductParsedResult extends ParsedResult {
|
||||||
return o1 == null ? o2 == null : o1.equals(o2);
|
return o1 == null ? o2 == null : o1.equals(o2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode(){
|
public int hashCode(){
|
||||||
int hash = 0;
|
int hash = 0;
|
||||||
hash ^= hashNotNull(productID);
|
hash ^= hashNotNull(productID);
|
||||||
|
@ -184,10 +186,11 @@ public class ExpandedProductParsedResult extends ParsedResult {
|
||||||
return priceCurrency;
|
return priceCurrency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hashtable getUncommonAIs() {
|
public Map<String,String> getUncommonAIs() {
|
||||||
return uncommonAIs;
|
return uncommonAIs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayResult() {
|
public String getDisplayResult() {
|
||||||
return String.valueOf(productID);
|
return String.valueOf(productID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
|
|
||||||
package com.google.zxing.client.result;
|
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.BarcodeFormat;
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
@ -37,16 +38,12 @@ import com.google.zxing.Result;
|
||||||
* @author Antonio Manuel Benjumea Conde, Servinform, S.A.
|
* @author Antonio Manuel Benjumea Conde, Servinform, S.A.
|
||||||
* @author Agustín Delgado, Servinform, S.A.
|
* @author Agustín Delgado, Servinform, S.A.
|
||||||
*/
|
*/
|
||||||
final class ExpandedProductResultParser extends ResultParser {
|
public final class ExpandedProductResultParser extends ResultParser {
|
||||||
|
|
||||||
private ExpandedProductResultParser() {
|
@Override
|
||||||
}
|
public ExpandedProductParsedResult parse(Result result) {
|
||||||
|
|
||||||
// Treat all RSS EXPANDED, in the sense that they are all
|
|
||||||
// product barcodes with complementary data.
|
|
||||||
public static ExpandedProductParsedResult parse(Result result) {
|
|
||||||
BarcodeFormat format = result.getBarcodeFormat();
|
BarcodeFormat format = result.getBarcodeFormat();
|
||||||
if (!BarcodeFormat.RSS_EXPANDED.equals(format)) {
|
if (format != BarcodeFormat.RSS_EXPANDED) {
|
||||||
// ExtendedProductParsedResult NOT created. Not a RSS Expanded barcode
|
// ExtendedProductParsedResult NOT created. Not a RSS Expanded barcode
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +67,7 @@ final class ExpandedProductResultParser extends ResultParser {
|
||||||
String price = null;
|
String price = null;
|
||||||
String priceIncrement = null;
|
String priceIncrement = null;
|
||||||
String priceCurrency = null;
|
String priceCurrency = null;
|
||||||
Hashtable uncommonAIs = new Hashtable();
|
Map<String,String> uncommonAIs = new HashMap<String,String>();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -153,7 +150,7 @@ final class ExpandedProductResultParser extends ResultParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String findAIvalue(int i, String rawText) {
|
private static String findAIvalue(int i, String rawText) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuilder buf = new StringBuilder();
|
||||||
char c = rawText.charAt(i);
|
char c = rawText.charAt(i);
|
||||||
// First character must be a open parenthesis.If not, ERROR
|
// First character must be a open parenthesis.If not, ERROR
|
||||||
if (c != '(') {
|
if (c != '(') {
|
||||||
|
@ -176,7 +173,7 @@ final class ExpandedProductResultParser extends ResultParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String findValue(int i, String rawText) {
|
private static String findValue(int i, String rawText) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuilder buf = new StringBuilder();
|
||||||
String rawTextAux = rawText.substring(i);
|
String rawTextAux = rawText.substring(i);
|
||||||
|
|
||||||
for (int index = 0; index < rawTextAux.length(); index++) {
|
for (int index = 0; index < rawTextAux.length(); index++) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ public final class GeoParsedResult extends ParsedResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getGeoURI() {
|
public String getGeoURI() {
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuilder result = new StringBuilder();
|
||||||
result.append("geo:");
|
result.append("geo:");
|
||||||
result.append(latitude);
|
result.append(latitude);
|
||||||
result.append(',');
|
result.append(',');
|
||||||
|
@ -79,8 +79,9 @@ public final class GeoParsedResult extends ParsedResult {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayResult() {
|
public String getDisplayResult() {
|
||||||
StringBuffer result = new StringBuffer(20);
|
StringBuilder result = new StringBuilder(20);
|
||||||
result.append(latitude);
|
result.append(latitude);
|
||||||
result.append(", ");
|
result.append(", ");
|
||||||
result.append(longitude);
|
result.append(longitude);
|
||||||
|
@ -97,36 +98,4 @@ public final class GeoParsedResult extends ParsedResult {
|
||||||
return result.toString();
|
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();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,6 +18,9 @@ package com.google.zxing.client.result;
|
||||||
|
|
||||||
import com.google.zxing.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
|
* 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
|
* the Earth as well as an optional altitude above the surface. See
|
||||||
|
@ -26,49 +29,44 @@ import com.google.zxing.Result;
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @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();
|
String rawText = result.getText();
|
||||||
if (rawText == null || (!rawText.startsWith("geo:") && !rawText.startsWith("GEO:"))) {
|
if (rawText == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Drop geo, query portion
|
|
||||||
int queryStart = rawText.indexOf('?', 4);
|
Matcher matcher = GEO_URL_PATTERN.matcher(rawText);
|
||||||
String query;
|
if (!matcher.matches()) {
|
||||||
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) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int longitudeEnd = geoURIWithoutQuery.indexOf(',', latitudeEnd + 1);
|
|
||||||
|
String query = matcher.group(4);
|
||||||
|
|
||||||
double latitude;
|
double latitude;
|
||||||
double longitude;
|
double longitude;
|
||||||
double altitude;
|
double altitude;
|
||||||
try {
|
try {
|
||||||
latitude = Double.parseDouble(geoURIWithoutQuery.substring(0, latitudeEnd));
|
latitude = Double.parseDouble(matcher.group(1));
|
||||||
if (latitude > 90.0 || latitude < -90.0) {
|
if (latitude > 90.0 || latitude < -90.0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (longitudeEnd < 0) {
|
longitude = Double.parseDouble(matcher.group(2));
|
||||||
longitude = Double.parseDouble(geoURIWithoutQuery.substring(latitudeEnd + 1));
|
if (longitude > 180.0 || longitude < -180.0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (matcher.group(3) == null) {
|
||||||
altitude = 0.0;
|
altitude = 0.0;
|
||||||
} else {
|
} else {
|
||||||
longitude = Double.parseDouble(geoURIWithoutQuery.substring(latitudeEnd + 1, longitudeEnd));
|
altitude = Double.parseDouble(matcher.group(3));
|
||||||
altitude = Double.parseDouble(geoURIWithoutQuery.substring(longitudeEnd + 1));
|
if (altitude < 0.0) {
|
||||||
}
|
return null;
|
||||||
if (longitude > 180.0 || longitude < -180.0 || altitude < 0) {
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -32,6 +32,7 @@ public final class ISBNParsedResult extends ParsedResult {
|
||||||
return isbn;
|
return isbn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayResult() {
|
public String getDisplayResult() {
|
||||||
return isbn;
|
return isbn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,16 +24,15 @@ import com.google.zxing.Result;
|
||||||
*
|
*
|
||||||
* @author jbreiden@google.com (Jeff Breidenbach)
|
* @author jbreiden@google.com (Jeff Breidenbach)
|
||||||
*/
|
*/
|
||||||
public class ISBNResultParser extends ResultParser {
|
public final class ISBNResultParser extends ResultParser {
|
||||||
|
|
||||||
private ISBNResultParser() {
|
/**
|
||||||
}
|
* See <a href="http://www.bisg.org/isbn-13/for.dummies.html">ISBN-13 For Dummies</a>
|
||||||
|
*/
|
||||||
// ISBN-13 For Dummies
|
@Override
|
||||||
// http://www.bisg.org/isbn-13/for.dummies.html
|
public ISBNParsedResult parse(Result result) {
|
||||||
public static ISBNParsedResult parse(Result result) {
|
|
||||||
BarcodeFormat format = result.getBarcodeFormat();
|
BarcodeFormat format = result.getBarcodeFormat();
|
||||||
if (!BarcodeFormat.EAN_13.equals(format)) {
|
if (format != BarcodeFormat.EAN_13) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String rawText = result.getText();
|
String rawText = result.getText();
|
||||||
|
|
|
@ -43,11 +43,12 @@ public abstract class ParsedResult {
|
||||||
|
|
||||||
public abstract String getDisplayResult();
|
public abstract String getDisplayResult();
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getDisplayResult();
|
return getDisplayResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void maybeAppend(String value, StringBuffer result) {
|
public static void maybeAppend(String value, StringBuilder result) {
|
||||||
if (value != null && value.length() > 0) {
|
if (value != null && value.length() > 0) {
|
||||||
// Don't add a newline before the first value
|
// Don't add a newline before the first value
|
||||||
if (result.length() > 0) {
|
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) {
|
if (value != null) {
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (String s : value) {
|
||||||
if (value[i] != null && value[i].length() > 0) {
|
if (s != null && s.length() > 0) {
|
||||||
if (result.length() > 0) {
|
if (result.length() > 0) {
|
||||||
result.append('\n');
|
result.append('\n');
|
||||||
}
|
}
|
||||||
result.append(value[i]);
|
result.append(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,32 +22,18 @@ package com.google.zxing.client.result;
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
public final class ParsedResultType {
|
public enum ParsedResultType {
|
||||||
|
|
||||||
public static final ParsedResultType ADDRESSBOOK = new ParsedResultType("ADDRESSBOOK");
|
ADDRESSBOOK,
|
||||||
public static final ParsedResultType EMAIL_ADDRESS = new ParsedResultType("EMAIL_ADDRESS");
|
EMAIL_ADDRESS,
|
||||||
public static final ParsedResultType PRODUCT = new ParsedResultType("PRODUCT");
|
PRODUCT,
|
||||||
public static final ParsedResultType URI = new ParsedResultType("URI");
|
URI,
|
||||||
public static final ParsedResultType TEXT = new ParsedResultType("TEXT");
|
TEXT,
|
||||||
public static final ParsedResultType ANDROID_INTENT = new ParsedResultType("ANDROID_INTENT");
|
GEO,
|
||||||
public static final ParsedResultType GEO = new ParsedResultType("GEO");
|
TEL,
|
||||||
public static final ParsedResultType TEL = new ParsedResultType("TEL");
|
SMS,
|
||||||
public static final ParsedResultType SMS = new ParsedResultType("SMS");
|
CALENDAR,
|
||||||
public static final ParsedResultType CALENDAR = new ParsedResultType("CALENDAR");
|
WIFI,
|
||||||
public static final ParsedResultType WIFI = new ParsedResultType("WIFI");
|
ISBN,
|
||||||
// "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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ public final class ProductParsedResult extends ParsedResult {
|
||||||
return normalizedProductID;
|
return normalizedProductID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayResult() {
|
public String getDisplayResult() {
|
||||||
return productID;
|
return productID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,16 +25,14 @@ import com.google.zxing.oned.UPCEReader;
|
||||||
*
|
*
|
||||||
* @author dswitkin@google.com (Daniel Switkin)
|
* @author dswitkin@google.com (Daniel Switkin)
|
||||||
*/
|
*/
|
||||||
final class ProductResultParser extends ResultParser {
|
public final class ProductResultParser extends ResultParser {
|
||||||
|
|
||||||
private ProductResultParser() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Treat all UPC and EAN variants as UPCs, in the sense that they are all product barcodes.
|
// 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();
|
BarcodeFormat format = result.getBarcodeFormat();
|
||||||
if (!(BarcodeFormat.UPC_A.equals(format) || BarcodeFormat.UPC_E.equals(format) ||
|
if (!(format == BarcodeFormat.UPC_A || format == BarcodeFormat.UPC_E ||
|
||||||
BarcodeFormat.EAN_8.equals(format) || BarcodeFormat.EAN_13.equals(format))) {
|
format == BarcodeFormat.EAN_8 || format == BarcodeFormat.EAN_13)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String rawText = result.getText();
|
String rawText = result.getText();
|
||||||
|
@ -49,7 +47,7 @@ final class ProductResultParser extends ResultParser {
|
||||||
|
|
||||||
String normalizedProductID;
|
String normalizedProductID;
|
||||||
// Expand UPC-E for purposes of searching
|
// Expand UPC-E for purposes of searching
|
||||||
if (BarcodeFormat.UPC_E.equals(format)) {
|
if (format == BarcodeFormat.UPC_E) {
|
||||||
normalizedProductID = UPCEReader.convertUPCEtoUPCA(rawText);
|
normalizedProductID = UPCEReader.convertUPCEtoUPCA(rawText);
|
||||||
} else {
|
} else {
|
||||||
normalizedProductID = rawText;
|
normalizedProductID = rawText;
|
||||||
|
|
|
@ -18,13 +18,18 @@ package com.google.zxing.client.result;
|
||||||
|
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.Vector;
|
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
|
* <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 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>
|
* 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
|
* <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 {
|
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) {
|
public static ParsedResult parseResult(Result theResult) {
|
||||||
// This is a bit messy, but given limited options in MIDP / CLDC, this may well be the simplest
|
for (ResultParser parser : PARSERS) {
|
||||||
// way to go about this. For example, we have no reflection available, really.
|
ParsedResult result = parser.parse(theResult);
|
||||||
// Order is important here.
|
if (result != null) {
|
||||||
ParsedResult result;
|
return 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) {
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return new TextParsedResult(theResult.getText(), null);
|
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) {
|
if (value != null) {
|
||||||
result.append('\n');
|
result.append('\n');
|
||||||
result.append(value);
|
result.append(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void maybeAppend(String[] value, StringBuffer result) {
|
protected static void maybeAppend(String[] value, StringBuilder result) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (String s : value) {
|
||||||
result.append('\n');
|
result.append('\n');
|
||||||
result.append(value[i]);
|
result.append(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ public abstract class ResultParser {
|
||||||
return escaped;
|
return escaped;
|
||||||
}
|
}
|
||||||
int max = escaped.length();
|
int max = escaped.length();
|
||||||
StringBuffer unescaped = new StringBuffer(max - 1);
|
StringBuilder unescaped = new StringBuilder(max - 1);
|
||||||
unescaped.append(escaped.toCharArray(), 0, backslash);
|
unescaped.append(escaped.toCharArray(), 0, backslash);
|
||||||
boolean nextIsEscaped = false;
|
boolean nextIsEscaped = false;
|
||||||
for (int i = backslash; i < max; i++) {
|
for (int i = backslash; i < max; i++) {
|
||||||
|
@ -124,148 +124,68 @@ public abstract class ResultParser {
|
||||||
return unescaped.toString();
|
return unescaped.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String urlDecode(String escaped) {
|
protected static int parseHexDigit(char c) {
|
||||||
// No we can't use java.net.URLDecoder here. JavaME doesn't have it.
|
if (c >= '0' && c <= '9') {
|
||||||
if (escaped == null) {
|
return c - '0';
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
char[] escapedArray = escaped.toCharArray();
|
if (c >= 'a' && c <= 'f') {
|
||||||
|
return 10 + (c - 'a');
|
||||||
int first = findFirstEscape(escapedArray);
|
|
||||||
if (first < 0) {
|
|
||||||
return escaped;
|
|
||||||
}
|
}
|
||||||
|
if (c >= 'A' && c <= 'F') {
|
||||||
int max = escapedArray.length;
|
return 10 + (c - 'A');
|
||||||
// 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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int parseHexDigit(char c) {
|
protected static boolean isStringOfDigits(CharSequence value, int length) {
|
||||||
if (c >= 'a') {
|
return value != null && length == value.length() && DIGITS.matcher(value).matches();
|
||||||
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') {
|
|
||||||
return c - '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean isStringOfDigits(String value, int length) {
|
protected static boolean isSubstringOfDigits(CharSequence value, int offset, int length) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return false;
|
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 isSubstringOfDigits(String value, int offset, int length) {
|
|
||||||
if (value == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int stringLength = value.length();
|
|
||||||
int max = offset + length;
|
int max = offset + length;
|
||||||
if (stringLength < max) {
|
return value.length() >= max && DIGITS.matcher(value.subSequence(offset, max)).matches();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = offset; i < max; i++) {
|
|
||||||
char c = value.charAt(i);
|
|
||||||
if (c < '0' || c > '9') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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('?');
|
int paramStart = uri.indexOf('?');
|
||||||
if (paramStart < 0) {
|
if (paramStart < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Hashtable result = new Hashtable(3);
|
Map<String,String> result = new HashMap<String,String>(3);
|
||||||
paramStart++;
|
for (String keyValue : AMPERSAND.split(uri.substring(paramStart + 1))) {
|
||||||
int paramEnd;
|
appendKeyValue(keyValue, result);
|
||||||
while ((paramEnd = uri.indexOf('&', paramStart)) >= 0) {
|
|
||||||
appendKeyValue(uri, paramStart, paramEnd, result);
|
|
||||||
paramStart = paramEnd + 1;
|
|
||||||
}
|
}
|
||||||
appendKeyValue(uri, paramStart, uri.length(), result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void appendKeyValue(String uri, int paramStart, int paramEnd, Hashtable result) {
|
private static void appendKeyValue(CharSequence keyValue,
|
||||||
int separator = uri.indexOf('=', paramStart);
|
Map<String,String> result) {
|
||||||
if (separator >= 0) {
|
String[] keyValueTokens = EQUALS.split(keyValue, 2);
|
||||||
// key = value
|
if (keyValueTokens.length == 2) {
|
||||||
String key = uri.substring(paramStart, separator);
|
String key = keyValueTokens[0];
|
||||||
String value = uri.substring(separator + 1, paramEnd);
|
String value = keyValueTokens[1];
|
||||||
value = urlDecode(value);
|
try {
|
||||||
|
value = URLDecoder.decode(value, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException uee) {
|
||||||
|
throw new IllegalStateException(uee); // can't happen
|
||||||
|
}
|
||||||
result.put(key, value);
|
result.put(key, value);
|
||||||
}
|
}
|
||||||
// Can't put key, null into a hashtable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static String[] matchPrefixedField(String prefix, String rawText, char endChar, boolean trim) {
|
static String[] matchPrefixedField(String prefix, String rawText, char endChar, boolean trim) {
|
||||||
Vector matches = null;
|
List<String> matches = null;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int max = rawText.length();
|
int max = rawText.length();
|
||||||
while (i < max) {
|
while (i < max) {
|
||||||
|
@ -275,35 +195,35 @@ public abstract class ResultParser {
|
||||||
}
|
}
|
||||||
i += prefix.length(); // Skip past this prefix we found to start
|
i += prefix.length(); // Skip past this prefix we found to start
|
||||||
int start = i; // Found the start of a match here
|
int start = i; // Found the start of a match here
|
||||||
boolean done = false;
|
boolean more = true;
|
||||||
while (!done) {
|
while (more) {
|
||||||
i = rawText.indexOf((int) endChar, i);
|
i = rawText.indexOf((int) endChar, i);
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
// No terminating end character? uh, done. Set i such that loop terminates and break
|
// No terminating end character? uh, done. Set i such that loop terminates and break
|
||||||
i = rawText.length();
|
i = rawText.length();
|
||||||
done = true;
|
more = false;
|
||||||
} else if (rawText.charAt(i - 1) == '\\') {
|
} else if (rawText.charAt(i - 1) == '\\') {
|
||||||
// semicolon was escaped so continue
|
// semicolon was escaped so continue
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
// found a match
|
// found a match
|
||||||
if (matches == null) {
|
if (matches == null) {
|
||||||
matches = new Vector(3); // lazy init
|
matches = new ArrayList<String>(3); // lazy init
|
||||||
}
|
}
|
||||||
String element = unescapeBackslash(rawText.substring(start, i));
|
String element = unescapeBackslash(rawText.substring(start, i));
|
||||||
if (trim) {
|
if (trim) {
|
||||||
element = element.trim();
|
element = element.trim();
|
||||||
}
|
}
|
||||||
matches.addElement(element);
|
matches.add(element);
|
||||||
i++;
|
i++;
|
||||||
done = true;
|
more = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (matches == null || matches.isEmpty()) {
|
if (matches == null || matches.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return toStringArray(matches);
|
return matches.toArray(new String[matches.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String matchSinglePrefixedField(String prefix, String rawText, char endChar, boolean trim) {
|
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];
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,10 @@ package com.google.zxing.client.result;
|
||||||
|
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.ArrayList;
|
||||||
import java.util.Vector;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Parses an "sms:" URI result, which specifies a number to SMS.
|
* <p>Parses an "sms:" URI result, which specifies a number to SMS.
|
||||||
|
@ -36,12 +38,10 @@ import java.util.Vector;
|
||||||
*
|
*
|
||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
final class SMSMMSResultParser extends ResultParser {
|
public final class SMSMMSResultParser extends ResultParser {
|
||||||
|
|
||||||
private SMSMMSResultParser() {
|
@Override
|
||||||
}
|
public SMSParsedResult parse(Result result) {
|
||||||
|
|
||||||
public static SMSParsedResult parse(Result result) {
|
|
||||||
String rawText = result.getText();
|
String rawText = result.getText();
|
||||||
if (!(rawText.startsWith("sms:") || rawText.startsWith("SMS:") ||
|
if (!(rawText.startsWith("sms:") || rawText.startsWith("SMS:") ||
|
||||||
rawText.startsWith("mms:") || rawText.startsWith("MMS:"))) {
|
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
|
// 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 subject = null;
|
||||||
String body = null;
|
String body = null;
|
||||||
boolean querySyntax = false;
|
boolean querySyntax = false;
|
||||||
if (nameValuePairs != null && !nameValuePairs.isEmpty()) {
|
if (nameValuePairs != null && !nameValuePairs.isEmpty()) {
|
||||||
subject = (String) nameValuePairs.get("subject");
|
subject = nameValuePairs.get("subject");
|
||||||
body = (String) nameValuePairs.get("body");
|
body = nameValuePairs.get("body");
|
||||||
querySyntax = true;
|
querySyntax = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +71,8 @@ final class SMSMMSResultParser extends ResultParser {
|
||||||
|
|
||||||
int lastComma = -1;
|
int lastComma = -1;
|
||||||
int comma;
|
int comma;
|
||||||
Vector numbers = new Vector(1);
|
List<String> numbers = new ArrayList<String>(1);
|
||||||
Vector vias = new Vector(1);
|
List<String> vias = new ArrayList<String>(1);
|
||||||
while ((comma = smsURIWithoutQuery.indexOf(',', lastComma + 1)) > lastComma) {
|
while ((comma = smsURIWithoutQuery.indexOf(',', lastComma + 1)) > lastComma) {
|
||||||
String numberPart = smsURIWithoutQuery.substring(lastComma + 1, comma);
|
String numberPart = smsURIWithoutQuery.substring(lastComma + 1, comma);
|
||||||
addNumberVia(numbers, vias, numberPart);
|
addNumberVia(numbers, vias, numberPart);
|
||||||
|
@ -80,16 +80,21 @@ final class SMSMMSResultParser extends ResultParser {
|
||||||
}
|
}
|
||||||
addNumberVia(numbers, vias, smsURIWithoutQuery.substring(lastComma + 1));
|
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(';');
|
int numberEnd = numberPart.indexOf(';');
|
||||||
if (numberEnd < 0) {
|
if (numberEnd < 0) {
|
||||||
numbers.addElement(numberPart);
|
numbers.add(numberPart);
|
||||||
vias.addElement(null);
|
vias.add(null);
|
||||||
} else {
|
} else {
|
||||||
numbers.addElement(numberPart.substring(0, numberEnd));
|
numbers.add(numberPart.substring(0, numberEnd));
|
||||||
String maybeVia = numberPart.substring(numberEnd + 1);
|
String maybeVia = numberPart.substring(numberEnd + 1);
|
||||||
String via;
|
String via;
|
||||||
if (maybeVia.startsWith("via=")) {
|
if (maybeVia.startsWith("via=")) {
|
||||||
|
@ -97,7 +102,7 @@ final class SMSMMSResultParser extends ResultParser {
|
||||||
} else {
|
} else {
|
||||||
via = null;
|
via = null;
|
||||||
}
|
}
|
||||||
vias.addElement(via);
|
vias.add(via);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,10 @@ public final class SMSParsedResult extends ParsedResult {
|
||||||
private final String subject;
|
private final String subject;
|
||||||
private final String body;
|
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);
|
super(ParsedResultType.SMS);
|
||||||
this.numbers = new String[] {number};
|
this.numbers = new String[] {number};
|
||||||
this.vias = new String[] {via};
|
this.vias = new String[] {via};
|
||||||
|
@ -34,7 +37,10 @@ public final class SMSParsedResult extends ParsedResult {
|
||||||
this.body = body;
|
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);
|
super(ParsedResultType.SMS);
|
||||||
this.numbers = numbers;
|
this.numbers = numbers;
|
||||||
this.vias = vias;
|
this.vias = vias;
|
||||||
|
@ -43,7 +49,7 @@ public final class SMSParsedResult extends ParsedResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSMSURI() {
|
public String getSMSURI() {
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuilder result = new StringBuilder();
|
||||||
result.append("sms:");
|
result.append("sms:");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (int i = 0; i < numbers.length; i++) {
|
for (int i = 0; i < numbers.length; i++) {
|
||||||
|
@ -93,8 +99,9 @@ public final class SMSParsedResult extends ParsedResult {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayResult() {
|
public String getDisplayResult() {
|
||||||
StringBuffer result = new StringBuffer(100);
|
StringBuilder result = new StringBuilder(100);
|
||||||
maybeAppend(numbers, result);
|
maybeAppend(numbers, result);
|
||||||
maybeAppend(subject, result);
|
maybeAppend(subject, result);
|
||||||
maybeAppend(body, result);
|
maybeAppend(body, result);
|
||||||
|
|
|
@ -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:
|
* <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
|
* <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
|
* "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
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
final class SMSTOMMSTOResultParser extends ResultParser {
|
public final class SMSTOMMSTOResultParser extends ResultParser {
|
||||||
|
|
||||||
private SMSTOMMSTOResultParser() {
|
@Override
|
||||||
}
|
public SMSParsedResult parse(Result result) {
|
||||||
|
|
||||||
public static SMSParsedResult parse(Result result) {
|
|
||||||
String rawText = result.getText();
|
String rawText = result.getText();
|
||||||
if (!(rawText.startsWith("smsto:") || rawText.startsWith("SMSTO:") ||
|
if (!(rawText.startsWith("smsto:") || rawText.startsWith("SMSTO:") ||
|
||||||
rawText.startsWith("mmsto:") || rawText.startsWith("MMSTO:"))) {
|
rawText.startsWith("mmsto:") || rawText.startsWith("MMSTO:"))) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue