我在onPause()onResume()相机实时循环中遇到了一些麻烦:带预览的相机,并且拍照完全没问题 . 除了一个例外:
我启动应用程序,单击主页按钮,切换回应用程序并再次拍摄 .
结果:仍然执行了shuttercallback(参见代码),但jpeg回调不再存在了!然后我的星系S振动,屏幕保持黑色,因为在jpegCallback之后没有重新触发startPreview() . 堆栈跟踪对我来说远非有用 . 奇怪的是,这只发生在我的Galaxy S上,而不是在模拟器上 . 我真的不知道如何继续前进:/任何人都知道什么是有用的?
10-28 18:59:40.649: ERROR/SecCamera(4291): SetRotate(angle(0))
10-28 18:59:40.649: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null)
10-28 18:59:40.649: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480))
10-28 18:59:40.673: ERROR/SecCamera(4291): SetRotate(angle(0))
10-28 18:59:40.673: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null)
10-28 18:59:40.673: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480))
10-28 18:59:40.692: ERROR/SecCamera(4291): SetRotate(angle(0))
10-28 18:59:40.692: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null)
10-28 18:59:40.692: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480))
10-28 18:59:40.712: ERROR/SecCamera(4291): SetRotate(angle(0))
10-28 18:59:40.712: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null)
10-28 18:59:40.712: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480))
10-28 18:59:40.751: ERROR/CameraHardwareSec(4291): stopPreview()
10-28 18:59:40.751: ERROR/SecCamera(4291): cancelAutofocus()
10-28 18:59:40.751: ERROR/SecCamera(4291): cancelAutofocus() end, 0, 4
10-28 18:59:40.768: ERROR/SecCamera(4291): stopPreview()
10-28 18:59:40.768: ERROR/SecCamera(4291): fimc_v4l2_streamoff()
10-28 18:59:40.797: ERROR/CameraHardwareSec(4291): stopPreview() end
10-28 18:59:41.622: ERROR/SecCamera(4291): fimc_v4l2_streamoff()
10-28 18:59:46.536: ERROR/dalvikvm(2993): Failed to write stack traces to /data/anr/traces.txt (2775 of 2970): Unknown error: 0
10-28 18:59:46.540: ERROR/dalvikvm(2919): Failed to write stack traces to /data/anr/traces.txt (-1 of 3414): Math result not representable
10-28 18:59:46.610: ERROR/dalvikvm(3044): Failed to write stack traces to /data/anr/traces.txt (3354 of 7154): Math result not representable
...
这是我的(缩短的)代码:
public class CameraActivity extends Activity implements MenuViewCallback, CutoutPathManagerCallback {
public static final String TAG = "CutoutCamera";
Preview preview;
OverlayView overlay;
static MenuView menuView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Hide the window title.
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
...
preview = (Preview) this.findViewById(R.id.preview);
...
}
...
@Override
protected void onResume() {
super.onResume();
this.log("onResume()");
preview.openCamera();
}
@Override
protected void onPause() {
super.onPause();
this.log("onPause()");
if (preview.camera != null) {
preview.camera.release();
preview.camera = null;
}
}
// Called when shutter is opened
ShutterCallback shutterCallback = new ShutterCallback() { //
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
// Handles data for raw picture
PictureCallback rawCallback = new PictureCallback() { //
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
// Handles data for jpeg picture
PictureCallback jpegCallback = new PictureCallback() { //
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - jpeg");
...
}
};
@Override
public void shootButtonClicked() {
preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
@Override
public void focusButtonClicked() {
preview.camera.autoFocus(new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
}
});
}
}
/**
* order of execution:
* openCamera()
* onMeasure()
* onLayout()
* onMeasure()
* onLayout()
* surfaceCreated()
* surfaceChanged()
* onMeasure()
* onLayout()
* onMeasure()
* @author stephan
*
*/
class Preview extends ViewGroup implements SurfaceHolder.Callback { //
private static final String TAG = "Preview";
SurfaceHolder mHolder; //
public Camera camera; //
private List supportedPreviewSizes;
private Size previewSize;
SurfaceView mSurfaceView;
CameraActivity cameraActivity;
int l2 = 0, t2 = 0, r2 = 0, b2 = 0;
int padding = 20;
Size optimalPreviewSize, optimalPictureSize;
// the size of this view. gets set in onMeasure()
int fullWidth, fullHeight;
public Preview(Context context) {
super(context);
init(context);
}
public Preview(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public Preview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
setKeepScreenOn(true);
cameraActivity = (CameraActivity) context;
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
mHolder = mSurfaceView.getHolder(); //
mHolder.addCallback(this); //
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //
}
...
public void openCamera() {
cameraActivity.log("openCamera()");
if (this.camera == null) {
cameraActivity.log("Camera.open()");
this.camera = Camera.open();
//supportedPreviewSizes = camera.getParameters().getSupportedPreviewSizes();
requestLayout(); // -> onMeassure() -> onLayout()
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
cameraActivity.log("onMeasure()");
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
fullWidth = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
fullHeight = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(fullWidth, fullHeight);
if(this.camera != null){
cameraActivity.log("fullSize:"+fullWidth+"x"+fullHeight);
this.setCameraPreviewSize();
this.setCameraPictureSize();
}
}
private void calcScaledPreviewSize(){
...
}
...
private void setCameraPreviewSize() {
Camera.Parameters parameters = camera.getParameters();
if(parameters.getPreviewSize() != this.getOptimalPreviewSize()){
parameters.setPreviewSize(this.getOptimalPreviewSize().width, this.getOptimalPreviewSize().height);
this.camera.setParameters(parameters);
}
}
private void setCameraPictureSize() {
Camera.Parameters parameters = this.camera.getParameters();
if(parameters.getPictureSize() != this.getOptimalCameraPictureSize()){
parameters.setPictureSize(getOptimalCameraPictureSize().width, getOptimalCameraPictureSize().height);
this.camera.setParameters(parameters);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
cameraActivity.log("onLayout()");
if (changed && getChildCount() > 0 && this.camera != null) {
final View child = getChildAt(0);
cameraActivity.log("r:"+this.getPreviewRight()+" l:"+this.getPreviewLeft()+" b:"+this.getPreviewBottom()+" t:"+this.getPreviewTop());
child.layout(this.getPreviewLeft(), this.getPreviewTop(), this.getPreviewRight(), this.getPreviewBottom());
cameraActivity.initOverlay(this.getPreviewLeft(),this.getPreviewTop(),this.getPreviewRight(),this.getPreviewBottom());
}
}
private Size getOptimalPreviewSize() {
if(optimalPreviewSize == null){
//calculate optimal preview size
}
return optimalPreviewSize;
}
private Size getOptimalCameraPictureSize() {
if(optimalPictureSize == null){
//calculate optimal image size
}
return optimalPictureSize;
}
// Called once the holder is ready
public void surfaceCreated(SurfaceHolder holder) { //
// The Surface has been created, acquire the camera and tell it where
// to draw.
cameraActivity.log("surfaceCreated()");
try {
if (this.camera != null) {
this.camera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
cameraActivity.log("surfaceChanged()");
if (camera != null) {
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(getOptimalPreviewSize().width, getOptimalPreviewSize().height);
requestLayout();
camera.setParameters(parameters);
camera.startPreview();
}
}
public void surfaceDestroyed(SurfaceHolder holder) { //
cameraActivity.log("surfaceDestroyed()");
if(this.camera != null){
camera.stopPreview();
}
}
public void releaseCamera(){
cameraActivity.log("releaseCamera()");
if (camera != null) {
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
}