mirror of
https://github.com/zxing/zxing.git
synced 2025-02-02 05:41:08 -08:00
Did a bunch of renaming, there was no need for the Barcodes prefix.
git-svn-id: https://zxing.googlecode.com/svn/trunk@682 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
f21c34ae16
commit
aef1dedb61
|
@ -24,7 +24,7 @@ versionName is 2.31, 2.4, or 3.0. -->
|
|||
android:versionCode="6">
|
||||
<application android:icon="@drawable/launcher_icon"
|
||||
android:label="@string/app_name">
|
||||
<activity android:name=".BarcodesCaptureActivity"
|
||||
<activity android:name=".CaptureActivity"
|
||||
android:screenOrientation="landscape"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||
|
@ -42,10 +42,10 @@ versionName is 2.31, 2.4, or 3.0. -->
|
|||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="BarcodesPreferenceActivity"
|
||||
<activity android:name="PreferencesActivity"
|
||||
android:label="@string/preferences_name">
|
||||
</activity>
|
||||
<activity android:name="BarcodesEncodeActivity">
|
||||
<activity android:name="EncodeActivity">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.zxing.client.android.ENCODE"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
|
|
420
android/src/com/google/zxing/client/android/CaptureActivity.java
Executable file
420
android/src/com/google/zxing/client/android/CaptureActivity.java
Executable file
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* 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 CaptureActivity 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 CaptureActivityHandler 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(PreferencesActivity.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, PreferencesActivity.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 CaptureActivityHandler(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();
|
||||
}
|
||||
|
||||
}
|
111
android/src/com/google/zxing/client/android/CaptureActivityHandler.java
Executable file
111
android/src/com/google/zxing/client/android/CaptureActivityHandler.java
Executable file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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 CaptureActivityHandler extends Handler {
|
||||
|
||||
private final CaptureActivity mActivity;
|
||||
private final DecodeThread mDecodeThread;
|
||||
private State mState;
|
||||
|
||||
private enum State {
|
||||
PREVIEW,
|
||||
SUCCESS,
|
||||
DONE
|
||||
}
|
||||
|
||||
CaptureActivityHandler(CaptureActivity 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -40,18 +40,18 @@ final class DecodeThread extends Thread {
|
|||
public static final String BARCODE_BITMAP = "barcode_bitmap";
|
||||
|
||||
public Handler mHandler;
|
||||
private BarcodesCaptureActivity mActivity;
|
||||
private CaptureActivity mActivity;
|
||||
private MultiFormatReader mMultiFormatReader;
|
||||
|
||||
DecodeThread(BarcodesCaptureActivity activity, String mode) {
|
||||
DecodeThread(CaptureActivity activity, String mode) {
|
||||
mActivity = activity;
|
||||
mMultiFormatReader = new MultiFormatReader();
|
||||
|
||||
// The prefs can't change while the thread is running, so pick them up once here.
|
||||
if (mode == null || mode.length() == 0) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
boolean decode1D = prefs.getBoolean(BarcodesPreferenceActivity.KEY_DECODE_1D, true);
|
||||
boolean decodeQR = prefs.getBoolean(BarcodesPreferenceActivity.KEY_DECODE_QR, true);
|
||||
boolean decode1D = prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, true);
|
||||
boolean decodeQR = prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, true);
|
||||
if (decode1D && decodeQR) {
|
||||
setDecodeAllMode();
|
||||
} else if (decode1D) {
|
||||
|
|
139
android/src/com/google/zxing/client/android/EncodeActivity.java
Executable file
139
android/src/com/google/zxing/client/android/EncodeActivity.java
Executable file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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 EncodeActivity 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(EncodeActivity.this, intent);
|
||||
setTitle(getString(R.string.app_name) + " - " + mQRCodeEncoder.getTitle());
|
||||
mQRCodeEncoder.requestBarcode(mHandler, smallerDimension);
|
||||
mProgressDialog = ProgressDialog.show(EncodeActivity.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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
59
android/src/com/google/zxing/client/android/PreferencesActivity.java
Executable file
59
android/src/com/google/zxing/client/android/PreferencesActivity.java
Executable file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 PreferencesActivity 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