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
}
private CameraManager cameraManager;
private CaptureActivityHandler handler;
private ViewfinderView viewfinderView;
private TextView statusView;
@ -145,6 +146,10 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
return handler;
}
CameraManager getCameraManager() {
return cameraManager;
}
@Override
public void onCreate(Bundle 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);
setContentView(R.layout.capture);
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
resultView = findViewById(R.id.result_view);
statusView = (TextView) findViewById(R.id.status_view);
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
// first launch. That led to bugs where the scanning rectangle was the wrong size and partially
// off screen.
CameraManager.init(getApplication());
cameraManager = new CameraManager(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
resetStatusView();
@ -203,7 +210,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
int height = intent.getIntExtra(Intents.Scan.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) &&
@ -249,13 +256,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
handler = null;
}
inactivityTimer.onPause();
CameraManager.get().closeDriver();
}
@Override
protected void onStop() {
super.onStop();
CameraManager.destroy();
cameraManager.closeDriver();
}
@Override
@ -616,10 +617,10 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
private void initCamera(SurfaceHolder surfaceHolder) {
try {
CameraManager.get().openDriver(surfaceHolder);
cameraManager.openDriver(surfaceHolder);
// Creating the handler starts the preview, which can also throw a RuntimeException.
if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats, characterSet);
handler = new CaptureActivityHandler(this, decodeFormats, characterSet, cameraManager);
}
} catch (IOException ioe) {
Log.w(TAG, ioe);

View file

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

View file

@ -21,7 +21,6 @@ import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.android.camera.CameraManager;
import com.google.zxing.common.HybridBinarizer;
import android.os.Bundle;
@ -73,7 +72,7 @@ final class DecodeHandler extends Handler {
private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
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));
try {
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 POINT_SIZE = 6;
private CameraManager cameraManager;
private final Paint paint;
private Bitmap resultBitmap;
private final int maskColor;
@ -73,12 +74,12 @@ public final class ViewfinderView extends View {
lastPossibleResultPoints = null;
}
public void setCameraManager(CameraManager cameraManager) {
this.cameraManager = cameraManager;
}
@Override
public void onDraw(Canvas canvas) {
CameraManager cameraManager = CameraManager.get();
if (cameraManager == null) {
return;
}
Rect frame = cameraManager.getFramingRect();
if (frame == null) {
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_HEIGHT = 400;
private static CameraManager cameraManager;
static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT
static {
int sdkInt;
@ -82,36 +80,7 @@ public final class CameraManager {
/** Autofocus callbacks arrive here, and are dispatched to the Handler which requested them. */
private final AutoFocusCallback autoFocusCallback;
/**
* 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) {
public CameraManager(Context context) {
this.context = context;
this.configManager = new CameraConfigurationManager(context);