2011-07-06 13 views
24

Nếu tôi chỉ sử dụng CAMERA_FACING_BACK hoặc CAMERA_FACING_FRONT tất cả đều hoạt động tốt.chuyển trở lại/camera trước trên bay

Tôi gặp sự cố khi chuyển từ CAMERA_FACING_BACK sang CAMERA_FACING_FRONT.

đoạn mã của tôi:

public class PhotoCameraActivity extends Activity implements OnClickListener { 
private SurfaceView cameraView; 
private Button turnButton; 
private Camera camera = null; 
private Callback listener; 
private static int camId = Camera.CameraInfo.CAMERA_FACING_BACK; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.photo_camera_main); 
    prepareActivity(); 
} 

private void prepareActivity() { 
    cameraView = (SurfaceView) findViewById(R.id.photo_camera_surface_view); 

    turnButton = (ImageButton) findViewById(R.id.turn_button); 
    turnButton.setOnClickListener(this); 
} 

@Override 
public void onClick(View v) { 
    if (v.equals(turnButton)) { 
     if (Camera.getNumberOfCameras() > 1 && camId < Camera.getNumberOfCameras() - 1) { 
      startCamera(camId + 1); 
     } else { 
      startCamera(Camera.CameraInfo.CAMERA_FACING_BACK); 
     } 
    } 
} 

@Override 
protected void onResume() { 
    startCamera(camId); 
    super.onResume(); 
} 

@Override 
protected void onPause() { 
    stopCamera(); 
    super.onPause(); 
} 

private void startCamera(int cameraId) { 
    if (camera != null) { 
     stopCamera(); 
    }  
    holder = cameraView.getHolder(); 
    listener = new Callback() { 

     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) { 
     } 

     @Override 
     public void surfaceCreated(SurfaceHolder holder) { 
      try { 
       camera.setPreviewDisplay(holder); 
       camera.startPreview(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void surfaceChanged(SurfaceHolder holder, int format, int   width, int height) {} 
    }; 
    holder.addCallback(listener); 


    camId = cameraId; 
    camera = Camera.open(cameraId); 
    Camera.Parameters params = camera.getParameters(); 
    if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) { 
     params.setPreviewSize(1280, 800); 
    } else { 
     params.setPreviewSize(640, 480); 
    } 
    camera.setParameters(params); 

} 

private void stopCamera(){ 
    System.out.println("stopCamera method"); 
    if (camera != null){ 
     camera.stopPreview(); 
     camera.setPreviewCallback(null); 
     camera.release(); 
     camera = null; 
     holder.removeCallback(listener); 
     holder = null; 
    } 
} 

} 
+1

là gì bản chất của "rắc rối" mà bạn đang có? – Estel

+0

Nếu tôi cố gắng dừng camera, kính ngắm bị đóng băng và không hiển thị hình ảnh từ máy ảnh khác. Nhưng nếu tôi nhấn "Quay lại" và sau đó lại bắt đầu Hoạt động này, máy ảnh sẽ chuyển sang trước và nó hoạt động tốt trở lại. Tôi nghĩ rằng tôi gặp sự cố với máy ảnh tắt và phát hành tài nguyên. –

+0

tôi bị kẹt với cùng một sự cố – himanshu

Trả lời

5

tôi khởi động lại Hoạt động với cameraId = 2 và điều này đang làm việc.

+1

@ Dmitriy_Boichenko..I am cũng phải đối mặt với cùng một vấn đề .. Bạn có thể chia sẻ mã của bạn không? – sarath

+0

Cách khởi động lại hoạt động trên nút bấm – Ravi

+0

gọi phương thức oncreate (null) để thực hiện lại mã. – WonderSoftwares

21

Trong onCreate() của hoạt động của tôi để tôi thêm người nghe onClick sau để một nút overlayed trên Preview SurfaceView của tôi (có rất nhiều ví dụ trên web cho xem trước):

ImageButton useOtherCamera = (ImageButton) findViewById(R.id.useOtherCamera); 
//if phone has only one camera, hide "switch camera" button 
if(Camera.getNumberOfCameras() == 1){ 
    useOtherCamera.setVisibility(View.INVISIBLE); 
} 
else { 
    useOtherCamera.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
    if (inPreview) { 
     camera.stopPreview(); 
    } 
    //NB: if you don't release the current camera before switching, you app will crash 
    camera.release(); 

    //swap the id of the camera to be used 
    if(currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK){ 
     currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT; 
    } 
    else { 
     currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK; 
    } 
    camera = Camera.open(currentCameraId); 
    //Code snippet for this method from somewhere on android developers, i forget where 
    setCameraDisplayOrientation(CameraActivity.this, currentCameraId, camera); 
    try { 
     //this step is critical or preview on new camera will no know where to render to 
     camera.setPreviewDisplay(previewHolder); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    camera.startPreview(); 
} 

Trên điện thoại thử nghiệm của tôi lại máy ảnh có ID là 0 và mặt trước có id là 1. Tôi đề xuất sử dụng biến tĩnh Camera.CameraInfo cho các giá trị mã hóa của máy ảnh chứ không phải mã hóa cứng. Tôi chắc chắn rằng sẽ chỉ gây ra sự cố trên các thiết bị khác.

+0

+1 Tôi đã thiếu camera.setPreviewDisplay (previewHolder); –

+5

** Mã này là [sai] (http://stackoverflow.com/questions/2779002/how-to-open-front-camera-on-android-platform/4767832#comment33410134_4767832) **: *… đối diện máy ảnh là không nhất thiết phải giống với chỉ số máy ảnh. Ví dụ: máy tính bảng của tôi chỉ có một máy ảnh (chỉ mục: 0) nhưng quay mặt ra phía trước (đối diện với chỉ mục: 1). Vì vậy, sử dụng mã đơn giản như Camera.open (CameraInfo.CAMERA_FACING_FRONT) là vô nghĩa * –

+1

@AlexCohn Tôi sẽ không nói mã này là sai, trên thực tế nó hoạt động khá tốt và cho thấy làm thế nào để dừng máy ảnh và bắt đầu một cái mới. Đó là lập trình viên để hiểu ** mã và thích ứng với nhu cầu riêng của họ. – Merlevede

4

Tôi đã xóa và thêm lại SurfaceView trong bố cục của mình và do đó nó hoạt động.

public void switchCamera(int cameraType) 
{ 
    if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) 
    { 
     if(Camera.getNumberOfCameras() > cameraType) 
     { 
      // Set selected camera 
      this.cameraType = cameraType; 
     } 
     else 
     { 
      // Set default camera (Rear) 
      this.cameraType = Camera.CameraInfo.CAMERA_FACING_BACK; 
     } 

     if(mCamera != null) 
     { 
      // Destroy previuos Holder 
      surfaceDestroyed(holder); 
      holder.removeCallback(this); 

      // Remove and re-Add SurfaceView 
      ViewGroup rootLayout = (ViewGroup) surface.getParent(); 
      rootLayout.removeView(surface); 
      surface = new SurfaceView(context); 
      holder = surface.getHolder(); 
      holder.addCallback(this); 
      rootLayout.addView(surface, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 
     } 
    } 
} 
+0

tôi đã thực sự quên để loại bỏ xem vì vậy tôi đã không thể nhìn thấy máy ảnh chuyển đổi view.thanks này đã giúp –

0

Sử dụng mã này:

if (mCamera != null) { 
     mCamera.stopPreview();     
     mCamera.release(); 
     mCamera = null; 
} 

//swap the id of the camera to be used 
if (currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) 
    currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT; 
else 
    currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;   

try {     
     mCamera = Camera.open(currentCameraId); 

     mCamera.setDisplayOrientation(90); 

     mCamera.setPreviewDisplay(surfaceHolder);    

     mCamera.startPreview(); 

    } 
catch (Exception e) { e.printStackTrace(); } 
+3

** Mã này là [sai] (http://stackoverflow.com/questions/2779002/how-to- open-front-camera-on-android-platform/4767832 # comment33410134_4767832) **: *… đối diện máy ảnh không nhất thiết phải giống với chỉ mục máy ảnh. Ví dụ: máy tính bảng của tôi chỉ có một máy ảnh (chỉ mục: 0) nhưng quay mặt ra phía trước (đối diện với chỉ mục: 1). Do đó, việc sử dụng mã đơn giản như Camera.open (CameraInfo.CAMERA_FACING_FRONT) là vô nghĩa * –

2

tôi phải loại bỏ các preview bề mặt trước khi thêm một hình mới:

if (mPreview != null) { 
     mPreview.surfaceDestroyed(mPreview.getHolder()); 
     mPreview.getHolder().removeCallback(mPreview); 
     mPreview.destroyDrawingCache(); 
     FrameLayout preview = (FrameLayout) view.findViewById(R.id.camera_frame); 
     preview.removeView(mPreview); 
     mPreview.mCamera = null; 
     mPreview = null; 

    } 

//then add your preview