import android.app.Activity;
import android.content.Context;
-import android.graphics.PixelFormat;
+import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
import android.view.Window;
-import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+import android.widget.TextView;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.result.ParsedReaderResult;
private CameraManager cameraManager;
private CameraSurfaceView surfaceView;
- private WorkerThread workerThread;
+ private CameraThread cameraThread;
+ private String lastResult;
private static final int ABOUT_ID = Menu.FIRST;
+ private static final int HELP_ID = Menu.FIRST + 1;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
- // Make sure to create a TRANSLUCENT window. This is required for SurfaceView to work.
- // Eventually this'll be done by the system automatically.
- getWindow().setAttributes(new LayoutParams(LayoutParams.APPLICATION_TYPE,
- LayoutParams.NO_STATUS_BAR_FLAG));
- getWindow().setFormat(PixelFormat.TRANSLUCENT);
+ setContentView(R.layout.main);
cameraManager = new CameraManager(getApplication());
surfaceView = new CameraSurfaceView(getApplication(), cameraManager);
- setContentView(surfaceView);
- workerThread = new WorkerThread(surfaceView, cameraManager, messageHandler);
- workerThread.requestPreviewLoop();
- workerThread.start();
+ surfaceView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ ViewGroup previewView = (ViewGroup) findViewById(R.id.preview_view);
+ previewView.addView(surfaceView);
+ cameraThread = null;
// TODO re-enable this when issues with Matrix.setPolyToPoly() are resolved
//GridSampler.setGridSampler(new AndroidGraphicsGridSampler());
}
- @Override
- protected boolean isFullscreenOpaque() {
- // Our main window is set to translucent, but we know that we will
- // fill it with opaque data. Tell the system that so it can perform
- // some important optimizations.
- return true;
- }
-
@Override
protected void onResume() {
super.onResume();
+ resetStatusView();
cameraManager.openDriver();
- if (workerThread == null) {
- workerThread = new WorkerThread(surfaceView, cameraManager, messageHandler);
- workerThread.requestPreviewLoop();
- workerThread.start();
+ if (cameraThread == null) {
+ cameraThread = new CameraThread(this, surfaceView, cameraManager, messageHandler);
+ cameraThread.start();
}
}
@Override
protected void onPause() {
super.onPause();
- if (workerThread != null) {
- workerThread.requestExitAndWait();
- workerThread = null;
+ if (cameraThread != null) {
+ cameraThread.quitSynchronously();
+ cameraThread = null;
}
cameraManager.closeDriver();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- workerThread.requestStillAndDecode();
- return true;
+ if (keyCode == KeyEvent.KEYCODE_A) {
+ cameraThread.setDecodeAllMode();
+ } else if (keyCode == KeyEvent.KEYCODE_C) {
+ Message save = Message.obtain(cameraThread.handler, R.id.save);
+ save.sendToTarget();
+ } else if (keyCode == KeyEvent.KEYCODE_P) {
+ cameraManager.setUsePreviewForDecode(true);
+ } else if (keyCode == KeyEvent.KEYCODE_Q) {
+ cameraThread.setDecodeQRMode();
+ } else if (keyCode == KeyEvent.KEYCODE_S) {
+ cameraManager.setUsePreviewForDecode(false);
+ } else if (keyCode == KeyEvent.KEYCODE_T) {
+ cameraThread.toggleTracing();
+ } else if (keyCode == KeyEvent.KEYCODE_U) {
+ cameraThread.setDecode1DMode();
} else {
return super.onKeyDown(keyCode, event);
}
+ return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, ABOUT_ID, R.string.menu_about);
+ menu.add(0, HELP_ID, R.string.menu_help);
return true;
}
@Override
public boolean onOptionsItemSelected(Menu.Item item) {
+ Context context = getApplication();
switch (item.getId()) {
case ABOUT_ID:
- Context context = getApplication();
- showAlert(context.getString(R.string.title_about),
- context.getString(R.string.msg_about),
- context.getString(R.string.button_ok), null, true, null);
+ showAlert(context.getString(R.string.title_about), 0,
+ context.getString(R.string.msg_about),
+ context.getString(R.string.button_ok),
+ true);
+ break;
+ case HELP_ID:
+ showAlert(context.getString(R.string.title_help), 0,
+ context.getString(R.string.msg_help),
+ context.getString(R.string.button_ok), true);
break;
}
return super.onOptionsItemSelected(item);
@Override
public void handleMessage(Message message) {
switch (message.what) {
- case R.id.decoding_succeeded_message:
- handleDecode((Result) message.obj);
+ case R.id.decode_succeeded:
+ int duration = message.arg1;
+ handleDecode((Result) message.obj, duration);
break;
- case R.id.decoding_failed_message:
- Context context = getApplication();
- showAlert(context.getString(R.string.title_no_barcode_detected),
- context.getString(R.string.msg_no_barcode_detected),
- context.getString(R.string.button_ok), null, true, null);
+ case R.id.restart_preview:
+ restartPreview();
break;
}
}
};
public void restartPreview() {
- workerThread.requestPreviewLoop();
+ Message restart = Message.obtain(cameraThread.handler, R.id.restart_preview);
+ restart.sendToTarget();
}
- // TODO(dswitkin): These deprecated showAlert calls need to be updated.
- private void handleDecode(Result rawResult) {
- ResultPoint[] points = rawResult.getResultPoints();
- if (points != null && points.length > 0) {
- surfaceView.drawResultPoints(points);
- }
+ private void handleDecode(Result rawResult, int duration) {
+ if (!rawResult.toString().equals(lastResult)) {
+ lastResult = rawResult.toString();
- Context context = getApplication();
- ParsedReaderResult readerResult = parseReaderResult(rawResult);
- Handler handler = new ResultHandler(this, readerResult);
- if (canBeHandled(readerResult.getType())) {
- // Can be handled by some external app; ask if the user wants to
- // proceed first though
- Message yesMessage = handler.obtainMessage(R.string.button_yes);
- Message noMessage = handler.obtainMessage(R.string.button_no);
- showAlert(context.getString(getDialogTitleID(readerResult.getType())),
- readerResult.getDisplayResult(), context.getString(R.string.button_yes),
- yesMessage, context.getString(R.string.button_no), noMessage, true, noMessage);
+ ResultPoint[] points = rawResult.getResultPoints();
+ if (points != null && points.length > 0) {
+ surfaceView.drawResultPoints(points);
+ }
+
+ TextView textView = (TextView) findViewById(R.id.status_text_view);
+ ParsedReaderResult readerResult = parseReaderResult(rawResult);
+ textView.setText(readerResult.getDisplayResult() + " (" + duration + " ms)");
+
+ Button actionButton = (Button) findViewById(R.id.status_action_button);
+ int buttonText = getActionButtonText(readerResult.getType());
+ if (buttonText != 0) {
+ actionButton.setVisibility(View.VISIBLE);
+ actionButton.setText(buttonText);
+ ResultHandler handler = new ResultHandler(this, readerResult);
+ actionButton.setOnClickListener(handler);
+ actionButton.requestFocus();
+ } else {
+ actionButton.setVisibility(View.GONE);
+ }
+
+ // Show the green finder patterns for one second, then restart the preview
+ Message message = Message.obtain(messageHandler, R.id.restart_preview);
+ messageHandler.sendMessageDelayed(message, 1000);
} else {
- // Just show information to user
- Message okMessage = handler.obtainMessage(R.string.button_ok);
- showAlert(context.getString(R.string.title_barcode_detected),
- readerResult.getDisplayResult(), context.getString(R.string.button_ok), okMessage, null,
- null, true, okMessage);
+ restartPreview();
}
}
+ private void resetStatusView() {
+ TextView textView = (TextView) findViewById(R.id.status_text_view);
+ textView.setText(R.string.msg_default_status);
+ Button actionButton = (Button) findViewById(R.id.status_action_button);
+ actionButton.setVisibility(View.GONE);
+ lastResult = "";
+ }
+
private static ParsedReaderResult parseReaderResult(Result rawResult) {
- String rawText = rawResult.getText();
- ParsedReaderResult readerResult = ParsedReaderResult.parseReaderResult(rawText);
+ ParsedReaderResult readerResult = ParsedReaderResult.parseReaderResult(rawResult);
if (readerResult.getType().equals(ParsedReaderResultType.TEXT)) {
- ParsedReaderResult androidResult = AndroidIntentParsedResult.parse(rawText);
+ String rawText = rawResult.getText();
+ AndroidIntentParsedResult androidResult = AndroidIntentParsedResult.parse(rawText);
if (androidResult != null) {
- readerResult = androidResult;
+ Intent intent = androidResult.getIntent();
+ if (!Intent.VIEW_ACTION.equals(intent.getAction())) {
+ // For now, don't take anything that just parses as a View action. A lot
+ // of things are accepted as a View action by default.
+ readerResult = androidResult;
+ }
}
}
return readerResult;
}
- private static boolean canBeHandled(ParsedReaderResultType type) {
- return !type.equals(ParsedReaderResultType.TEXT);
- }
-
- private static int getDialogTitleID(ParsedReaderResultType type) {
+ private static int getActionButtonText(ParsedReaderResultType type) {
+ int buttonText;
if (type.equals(ParsedReaderResultType.ADDRESSBOOK)) {
- return R.string.title_add_contact;
+ buttonText = R.string.button_add_contact;
} else if (type.equals(ParsedReaderResultType.URI) ||
type.equals(ParsedReaderResultType.BOOKMARK) ||
type.equals(ParsedReaderResultType.URLTO)) {
- return R.string.title_open_url;
+ buttonText = R.string.button_open_browser;
} else if (type.equals(ParsedReaderResultType.EMAIL) ||
type.equals(ParsedReaderResultType.EMAIL_ADDRESS)) {
- return R.string.title_compose_email;
+ buttonText = R.string.button_email;
} else if (type.equals(ParsedReaderResultType.UPC)) {
- return R.string.title_lookup_barcode;
+ buttonText = R.string.button_lookup_product;
+ } else if (type.equals(ParsedReaderResultType.TEL)) {
+ buttonText = R.string.button_dial;
+ } else if (type.equals(ParsedReaderResultType.GEO)) {
+ buttonText = R.string.button_show_map;
} else {
- return R.string.title_barcode_detected;
+ buttonText = 0;
}
+ return buttonText;
}
}
\ No newline at end of file