2017-06-20 77 views
1

所以我有一個簡單的相機管理器類,我想在對話框中生成相機預覽。除了相機預覽未在對話框中顯示的部分外,一切都可以正常工作!這裏是類調用相機無法生成相機預覽視圖

Manager類:

public class CameraExample extends AnimatedViewContainer { 

    private final static String TAG = "CameraExample"; 

    private Context mContext; 
    private SurfaceView mPreview; 
    public CameraExample(Context context, int i) { 
     super(context, i); 
     mContext = context; 

    } 

    @Override 
    public void onCreateViewContent(LayoutInflater layoutInflater, ViewGroup parentGroup, View[] containerViews, int index) { 
     containerViews[index] = layoutInflater.inflate(R.layout.example_camera, parentGroup, false); 
     FrameLayout previewFrame = (FrameLayout) containerViews[index].findViewById(R.id.preview); 

     //this have been line moved here from constructor 
     mPreview = (SurfaceView) findViewById(R.id.surfaceView); 
     CameraPreview mgr = new CameraPreview(mContext, mPreview); 
     mgr.init(); 

     // Add preview for inflation 
     previewFrame.addView(mPreview); 

    } 
} 

,這裏是相機管理類:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    private static String TAG = "CameraManager"; 

    private Context mContext = null; 
    private SurfaceView mPreview = null; 
    private SurfaceHolder mHolder = null; 
    private Camera mCamera = null; 
    private int mFrontFaceID = -1; 
    private int mBackFaceID = -1; 
    private int mActualFacingID = -1; 

    public CameraPreview(Context context, SurfaceView preview) { 
     super(context); 
     mContext = context; 
     mPreview = preview; 
     mHolder = mPreview.getHolder(); 
     mHolder.addCallback(this); 
    } 

    //called in onCreate 
    public void init() { 
     Camera.CameraInfo info = new Camera.CameraInfo(); 
     for (int i = 0; i < Camera.getNumberOfCameras(); i++) { 
      Camera.getCameraInfo(i, info); 
      if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
       mFrontFaceID = i; 
      } 
      if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 
       mBackFaceID = i; 
      } 
     } 
     if (mActualFacingID == -1) { 
      if (mFrontFaceID != -1) { 
       mActualFacingID = mFrontFaceID; 
      } else { 
       mActualFacingID = mBackFaceID; 
      } 
     } 
     //At least one one camera will be available because of manifest declaration 
    } 

    //called first on surface created 
    public void start() { 
     Log.i(TAG, "startCamera()"); 
     if (mCamera == null) { 
      mCamera = getCameraInstance(mActualFacingID); 
     } 
     if (mCamera == null) { 
      Log.i(TAG, "can't get camera instance"); 
      return; 
     } 
     try { 
      mCamera.setPreviewDisplay(mHolder); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     setCameraDisplayOrientation(); 
     setBestSupportedSizes(); 
     mCamera.startPreview(); 
    } 

    public void stop() { 
     Log.i(TAG, "stopCamera()"); 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

    public void switchFacing() { 
     if (mFrontFaceID == -1 || mBackFaceID == -1) { 
      return; 
     } 
     stop(); 
     if (mActualFacingID == mFrontFaceID) { 
      mActualFacingID = mBackFaceID; 
     } else { 
      mActualFacingID = mFrontFaceID; 
     } 
     start(); 
    } 

    public Camera getCameraInstance(int cameraID) { 
     Camera c = null; 
     if (cameraID != -1) { 
      try { 
       c = Camera.open(cameraID); 
      } catch (Exception e) { 
       e.printStackTrace(); 
       Log.i(TAG, "error opening camera: " + cameraID); 
      } 
     } 
     return c; 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     Log.i(TAG, "surfaceCreated()"); 
     start(); 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     Log.i(TAG, "surfaceChanged()"); 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     Log.i(TAG, "surfaceDestroyed()"); 
     stop(); 
    } 

    private void setBestSupportedSizes() { 
     if (mCamera == null) { 
      return; 
     } 
     Camera.Parameters parameters = mCamera.getParameters(); 
     List<Point> pictureSizes=getSortedSizes(parameters.getSupportedPictureSizes()); 

     List<Point> previewSizes=getSortedSizes(parameters.getSupportedPreviewSizes()); 

     Point previewResult=null; 
     for (Point size:previewSizes){ 
      float ratio = (float) size.y/size.x; 
      if(Math.abs(ratio-4/(float)3)<0.05){ //Aspect ratio of 4/3 because otherwise the image scales to much. 
       previewResult=size; 
       break; 
      } 
     } 
     Log.i(TAG,"preview: "+previewResult.x+"x"+previewResult.y); 
     Point pictureResult=null; 
     if(previewResult!=null){ 
      float previewRatio=(float)previewResult.y/previewResult.x; 
      for (Point size:pictureSizes){ 
       float ratio = (float) size.y/size.x; 
       if(Math.abs(previewRatio-ratio)<0.05){ 
        pictureResult=size; 
        break; 
       } 
      } 
     } 
     Log.i(TAG,"preview: "+pictureResult.x+"x"+pictureResult.y); 

     if(previewResult!=null && pictureResult!=null){ 
      Log.i(TAG,"best preview: "+previewResult.x+"x"+previewResult.y); 
      Log.i(TAG, "best picture: " + pictureResult.x + "x" + pictureResult.y); 
      parameters.setPreviewSize(previewResult.y, previewResult.x); 
      parameters.setPictureSize(pictureResult.y, pictureResult.x); 
      mCamera.setParameters(parameters); 
      mPreview.setBackgroundColor(Color.TRANSPARENT); //in the case of errors needed 
     }else{ 
      mCamera.stopPreview(); 
      mPreview.setBackgroundColor(Color.BLACK); 
     } 
    } 

    private List<Point> getSortedSizes(List<Camera.Size> sizes) { 
     ArrayList<Point> list = new ArrayList<>(); 

     for (Camera.Size size : sizes) { 
      int height; 
      int width; 
      if (size.width > size.height) { 
       height = size.width; 
       width = size.height; 
      } else { 
       height = size.height; 
       width = size.width; 
      } 
      list.add(new Point(width, height)); 

     } 

     Collections.sort(list, new Comparator<Point>() { 
      @Override 
      public int compare(Point lhs, Point rhs) { 
       long lhsCount = lhs.x * (long) lhs.y; 
       long rhsCount = rhs.x * (long) rhs.y; 
       if (lhsCount < rhsCount) { 
        return 1; 
       } 
       if (lhsCount > rhsCount) { 
        return -1; 
       } 
       return 0; 
      } 
     }); 
     return list; 
    } 

    public void onPictureTaken(byte[] data, Camera camera) { 
     //do something with your picture 
    } 

    //ROTATION 
    private void setCameraDisplayOrientation() { 
     if (mCamera != null) { 
      mCamera.setDisplayOrientation((int) getRotation()); 
     } 
    } 

    @Override 
    public float getRotation() { 
     Camera.CameraInfo info = new Camera.CameraInfo(); 
     Camera.getCameraInfo(mActualFacingID, info); 
     int rotation = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay() 
       .getRotation(); 
     int degrees = 0; 
     switch (rotation) { 
      case Surface.ROTATION_0: 
       degrees = 0; 
       break; 
      case Surface.ROTATION_90: 
       degrees = 90; 
       break; 
      case Surface.ROTATION_180: 
       degrees = 180; 
       break; 
      case Surface.ROTATION_270: 
       degrees = 270; 
       break; 
     } 

     int result; 
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
      result = (info.orientation + degrees) % 360; 
      result = (360 - result) % 360; // compensate the mirror 
     } else { // back-facing 
      result = (info.orientation - degrees + 360) % 360; 
     } 
     return result; 
    } 
} 

最後這裏是XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical"> 

    <FrameLayout 
     android:id="@+id/preview" 
     android:layout_width="match_parent" 
     android:layout_height="@dimen/photo_example_height"> 
     <SurfaceView 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:id="@+id/surfaceView" /> 
    </FrameLayout> 
</LinearLayout> 

我確實有所有必要的permissions問題是在編譯或運行時沒有錯誤!我做錯了什麼,全能否認我在對話框中的預覽?

+0

可能完全在這裏 - 但你可以嘗試使用紋理視圖,而不是表面視圖?據我記得,表面視圖不能在對話框中工作... – Frame91

+0

@ Frame91你也許完全正確!如果你有一個小代碼,作爲答案張貼,我會嘗試。現在我已經真正被這個日子掀起了! –

+0

我會盡力在一天結束時寫一小段代碼! – Frame91

回答

1

我想這個問題是在這裏在這一行:

mPreview = (SurfaceView) findViewById(R.id.surfaceView); 

你正試圖從你的活動得到它,但它不存在。你的Surfaceview實際上是在Container中。試試這個:

這個替換您上面的代碼行:

mPreview = (SurfaceView) containerViews[index].findViewById(R.id.surfaceView); 

希望它會工作!