这是我的CameraView类:
public class CameraView extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback {
private Camera camera=null;
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = this.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public boolean isVisible(){
return this.getVisibility()==View.VISIBLE;
}
public void show(){
this.setVisibility(View.VISIBLE);
}
public void hide(){
this.setVisibility(View.GONE);
}
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
camera.setPreviewCallback(this);
try {
camera.setPreviewDisplay(holder);
}catch (IOException e) {
Log.e("Preview Exception", e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera=null;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if(camera==null || !(w>0&&h>0))
return;
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
}
在我的活动中,我有两个按钮 - 其中一个显示相机预览,第二个隐藏它(使用CameraView.show()和CameraView.hide())方法。
除了一个案例外,它几乎可以正常工作: 如果我使用CameraView.hide()隐藏预览,请按HOME按钮(应用程序将分叉到背景)并再次将应用程序带到前面,我无法再开始预览。 当我调用CameraView.show()(按下按钮)时,会出现CameraView,但预览不会启动。
对我来说它看起来像android bug,因为在其他情况下一切正常 - 我正在运行android 2.1。
有人能帮助我吗? 谢谢!
PS。根据mmeyer的帖子(仍然没有工作),这是更新的课程:
public class CameraView extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback {
private Camera camera=null;
private SurfaceHolder holder;
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void initialize(){
camera=Camera.open();
holder = this.getHolder();
holder.addCallback(this);
holder.setSizeFromLayout();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void release(){
holder.removeCallback(this);
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera=null;
}
}
public boolean isVisible(){
return this.getVisibility()==View.VISIBLE;
}
public void show(){
this.setVisibility(View.VISIBLE);
}
public void hide(){
this.setVisibility(View.GONE);
}
public void surfaceCreated(SurfaceHolder holder) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera!=null)
camera.stopPreview();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if(camera==null || !(w>0&&h>0))
return;
try {
camera.setPreviewDisplay(holder);
}catch (IOException e) {
Log.e("Preview Exception", e.getMessage());
}
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
}
答案 0 :(得分:2)
我怀疑你需要在onDestroy中最低限度地释放相机,理想情况是在onPause中,否则你最终会挂起相机驱动程序。
我用于相机预览的模式是:
onResume:
- get a ref to camera with Camera.open();
- sv = (SurfaceView)this.findViewById(R.id.capture_SurfaceView);
mHolder = sv.getHolder();
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.setSizeFromLayout();
mHolder.addCallback(this);
surfaceChanged:
- Camera.setPreviewDisplayHolder()
- Camera.startPreview()
onPause:
- Camera.stopPreview
- SurfaceHolder.removeCallback()
- Camera.release()
答案 1 :(得分:0)
我有一个工作版本:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private SurfaceHolder surfaceHolder;
private Camera camera;
public CameraPreview(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here,
// make sure to stop the preview before resizing or reformatting it
if (surfaceHolder.getSurface() == null){
// Preview surface does not exist
return;
}
// Stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// Set preview size and make any resize, rotate or
// reformatting changes here
// Start preview with new settings
try {
camera.setPreviewDisplay(surfaceHolder);
// Update the camera parameters
Camera.Parameters cameraParameters = camera.getParameters();
cameraParameters.setPreviewSize(w, h);
camera.setParameters(cameraParameters);
camera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void setCamera(Camera camera) {
this.camera = camera;
}
}