2017-05-10 51 views
0

我正在開發相機應用程序。我寫了一些代碼來顯示預覽,但它不工作。沒有錯誤,但屏幕始終是黑色的。我想我錯過了一些東西。這是代碼。在Android中設置相機預覽

預覽

public class Preview extends SurfaceView implements SurfaceHolder.Callback { 

    private static final String TAG = "com.azeem.Debug"; 

    private Context context; 
    private SurfaceView mSurfaceView; 
    public Camera mCamera; 
    private static final Camera.CameraInfo mCameraInfo = new Camera.CameraInfo(); 
    private Display mDisplay; 
    private List<Camera.Size> mSupportedPreviewSizes; 
    Camera.Size mPreviewSize; 
    private static final int NO_CAMERA = -1; 
    private boolean mIsFrontCamera = false; 
    private boolean mIsFlashOn = false; 
    private int mFrontCameraId, mBackCameraId; 

    public Preview(Context ctx) { 
     super(ctx); 
     context = ctx; 
     Log.i(TAG, "First Constructor"); 
     init(); 
    } 

    public Preview(Context ctx, AttributeSet attrs) { 
     super(ctx, attrs); 
     context = ctx; 
     Log.i(TAG, "Second Constructor"); 
     init(); 
    } 

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

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     Log.i(TAG, "surfaceChanged"); 
     if(mPreviewSize != null) { 
      Log.i(TAG, "Activate Optimal Preview"); 
      Camera.Parameters parameters = mCamera.getParameters(); 
      parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
      mCamera.setParameters(parameters); 
      mCamera.startPreview(); 
     } 
    } 

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

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     Log.i(TAG, "onMeasure"); 
     final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
     final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
     setMeasuredDimension(width, height); 

     if (mSupportedPreviewSizes != null) { 
      mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); 
     } 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     Log.i(TAG, "onLayout"); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     Log.i(TAG, "onTouchEvent"); 
     return super.onTouchEvent(event); 
    } 

    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { 
     final double ASPECT_TOLERANCE = 0.1; 
     double targetRatio=(double)h/w; 

     if (sizes == null) return null; 

     Camera.Size optimalSize = null; 
     double minDiff = Double.MAX_VALUE; 

     int targetHeight = h; 

     for (Camera.Size size : sizes) { 
      double ratio = (double) size.width/size.height; 
      if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 

     if (optimalSize == null) { 
      minDiff = Double.MAX_VALUE; 
      for (Camera.Size size : sizes) { 
       if (Math.abs(size.height - targetHeight) < minDiff) { 
        optimalSize = size; 
        minDiff = Math.abs(size.height - targetHeight); 
       } 
      } 
     } 
     return optimalSize; 
    } 

    private void init(){ 
     Log.i(TAG, "init"); 
     if(hasCamera()) { 
      final SurfaceHolder surfaceHolder = this.getHolder(); 
      surfaceHolder.addCallback(this); 

      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) 
       surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

      mBackCameraId = findCameraId(false); 

      if(hasFrontCamera()){ 
       mFrontCameraId = findCameraId(true); 
      }else{ 
       mFrontCameraId = NO_CAMERA; // Front Face Camera Not found on device 
      } 

      final WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
      mDisplay = windowManager.getDefaultDisplay(); 

     } // Else Camera not found on device 
    } 

    public void setCamera(){ 
     Log.i(TAG, "setCamera"); 
     //if(mSurfaceView != null && hasCamera()){ 
     if(hasCamera()){ 
      mCamera = Camera.open(mBackCameraId); 
     } 
    } 

    public void start(){ 
     Log.i(TAG, "start"); 
     if(mCamera != null){ 
      try { 
       mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
       //mCamera.setPreviewDisplay(mSurfaceView.getHolder()); 
       mCamera.setPreviewDisplay(this.getHolder()); 
       mCamera.startPreview(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

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

    private boolean hasCamera() { 
     final PackageManager packageManager = context.getPackageManager(); 
     return packageManager != null 
       && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA); 
    } 

    private boolean hasFrontCamera() { 
     final PackageManager packageManager = context.getPackageManager(); 
     return packageManager != null 
       && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT); 
    } 

    private int findCameraId(boolean front) { 
     final int cameraCount = Camera.getNumberOfCameras(); 
     for (int i = 0; i < cameraCount; i++) { 
      Camera.getCameraInfo(i, mCameraInfo); 
      if ((front && mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) 
        || (!front && mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)) { 
       return i; 
      } 
     } 
     return NO_CAMERA; 
    } 

} 

MainActivity

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     preview = new Preview(this); 


    capturePicture.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       preview.mCamera.takePicture(null, null, jpegCallback); 
      } 
     }); 
    }  
    @Override 
    protected void onResume() { 
     super.onResume(); 
     preview.setCamera(); 
     preview.start(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     preview.stop(); 
    }  
    // Other Code.... 
} 

activity_main.xml中

<com.azeem.mycamera.Preview 
    android:id="@+id/surfaceView" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

<!-- Other Codes Buttons etc --> 

這是我的代碼使用但預覽不顯示。你能讓我知道我錯過了什麼嗎?

更新

也存在其中我提到的所有需要​​uses-premissions

預覽工作清單文件,當我setCamerapreview類,但是當我將它從MainActivity它不工作。

這是代碼的工作原理。 預覽類

// other code 
@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    Log.i(TAG, "surfaceCreated"); 
    this.setCamera(); 
    this.start(); 
} 
// other code 

MainActivity

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

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

@Override 
protected void onPause() { 
    super.onPause(); 
}  
// Other Code.... 

這是工作,但它不工作時,我把它從MainActivity正如我以前更新的是什麼我的問題顯示代碼你錯過了,請讓我知道。

+0

你需要分享有問題的預覽代碼 –

+0

@Javacoder我已經分享了'預覽'類這就是我所有的代碼 –

+0

在sdk中應該有一個示例應用程序。你應該找到並與你的代碼進行比較。 –

回答

0

您是否在Android Manifest中聲明瞭權限並檢查了使用Android最新版本的運行時權限。

+0

是的,我在android中聲明瞭權限 –

0

直到表面創建完畢才能開始預覽。因此,在工作代碼中的onSurfaceCreated中啓動攝像頭似乎很有意義。如果你真的想在onResume中強制執行這個行爲,那麼你可以做的最好的做法是維護兩個標誌:resumed和surfaceCreated。

像這樣的東西(注:僞代碼)...

onResume(...){ 
    resumed = true; 
    if (surfaceCreated){ 
     startCam(); 
    } 
} 

onSurfaceCreated(){ 
    surfaceCreated = true; 
    if (resumed){ 
     startCam(); 
    } 
} 

onPause(){ 
    resumed = false; 
} 

onSurfaceDestroyed(){ 
    surfaceCreated = false; 
} 

這將確保所有的條件設置相機時得到滿足。