Real fix for Issue 1044 - don't use static CameraManager

git-svn-id: https://zxing.googlecode.com/svn/trunk@2013 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2011-11-04 11:21:21 +00:00
parent 86034a4442
commit c3659d2b94
5 changed files with 32 additions and 61 deletions

View file

@ -110,6 +110,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
NONE NONE
} }
private CameraManager cameraManager;
private CaptureActivityHandler handler; private CaptureActivityHandler handler;
private ViewfinderView viewfinderView; private ViewfinderView viewfinderView;
private TextView statusView; private TextView statusView;
@ -145,6 +146,10 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
return handler; return handler;
} }
CameraManager getCameraManager() {
return cameraManager;
}
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
@ -153,7 +158,6 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.capture); setContentView(R.layout.capture);
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
resultView = findViewById(R.id.result_view); resultView = findViewById(R.id.result_view);
statusView = (TextView) findViewById(R.id.status_view); statusView = (TextView) findViewById(R.id.status_view);
handler = null; handler = null;
@ -175,7 +179,10 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
// want to open the camera driver and measure the screen size if we're going to show the help on // want to open the camera driver and measure the screen size if we're going to show the help on
// first launch. That led to bugs where the scanning rectangle was the wrong size and partially // first launch. That led to bugs where the scanning rectangle was the wrong size and partially
// off screen. // off screen.
CameraManager.init(getApplication()); cameraManager = new CameraManager(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
resetStatusView(); resetStatusView();
@ -203,7 +210,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
int width = intent.getIntExtra(Intents.Scan.WIDTH, 0); int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0); int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);
if (width > 0 && height > 0) { if (width > 0 && height > 0) {
CameraManager.get().setManualFramingRect(width, height); cameraManager.setManualFramingRect(width, height);
} }
} }
} else if (dataString != null && dataString.contains(PRODUCT_SEARCH_URL_PREFIX) && } else if (dataString != null && dataString.contains(PRODUCT_SEARCH_URL_PREFIX) &&
@ -249,13 +256,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
handler = null; handler = null;
} }
inactivityTimer.onPause(); inactivityTimer.onPause();
CameraManager.get().closeDriver(); cameraManager.closeDriver();
}
@Override
protected void onStop() {
super.onStop();
CameraManager.destroy();
} }
@Override @Override
@ -616,10 +617,10 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
private void initCamera(SurfaceHolder surfaceHolder) { private void initCamera(SurfaceHolder surfaceHolder) {
try { try {
CameraManager.get().openDriver(surfaceHolder); cameraManager.openDriver(surfaceHolder);
// Creating the handler starts the preview, which can also throw a RuntimeException. // Creating the handler starts the preview, which can also throw a RuntimeException.
if (handler == null) { if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats, characterSet); handler = new CaptureActivityHandler(this, decodeFormats, characterSet, cameraManager);
} }
} catch (IOException ioe) { } catch (IOException ioe) {
Log.w(TAG, ioe); Log.w(TAG, ioe);

View file

@ -43,6 +43,7 @@ public final class CaptureActivityHandler extends Handler {
private final CaptureActivity activity; private final CaptureActivity activity;
private final DecodeThread decodeThread; private final DecodeThread decodeThread;
private State state; private State state;
private final CameraManager cameraManager;
private enum State { private enum State {
PREVIEW, PREVIEW,
@ -50,8 +51,10 @@ public final class CaptureActivityHandler extends Handler {
DONE DONE
} }
CaptureActivityHandler(CaptureActivity activity, Collection<BarcodeFormat> decodeFormats, CaptureActivityHandler(CaptureActivity activity,
String characterSet) { Collection<BarcodeFormat> decodeFormats,
String characterSet,
CameraManager cameraManager) {
this.activity = activity; this.activity = activity;
decodeThread = new DecodeThread(activity, decodeFormats, characterSet, decodeThread = new DecodeThread(activity, decodeFormats, characterSet,
new ViewfinderResultPointCallback(activity.getViewfinderView())); new ViewfinderResultPointCallback(activity.getViewfinderView()));
@ -59,7 +62,8 @@ public final class CaptureActivityHandler extends Handler {
state = State.SUCCESS; state = State.SUCCESS;
// Start ourselves capturing previews and decoding. // Start ourselves capturing previews and decoding.
CameraManager.get().startPreview(); this.cameraManager = cameraManager;
cameraManager.startPreview();
restartPreviewAndDecode(); restartPreviewAndDecode();
} }
@ -71,7 +75,7 @@ public final class CaptureActivityHandler extends Handler {
// When one auto focus pass finishes, start another. This is the closest thing to // 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. // continuous AF. It does seem to hunt a bit, but I'm not sure what else to do.
if (state == State.PREVIEW) { if (state == State.PREVIEW) {
CameraManager.get().requestAutoFocus(this, R.id.auto_focus); cameraManager.requestAutoFocus(this, R.id.auto_focus);
} }
break; break;
case R.id.restart_preview: case R.id.restart_preview:
@ -89,7 +93,7 @@ public final class CaptureActivityHandler extends Handler {
case R.id.decode_failed: case R.id.decode_failed:
// We're decoding as fast as possible, so when one decode fails, start another. // We're decoding as fast as possible, so when one decode fails, start another.
state = State.PREVIEW; state = State.PREVIEW;
CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode); cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
break; break;
case R.id.return_scan_result: case R.id.return_scan_result:
Log.d(TAG, "Got return scan result message"); Log.d(TAG, "Got return scan result message");
@ -108,10 +112,7 @@ public final class CaptureActivityHandler extends Handler {
public void quitSynchronously() { public void quitSynchronously() {
state = State.DONE; state = State.DONE;
CameraManager cameraManager = CameraManager.get();
if (cameraManager != null) {
cameraManager.stopPreview(); cameraManager.stopPreview();
}
Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit); Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
quit.sendToTarget(); quit.sendToTarget();
try { try {
@ -129,8 +130,8 @@ public final class CaptureActivityHandler extends Handler {
private void restartPreviewAndDecode() { private void restartPreviewAndDecode() {
if (state == State.SUCCESS) { if (state == State.SUCCESS) {
state = State.PREVIEW; state = State.PREVIEW;
CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode); cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
CameraManager.get().requestAutoFocus(this, R.id.auto_focus); cameraManager.requestAutoFocus(this, R.id.auto_focus);
activity.drawViewfinder(); activity.drawViewfinder();
} }
} }

View file

@ -21,7 +21,6 @@ import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException; import com.google.zxing.ReaderException;
import com.google.zxing.Result; import com.google.zxing.Result;
import com.google.zxing.client.android.camera.CameraManager;
import com.google.zxing.common.HybridBinarizer; import com.google.zxing.common.HybridBinarizer;
import android.os.Bundle; import android.os.Bundle;
@ -73,7 +72,7 @@ final class DecodeHandler extends Handler {
private void decode(byte[] data, int width, int height) { private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
Result rawResult = null; Result rawResult = null;
PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(data, width, height); PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try { try {
rawResult = multiFormatReader.decodeWithState(bitmap); rawResult = multiFormatReader.decodeWithState(bitmap);

View file

@ -45,6 +45,7 @@ public final class ViewfinderView extends View {
private static final int MAX_RESULT_POINTS = 20; private static final int MAX_RESULT_POINTS = 20;
private static final int POINT_SIZE = 6; private static final int POINT_SIZE = 6;
private CameraManager cameraManager;
private final Paint paint; private final Paint paint;
private Bitmap resultBitmap; private Bitmap resultBitmap;
private final int maskColor; private final int maskColor;
@ -73,12 +74,12 @@ public final class ViewfinderView extends View {
lastPossibleResultPoints = null; lastPossibleResultPoints = null;
} }
public void setCameraManager(CameraManager cameraManager) {
this.cameraManager = cameraManager;
}
@Override @Override
public void onDraw(Canvas canvas) { public void onDraw(Canvas canvas) {
CameraManager cameraManager = CameraManager.get();
if (cameraManager == null) {
return;
}
Rect frame = cameraManager.getFramingRect(); Rect frame = cameraManager.getFramingRect();
if (frame == null) { if (frame == null) {
return; return;

View file

@ -48,8 +48,6 @@ public final class CameraManager {
private static final int MAX_FRAME_WIDTH = 600; private static final int MAX_FRAME_WIDTH = 600;
private static final int MAX_FRAME_HEIGHT = 400; private static final int MAX_FRAME_HEIGHT = 400;
private static CameraManager cameraManager;
static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT
static { static {
int sdkInt; int sdkInt;
@ -82,36 +80,7 @@ public 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 AutoFocusCallback autoFocusCallback; private final AutoFocusCallback autoFocusCallback;
/** public CameraManager(Context context) {
* Initializes this static object with the Context of the calling Activity. The caller of this
* method relies on the ability to harmlessly call it multiple times and only have the object
* built once, the first time.
*
* @param context The Activity which wants to use the camera.
*/
public static void init(Context context) {
if (cameraManager == null) {
cameraManager = new CameraManager(context);
}
}
/**
* Deletes all state. We don't want to keep global variables around from one launch to another.
*/
public static void destroy() {
cameraManager = null;
}
/**
* Gets the CameraManager singleton instance.
*
* @return A reference to the CameraManager singleton.
*/
public static CameraManager get() {
return cameraManager;
}
private CameraManager(Context context) {
this.context = context; this.context = context;
this.configManager = new CameraConfigurationManager(context); this.configManager = new CameraConfigurationManager(context);