2011-11-15 157 views
0

這裏是我的CameraView類:Android相機預覽錯誤

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) { 

} 
} 

回答

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() 
+0

我修改了類如你所說,但問題仍然存在。 – user1011446

+0

如果您事先沒有事先做好CameraView.hide()而回到家中,您會遇到同樣的問題嗎?如果隱藏似乎是問題,那麼我會考慮讓它也發佈。 – mmeyer

+0

如果我在將應用程序分配到背景之前沒有隱藏預覽,那麼一切正常。 – user1011446

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; 
    } 
}