2012-06-28 41 views
5

Xin chào các bạn, tôi đang cố gắng chuyển đổi giữa Camera trước và sau của thiết bị trong khi hiển thị xem trước máy ảnh. Tôi đang theo mẫu được cung cấp bởi các sản phẩm thông thường. Dưới đây là mã mà tôi đang sử dụng và bất cứ khi nào tôi nhấp vào nút Flip, bề mặt sẽ chuyển sang màu đen và tôi không biết tôi đang đi đâu sai. Làm ơn giúp tôi giải quyết vấn đề này. Tôi tìm kiếm về điều này và tôi đã không nhận được bất kỳ câu trả lời phù hợp như một số đã cố gắng để khởi động lại hoạt động hiện tại nhưng tôi không muốn như thế. Hy vọng sẽ có phản ứng tốt hơn. Cảm ơn trước.Xem trước máy ảnh Android Chuyển đổi giữa các máy ảnh

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

Đặt 'camId' thành thành viên tĩnh và bắt đầu lại hoạt động khi kiểm tra thay đổi .. như bắt đầu chính nó và kết thúc cuộc gọi ở dòng tiếp theo ... Giống như một hoạt động đệ quy' .. – Ronnie

+0

@ userSeven7s Trong khi đó sẽ giải quyết được sự cố nó không phải là (theo ý kiến ​​của tôi) một sự lựa chọn thiết kế khôn ngoan. Một mẫu phổ biến cho Máy ảnh là làm cho chúng trở lại đường dẫn đến hình ảnh đã chụp. Nếu tôi khởi động Máy ảnh từ hoạt động A và máy ảnh tự khởi động, việc nhận được kết quả từ máy ảnh trở nên phức tạp. Bên cạnh đó, việc thêm đệ quy vào vòng đời "đặc biệt" của Android nghe như một ý tưởng khủng khiếp. – TheCrafter

Trả lời

12

Bạn dường như đã bị lãng quên để gọi setPreviewDisplay() (hoặc, trong trường hợp của bạn, initPreview()) trước khi gọi startPreview() từ phương pháp restartPreviev() của bạn. Có hiệu quả, bạn đang cố bắt đầu xem trước mà không chỉ định bề mặt để hiển thị bản xem trước.

Các vấn đề liên quan