2012-06-28 5 views
5

안녕하세요 여러분, 카메라 미리보기를 표시하는 동안 장치의 앞면 및 뒷면 카메라를 전환하려고합니다. 나는 일반적인 도자기로 제공되는 샘플을 따르고있다. 아래 코드는 제가 사용하고있는 플립 버튼을 클릭 할 때마다 표면이 검은 색으로 변하고 어디서 잘못 될지 모릅니다. 이 문제를 해결하도록 도와주세요. 나는 이것에 대해서 수색했는데 어떤 사람들은 현재의 활동을 재시작하려했으나 그렇게하고 싶지 않기 때문에 적절한 답을 얻지 못했다. 더 나은 응답을 원합니다. 미리 감사드립니다.카메라 사이의 안드로이드 카메라 미리보기 스위치

package com.commonsware.android.camera; 
import android.app.Activity; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.widget.CompoundButton; 
import android.widget.CompoundButton.OnCheckedChangeListener; 
import android.widget.Toast; 
import android.widget.ToggleButton; 
public class PreviewDemo extends Activity { 
    private SurfaceView preview = null; 
    private SurfaceHolder previewHolder = null; 
    private Camera camera = null; 
    private boolean inPreview = false; 
    private boolean cameraConfigured = false; 
    private ToggleButton flipCamera; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 
    flipCamera = (ToggleButton) findViewById(R.id.flip); 
    preview = (SurfaceView) findViewById(R.id.preview); 
    previewHolder = preview.getHolder(); 
    previewHolder.addCallback(surfaceCallback); 
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    flipCamera.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

     @Override 
     public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 
      // TODO Auto-generated method stub 
      restartPreview(isChecked); 
     } 
    }); 

} 

@Override 
public void onResume() { 
    super.onResume(); 

    // camera=Camera.open(); 
    int camId = Camera.CameraInfo.CAMERA_FACING_BACK; 
    if (Camera.getNumberOfCameras() > 1 
      && camId < Camera.getNumberOfCameras() - 1) { 
     // startCamera(camId + 1); 
     camera = Camera.open(camId + 1); 
    } else { 
     // startCamera(Camera.CameraInfo.CAMERA_FACING_BACK); 
     camera = Camera.open(camId); 
    } 
    startPreview(); 
} 

void restartPreview(boolean isFront) { 
    if (inPreview) { 
     camera.stopPreview(); 
    } 
    // 
    camera.release(); 

    // camera=null; 
    // inPreview=false; 
    // /*int camId = Camera.CameraInfo.CAMERA_FACING_BACK; 
    // if (Camera.getNumberOfCameras() > 1 && camId < 
    // Camera.getNumberOfCameras() - 1) { 
    // //startCamera(camId + 1); 
    // camera = Camera.open(camId + 1); 
    // } else { 
    // //startCamera(Camera.CameraInfo.CAMERA_FACING_BACK); 
    // camera = Camera.open(camId); 
    // }*/ 
    int camId = Camera.CameraInfo.CAMERA_FACING_BACK; 
    if (isFront) { 
     camera = Camera.open(camId); 
     camera.startPreview(); 

    } else { 
     camera = Camera.open(camId + 1); 
     camera.startPreview(); 

    } 
    // startPreview(); 
} 

@Override 
public void onPause() { 
    if (inPreview) { 
     camera.stopPreview(); 
    } 

    camera.release(); 
    camera = null; 
    inPreview = false; 

    super.onPause(); 
} 

private Camera.Size getBestPreviewSize(int width, int height, 
     Camera.Parameters parameters) { 
    Camera.Size result = null; 

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) { 
     if (size.width <= width && size.height <= height) { 
      if (result == null) { 
       result = size; 
      } else { 
       int resultArea = result.width * result.height; 
       int newArea = size.width * size.height; 

       if (newArea > resultArea) { 
        result = size; 
       } 
      } 
     } 
    } 

    return (result); 
} 

private void initPreview(int width, int height) { 
    if (camera != null && previewHolder.getSurface() != null) { 
     try { 
      camera.setPreviewDisplay(previewHolder); 
     } catch (Throwable t) { 
      Log.e("PreviewDemo-surfaceCallback", 
        "Exception in setPreviewDisplay()", t); 
      Toast.makeText(PreviewDemo.this, t.getMessage(), 
        Toast.LENGTH_LONG).show(); 
     } 

     if (!cameraConfigured) { 
      Camera.Parameters parameters = camera.getParameters(); 
      Camera.Size size = getBestPreviewSize(width, height, parameters); 

      if (size != null) { 
       parameters.setPreviewSize(size.width, size.height); 
       camera.setParameters(parameters); 
       cameraConfigured = true; 
      } 
     } 
    } 
} 

private void startPreview() { 
    if (cameraConfigured && camera != null) { 

     camera.startPreview(); 
     inPreview = true; 
    } 
} 

SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { 
    public void surfaceCreated(SurfaceHolder holder) { 
     // no-op -- wait until surfaceChanged() 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
     initPreview(width, height); 
     startPreview(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     // no-op 
     if (camera != null) { 
      /* 
      * Call stopPreview() to stop updating the preview surface. 
      */ 
      camera.stopPreview(); 

      /* 
      * Important: Call release() to release the camera for use by 
      * other applications. Applications should release the camera 
      * immediately in onPause() (and re-open() it in onResume()). 
      */ 
      camera.release(); 

      camera = null; 
     } 
    } 
}; 
} 
+0

'camId'를 정적 멤버로 만들고 체크가 변경되면 다시 활동을 시작합니다 .. 그 자체를 시작하고 다음 라인에서 finish를 호출하는 것처럼 ...'recursive activity'처럼 .. – Ronnie

+0

@ userSeven7s 그게 문제를 해결하는 동안 그것은 내 의견으로는 현명한 디자인 선택이 아닙니다. 카메라의 일반적인 패턴은 캡쳐 된 이미지의 경로를 반환하는 것입니다. 활동 A에서 카메라를 시작하고 카메라가 시작되면 카메라에서 결과를 얻는 것이 복잡해집니다. 게다가 안드로이드의 이미 "특별한"수명주기에 재귀를 추가하는 것은 끔찍한 생각처럼 들립니다. – TheCrafter

답변

12

당신은 당신의 restartPreviev() 방법에서 startPreview()를 호출하기 전에 (귀하의 경우 나, initPreview()) setPreviewDisplay() 전화를 잊어 버린 것 같다. 효과적으로 미리보기를 렌더링 할 서페이스를 지정하지 않고 미리보기를 시작하려고합니다.

관련 문제