mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Somehow the IntelliJ Subversion integration did not commit these deleted files when I did the rename.
git-svn-id: https://zxing.googlecode.com/svn/trunk@684 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
9de8f5e1f0
commit
5a26635782
|
@ -1,420 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 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.android;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.res.AssetFileDescriptor;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.media.MediaPlayer;
|
|
||||||
import android.media.MediaPlayer.OnCompletionListener;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.text.SpannableStringBuilder;
|
|
||||||
import android.text.style.UnderlineSpan;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
import android.view.SurfaceView;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import com.google.zxing.Result;
|
|
||||||
import com.google.zxing.ResultPoint;
|
|
||||||
import com.google.zxing.client.android.result.ResultButtonListener;
|
|
||||||
import com.google.zxing.client.android.result.ResultHandler;
|
|
||||||
import com.google.zxing.client.android.result.ResultHandlerFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The barcode reader activity itself. This is loosely based on the CameraPreview
|
|
||||||
* example included in the Android SDK.
|
|
||||||
*/
|
|
||||||
public final class BarcodesCaptureActivity extends Activity implements SurfaceHolder.Callback {
|
|
||||||
|
|
||||||
private static final int SHARE_ID = Menu.FIRST;
|
|
||||||
private static final int SETTINGS_ID = Menu.FIRST + 1;
|
|
||||||
private static final int HELP_ID = Menu.FIRST + 2;
|
|
||||||
private static final int ABOUT_ID = Menu.FIRST + 3;
|
|
||||||
|
|
||||||
private static final int MAX_RESULT_IMAGE_SIZE = 150;
|
|
||||||
private static final int INTENT_RESULT_DURATION = 1500;
|
|
||||||
private static final float BEEP_VOLUME = 0.15f;
|
|
||||||
|
|
||||||
public BarcodesCaptureActivityHandler mHandler;
|
|
||||||
|
|
||||||
private ViewfinderView mViewfinderView;
|
|
||||||
private View mStatusView;
|
|
||||||
private View mResultView;
|
|
||||||
private MediaPlayer mMediaPlayer;
|
|
||||||
private Result mLastResult;
|
|
||||||
private boolean mHasSurface;
|
|
||||||
private boolean mPlayBeep;
|
|
||||||
private boolean mScanIntent;
|
|
||||||
private String mDecodeMode;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle icicle) {
|
|
||||||
super.onCreate(icicle);
|
|
||||||
|
|
||||||
Window window = getWindow();
|
|
||||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
setContentView(R.layout.capture);
|
|
||||||
|
|
||||||
CameraManager.init(getApplication());
|
|
||||||
mViewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
|
|
||||||
mResultView = findViewById(R.id.result_view);
|
|
||||||
mStatusView = findViewById(R.id.status_view);
|
|
||||||
mHandler = null;
|
|
||||||
mLastResult = null;
|
|
||||||
mHasSurface = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
|
|
||||||
SurfaceHolder surfaceHolder = surfaceView.getHolder();
|
|
||||||
if (mHasSurface) {
|
|
||||||
// The activity was paused but not stopped, so the surface still exists. Therefore
|
|
||||||
// surfaceCreated() won't be called, so init the camera here.
|
|
||||||
initCamera(surfaceHolder);
|
|
||||||
} else {
|
|
||||||
// Install the callback and wait for surfaceCreated() to init the camera.
|
|
||||||
surfaceHolder.addCallback(this);
|
|
||||||
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent intent = getIntent();
|
|
||||||
if (intent != null && (intent.getAction().equals(Intents.Scan.ACTION) ||
|
|
||||||
intent.getAction().equals(Intents.Scan.DEPRECATED_ACTION))) {
|
|
||||||
mScanIntent = true;
|
|
||||||
mDecodeMode = intent.getStringExtra(Intents.Scan.MODE);
|
|
||||||
resetStatusView();
|
|
||||||
} else {
|
|
||||||
mScanIntent = false;
|
|
||||||
mDecodeMode = null;
|
|
||||||
if (mLastResult == null) {
|
|
||||||
resetStatusView();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
mPlayBeep = prefs.getBoolean(BarcodesPreferenceActivity.KEY_PLAY_BEEP, true);
|
|
||||||
initBeepSound();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
if (mHandler != null) {
|
|
||||||
mHandler.quitSynchronously();
|
|
||||||
mHandler = null;
|
|
||||||
}
|
|
||||||
CameraManager.get().closeDriver();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
|
||||||
if (mScanIntent) {
|
|
||||||
setResult(RESULT_CANCELED);
|
|
||||||
finish();
|
|
||||||
return true;
|
|
||||||
} else if (mLastResult != null) {
|
|
||||||
resetStatusView();
|
|
||||||
mHandler.sendEmptyMessage(R.id.restart_preview);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_FOCUS || keyCode == KeyEvent.KEYCODE_CAMERA) {
|
|
||||||
// Handle these events so they don't launch the Camera app
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onKeyDown(keyCode, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
super.onCreateOptionsMenu(menu);
|
|
||||||
menu.add(0, SHARE_ID, 0, R.string.menu_share).setIcon(R.drawable.share_barcode);
|
|
||||||
menu.add(0, SETTINGS_ID, 0, R.string.menu_settings)
|
|
||||||
.setIcon(android.R.drawable.ic_menu_preferences);
|
|
||||||
menu.add(0, HELP_ID, 0, R.string.menu_help)
|
|
||||||
.setIcon(android.R.drawable.ic_menu_help);
|
|
||||||
menu.add(0, ABOUT_ID, 0, R.string.menu_about)
|
|
||||||
.setIcon(android.R.drawable.ic_menu_info_details);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case SHARE_ID: {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
intent.setClassName(this, ShareActivity.class.getName());
|
|
||||||
startActivity(intent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SETTINGS_ID: {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
intent.setClassName(this, BarcodesPreferenceActivity.class.getName());
|
|
||||||
startActivity(intent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case HELP_ID: {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle(R.string.title_help);
|
|
||||||
builder.setMessage(R.string.msg_help);
|
|
||||||
builder.setPositiveButton(R.string.button_ok, null);
|
|
||||||
builder.show();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ABOUT_ID: {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle(R.string.title_about);
|
|
||||||
builder.setMessage(getString(R.string.msg_about) + "\n\n" + getString(R.string.zxing_url));
|
|
||||||
builder.setIcon(R.drawable.zxing_icon);
|
|
||||||
builder.setPositiveButton(R.string.button_open_browser, mAboutListener);
|
|
||||||
builder.setNegativeButton(R.string.button_cancel, null);
|
|
||||||
builder.show();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigurationChanged(Configuration config) {
|
|
||||||
// Do nothing, this is to prevent the activity from being restarted when the keyboard opens.
|
|
||||||
super.onConfigurationChanged(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final DialogInterface.OnClickListener mAboutListener = new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(android.content.DialogInterface dialogInterface, int i) {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.zxing_url)));
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
|
||||||
if (!mHasSurface) {
|
|
||||||
mHasSurface = true;
|
|
||||||
initCamera(holder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
|
||||||
mHasSurface = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A valid barcode has been found, so give an indication of success and show the results.
|
|
||||||
*
|
|
||||||
* @param rawResult The contents of the barcode.
|
|
||||||
* @param barcode A greyscale bitmap of the camera data which was decoded.
|
|
||||||
* @param duration How long the decoding took in milliseconds.
|
|
||||||
*/
|
|
||||||
public void handleDecode(Result rawResult, Bitmap barcode, int duration) {
|
|
||||||
mLastResult = rawResult;
|
|
||||||
playBeepSound();
|
|
||||||
drawResultPoints(barcode, rawResult);
|
|
||||||
|
|
||||||
if (mScanIntent) {
|
|
||||||
handleDecodeForScanIntent(rawResult, barcode, duration);
|
|
||||||
} else {
|
|
||||||
mStatusView.setVisibility(View.GONE);
|
|
||||||
mViewfinderView.setVisibility(View.GONE);
|
|
||||||
mResultView.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view);
|
|
||||||
barcodeImageView.setMaxWidth(MAX_RESULT_IMAGE_SIZE);
|
|
||||||
barcodeImageView.setMaxHeight(MAX_RESULT_IMAGE_SIZE);
|
|
||||||
barcodeImageView.setImageBitmap(barcode);
|
|
||||||
|
|
||||||
TextView formatTextView = (TextView) findViewById(R.id.format_text_view);
|
|
||||||
formatTextView.setText(getString(R.string.msg_default_format) + ": " +
|
|
||||||
rawResult.getBarcodeFormat().toString());
|
|
||||||
|
|
||||||
ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
|
|
||||||
TextView typeTextView = (TextView) findViewById(R.id.type_text_view);
|
|
||||||
typeTextView.setText(getString(R.string.msg_default_type) + ": " +
|
|
||||||
resultHandler.getType().toString());
|
|
||||||
|
|
||||||
TextView contentsTextView = (TextView) findViewById(R.id.contents_text_view);
|
|
||||||
CharSequence title = getString(resultHandler.getDisplayTitle());
|
|
||||||
SpannableStringBuilder styled = new SpannableStringBuilder(title + "\n\n");
|
|
||||||
styled.setSpan(new UnderlineSpan(), 0, title.length(), 0);
|
|
||||||
styled.append(resultHandler.getDisplayContents());
|
|
||||||
contentsTextView.setText(styled);
|
|
||||||
|
|
||||||
int buttonCount = resultHandler.getButtonCount();
|
|
||||||
ViewGroup buttonView = (ViewGroup) findViewById(R.id.result_button_view);
|
|
||||||
buttonView.requestFocus();
|
|
||||||
for (int x = 0; x < ResultHandler.MAX_BUTTON_COUNT; x++) {
|
|
||||||
Button button = (Button) buttonView.getChildAt(x);
|
|
||||||
if (x < buttonCount) {
|
|
||||||
button.setVisibility(View.VISIBLE);
|
|
||||||
button.setText(resultHandler.getButtonText(x));
|
|
||||||
button.setOnClickListener(new ResultButtonListener(resultHandler, x));
|
|
||||||
} else {
|
|
||||||
button.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Superimpose a line for 1D or dots for 2D to highlight the key features of the barcode.
|
|
||||||
*
|
|
||||||
* @param barcode A bitmap of the captured image.
|
|
||||||
* @param rawResult The decoded results which contains the points to draw.
|
|
||||||
*/
|
|
||||||
private void drawResultPoints(Bitmap barcode, Result rawResult) {
|
|
||||||
ResultPoint[] points = rawResult.getResultPoints();
|
|
||||||
if (points != null && points.length > 0) {
|
|
||||||
Canvas canvas = new Canvas(barcode);
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setColor(getResources().getColor(R.color.result_image_border));
|
|
||||||
paint.setStrokeWidth(3);
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
Rect border = new Rect(2, 2, barcode.getWidth() - 2, barcode.getHeight() - 2);
|
|
||||||
canvas.drawRect(border, paint);
|
|
||||||
|
|
||||||
paint.setColor(getResources().getColor(R.color.result_points));
|
|
||||||
if (points.length == 2) {
|
|
||||||
paint.setStrokeWidth(4);
|
|
||||||
canvas.drawLine(points[0].getX(), points[0].getY(), points[1].getX(),
|
|
||||||
points[1].getY(), paint);
|
|
||||||
} else {
|
|
||||||
paint.setStrokeWidth(10);
|
|
||||||
for (int x = 0; x < points.length; x++) {
|
|
||||||
canvas.drawPoint(points[x].getX(), points[x].getY(), paint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleDecodeForScanIntent(Result rawResult, Bitmap barcode, int duration) {
|
|
||||||
mViewfinderView.drawResultBitmap(barcode);
|
|
||||||
|
|
||||||
// Since this message will only be shown for a second, just tell the user what kind of
|
|
||||||
// barcode was found (e.g. contact info) rather than the full contents, which they won't
|
|
||||||
// have time to read.
|
|
||||||
ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
|
|
||||||
TextView textView = (TextView) findViewById(R.id.status_text_view);
|
|
||||||
textView.setGravity(Gravity.CENTER);
|
|
||||||
textView.setTextSize(18.0f);
|
|
||||||
textView.setText(getString(resultHandler.getDisplayTitle()));
|
|
||||||
|
|
||||||
mStatusView.setBackgroundColor(getResources().getColor(R.color.transparent));
|
|
||||||
|
|
||||||
// Hand back whatever action they requested - this can be changed to Intents.Scan.ACTION when
|
|
||||||
// the deprecated intent is retired.
|
|
||||||
Intent intent = new Intent(getIntent().getAction());
|
|
||||||
intent.putExtra(Intents.Scan.RESULT, rawResult.toString());
|
|
||||||
intent.putExtra(Intents.Scan.RESULT_FORMAT, rawResult.getBarcodeFormat().toString());
|
|
||||||
Message message = Message.obtain(mHandler, R.id.return_scan_result);
|
|
||||||
message.obj = intent;
|
|
||||||
mHandler.sendMessageDelayed(message, INTENT_RESULT_DURATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the beep MediaPlayer in advance so that the sound can be triggered with the least
|
|
||||||
* latency possible.
|
|
||||||
*/
|
|
||||||
private void initBeepSound() {
|
|
||||||
if (mPlayBeep && mMediaPlayer == null) {
|
|
||||||
mMediaPlayer = new MediaPlayer();
|
|
||||||
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_SYSTEM);
|
|
||||||
mMediaPlayer.setOnCompletionListener(mBeepListener);
|
|
||||||
|
|
||||||
AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.beep);
|
|
||||||
try {
|
|
||||||
mMediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(),
|
|
||||||
file.getLength());
|
|
||||||
file.close();
|
|
||||||
mMediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
|
|
||||||
mMediaPlayer.prepare();
|
|
||||||
} catch (IOException e) {
|
|
||||||
mMediaPlayer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playBeepSound() {
|
|
||||||
if (mPlayBeep && mMediaPlayer != null) {
|
|
||||||
mMediaPlayer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initCamera(SurfaceHolder surfaceHolder) {
|
|
||||||
CameraManager.get().openDriver(surfaceHolder);
|
|
||||||
if (mHandler == null) {
|
|
||||||
boolean beginScanning = mLastResult == null;
|
|
||||||
mHandler = new BarcodesCaptureActivityHandler(this, mDecodeMode, beginScanning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When the beep has finished playing, rewind to queue up another one.
|
|
||||||
*/
|
|
||||||
private final OnCompletionListener mBeepListener = new OnCompletionListener() {
|
|
||||||
public void onCompletion(MediaPlayer mediaPlayer) {
|
|
||||||
mediaPlayer.seekTo(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void resetStatusView() {
|
|
||||||
mResultView.setVisibility(View.GONE);
|
|
||||||
mStatusView.setVisibility(View.VISIBLE);
|
|
||||||
mStatusView.setBackgroundColor(getResources().getColor(R.color.status_view));
|
|
||||||
mViewfinderView.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
TextView textView = (TextView) findViewById(R.id.status_text_view);
|
|
||||||
textView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
|
|
||||||
textView.setTextSize(14.0f);
|
|
||||||
textView.setText(R.string.msg_default_status);
|
|
||||||
mLastResult = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawViewfinder() {
|
|
||||||
mViewfinderView.drawViewfinder();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 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.android;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import com.google.zxing.Result;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class handles all the messaging which comprises the state machine for capture.
|
|
||||||
*/
|
|
||||||
public class BarcodesCaptureActivityHandler extends Handler {
|
|
||||||
|
|
||||||
private final BarcodesCaptureActivity mActivity;
|
|
||||||
private final DecodeThread mDecodeThread;
|
|
||||||
private State mState;
|
|
||||||
|
|
||||||
private enum State {
|
|
||||||
PREVIEW,
|
|
||||||
SUCCESS,
|
|
||||||
DONE
|
|
||||||
}
|
|
||||||
|
|
||||||
BarcodesCaptureActivityHandler(BarcodesCaptureActivity activity, String decodeMode,
|
|
||||||
boolean beginScanning) {
|
|
||||||
mActivity = activity;
|
|
||||||
mDecodeThread = new DecodeThread(activity, decodeMode);
|
|
||||||
mDecodeThread.start();
|
|
||||||
mState = State.SUCCESS;
|
|
||||||
|
|
||||||
// Start ourselves capturing previews and decoding.
|
|
||||||
CameraManager.get().startPreview();
|
|
||||||
if (beginScanning) {
|
|
||||||
restartPreviewAndDecode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleMessage(Message message) {
|
|
||||||
switch (message.what) {
|
|
||||||
case R.id.auto_focus:
|
|
||||||
// When one auto focus pass finishes, start another. This is the closest thing to
|
|
||||||
// continuous AF. It does seem to hunt a bit, but I'm not sure what else to do.
|
|
||||||
if (mState == State.PREVIEW) {
|
|
||||||
CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case R.id.restart_preview:
|
|
||||||
restartPreviewAndDecode();
|
|
||||||
break;
|
|
||||||
case R.id.decode_succeeded:
|
|
||||||
mState = State.SUCCESS;
|
|
||||||
Bundle bundle = message.getData();
|
|
||||||
Bitmap barcode = bundle.getParcelable(DecodeThread.BARCODE_BITMAP);
|
|
||||||
int duration = message.arg1;
|
|
||||||
mActivity.handleDecode((Result) message.obj, barcode, duration);
|
|
||||||
break;
|
|
||||||
case R.id.decode_failed:
|
|
||||||
// We're decoding as fast as possible, so when one decode fails, start another.
|
|
||||||
mState = State.PREVIEW;
|
|
||||||
CameraManager.get().requestPreviewFrame(mDecodeThread.mHandler, R.id.decode);
|
|
||||||
break;
|
|
||||||
case R.id.return_scan_result:
|
|
||||||
mActivity.setResult(Activity.RESULT_OK, (Intent) message.obj);
|
|
||||||
mActivity.finish();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void quitSynchronously() {
|
|
||||||
mState = State.DONE;
|
|
||||||
CameraManager.get().stopPreview();
|
|
||||||
Message quit = Message.obtain(mDecodeThread.mHandler, R.id.quit);
|
|
||||||
quit.sendToTarget();
|
|
||||||
try {
|
|
||||||
mDecodeThread.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Be absolutely sure we don't send any queued up messages
|
|
||||||
removeMessages(R.id.decode_succeeded);
|
|
||||||
removeMessages(R.id.decode_failed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void restartPreviewAndDecode() {
|
|
||||||
if (mState == State.SUCCESS) {
|
|
||||||
mState = State.PREVIEW;
|
|
||||||
CameraManager.get().requestPreviewFrame(mDecodeThread.mHandler, R.id.decode);
|
|
||||||
CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
|
|
||||||
mActivity.drawViewfinder();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 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.android;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.ProgressDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.DialogInterface.OnCancelListener;
|
|
||||||
import android.content.DialogInterface.OnClickListener;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class encodes data from an Intent into a QR code, and then displays it full screen so that
|
|
||||||
* another person can scan it with their device.
|
|
||||||
*/
|
|
||||||
public class BarcodesEncodeActivity extends Activity {
|
|
||||||
|
|
||||||
private QRCodeEncoder mQRCodeEncoder;
|
|
||||||
private ProgressDialog mProgressDialog;
|
|
||||||
private boolean mFirstLayout;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle icicle) {
|
|
||||||
super.onCreate(icicle);
|
|
||||||
|
|
||||||
Intent intent = getIntent();
|
|
||||||
if (intent != null && (intent.getAction().equals(Intents.Encode.ACTION) ||
|
|
||||||
intent.getAction().equals(Intents.Encode.DEPRECATED_ACTION))) {
|
|
||||||
setContentView(R.layout.encode);
|
|
||||||
} else {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
LinearLayout layout = (LinearLayout) findViewById(R.id.encode_view);
|
|
||||||
layout.getViewTreeObserver().addOnGlobalLayoutListener(mLayoutListener);
|
|
||||||
mFirstLayout = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This needs to be delayed until after the first layout so that the view dimensions will be
|
|
||||||
* available.
|
|
||||||
*/
|
|
||||||
public OnGlobalLayoutListener mLayoutListener = new OnGlobalLayoutListener() {
|
|
||||||
public void onGlobalLayout() {
|
|
||||||
if (mFirstLayout) {
|
|
||||||
LinearLayout layout = (LinearLayout) findViewById(R.id.encode_view);
|
|
||||||
int width = layout.getWidth();
|
|
||||||
int height = layout.getHeight();
|
|
||||||
int smallerDimension = (width < height) ? width : height;
|
|
||||||
smallerDimension = smallerDimension * 7 / 8;
|
|
||||||
|
|
||||||
Intent intent = getIntent();
|
|
||||||
try {
|
|
||||||
mQRCodeEncoder = new QRCodeEncoder(BarcodesEncodeActivity.this, intent);
|
|
||||||
setTitle(getString(R.string.app_name) + " - " + mQRCodeEncoder.getTitle());
|
|
||||||
mQRCodeEncoder.requestBarcode(mHandler, smallerDimension);
|
|
||||||
mProgressDialog = ProgressDialog.show(BarcodesEncodeActivity.this, null,
|
|
||||||
getString(R.string.msg_encode_in_progress), true, true, mCancelListener);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
showErrorMessage(R.string.msg_encode_contents_failed);
|
|
||||||
}
|
|
||||||
mFirstLayout = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public Handler mHandler = new Handler() {
|
|
||||||
public void handleMessage(Message message) {
|
|
||||||
switch (message.what) {
|
|
||||||
case R.id.encode_succeeded:
|
|
||||||
mProgressDialog.dismiss();
|
|
||||||
mProgressDialog = null;
|
|
||||||
Bitmap image = (Bitmap) message.obj;
|
|
||||||
ImageView view = (ImageView) findViewById(R.id.image_view);
|
|
||||||
view.setImageBitmap(image);
|
|
||||||
TextView contents = (TextView) findViewById(R.id.contents_text_view);
|
|
||||||
contents.setText(mQRCodeEncoder.getDisplayContents());
|
|
||||||
mQRCodeEncoder = null;
|
|
||||||
break;
|
|
||||||
case R.id.encode_failed:
|
|
||||||
showErrorMessage(R.string.msg_encode_barcode_failed);
|
|
||||||
mQRCodeEncoder = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void showErrorMessage(int message) {
|
|
||||||
if (mProgressDialog != null) {
|
|
||||||
mProgressDialog.dismiss();
|
|
||||||
mProgressDialog = null;
|
|
||||||
}
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setMessage(message);
|
|
||||||
builder.setPositiveButton(R.string.button_ok, mClickListener);
|
|
||||||
builder.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private OnClickListener mClickListener = new OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private OnCancelListener mCancelListener = new OnCancelListener() {
|
|
||||||
public void onCancel(DialogInterface dialog) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 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.android;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.CheckBoxPreference;
|
|
||||||
import android.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
public class BarcodesPreferenceActivity extends android.preference.PreferenceActivity
|
|
||||||
implements OnSharedPreferenceChangeListener {
|
|
||||||
|
|
||||||
static final String KEY_DECODE_1D = "preferences_decode_1D";
|
|
||||||
static final String KEY_DECODE_QR = "preferences_decode_QR";
|
|
||||||
static final String KEY_PLAY_BEEP = "preferences_play_beep";
|
|
||||||
|
|
||||||
CheckBoxPreference mDecode1D;
|
|
||||||
CheckBoxPreference mDecodeQR;
|
|
||||||
CheckBoxPreference mPlayBeep;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle icicle) {
|
|
||||||
super.onCreate(icicle);
|
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
|
||||||
|
|
||||||
PreferenceScreen preferences = getPreferenceScreen();
|
|
||||||
preferences.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
|
||||||
mDecode1D = (CheckBoxPreference) preferences.findPreference(KEY_DECODE_1D);
|
|
||||||
mDecodeQR = (CheckBoxPreference) preferences.findPreference(KEY_DECODE_QR);
|
|
||||||
mPlayBeep = (CheckBoxPreference) preferences.findPreference(KEY_PLAY_BEEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent the user from turning off both decode options
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
|
||||||
if (key.equals(KEY_DECODE_1D)) {
|
|
||||||
mDecodeQR.setEnabled(mDecode1D.isChecked());
|
|
||||||
mDecodeQR.setChecked(true);
|
|
||||||
} else if (key.equals(KEY_DECODE_QR)) {
|
|
||||||
mDecode1D.setEnabled(mDecodeQR.isChecked());
|
|
||||||
mDecode1D.setChecked(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue