我有一个应用程序使用带有SurfaceView的相机。 这是Surface View的代码:
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraView(Context context, Camera camera){
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
//get the holder and set this class as the callback, so we can get camera data here
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try{
//when the surface is created, we can set the camera to draw images in this surfaceholder
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
//before changing the application orientation, you need to stop the preview, rotate and then start it again
if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try{
mCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera if it's not running
}
//now, recreate the camera preview
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
} catch (RuntimeException e){
} catch (Exception e){
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//our app has only one screen, so we'll destroy the camera in the surface
//if you are unsing with more screens, please move this code your activity
//mCamera.stopPreview();
//mCamera.release();
}
}
这是与其活动相关的相机代码:
public class CameraOverlay extends ActionBarActivity implements CameraLoopsAdapterDelegate {
private Camera mCamera = null;
private CameraView mCameraView = null;
FrameLayout camera_view;
Bitmap bmp = null;
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bmpAux = BitmapFactory.decodeByteArray(data, 0, data.length);
int rotationInDegrees;//PictureUtil.exifToDegrees(rotation);
Log.e("", "CAMERA MODE "+cameraMode+" (back, front)="+ CameraInfo.CAMERA_FACING_BACK+","+CameraInfo.CAMERA_FACING_FRONT);
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
Log.e("", "CAMERA ORIENTATION "+orientationOnPhoto);
if(cameraMode == Camera.CameraInfo.CAMERA_FACING_BACK) {
if (orientationOnPhoto == Constants.ORIENTATION_PORTRAIT_NORMAL)
rotationInDegrees = 90;
else if (orientationOnPhoto == Constants.ORIENTATION_PORTRAIT_INVERTED)
rotationInDegrees = 270;
else if (orientationOnPhoto == Constants.ORIENTATION_LANDSCAPE_NORMAL)
rotationInDegrees = 0;
else //if (orientationOnPhoto == Constants.ORIENTATION_LANDSCAPE_INVERTED)
rotationInDegrees = 180;
}
else {
if (orientationOnPhoto == Constants.ORIENTATION_PORTRAIT_NORMAL)
rotationInDegrees = 270;
else if (orientationOnPhoto == Constants.ORIENTATION_PORTRAIT_INVERTED)
rotationInDegrees = 90;
else if (orientationOnPhoto == Constants.ORIENTATION_LANDSCAPE_NORMAL)
rotationInDegrees = 0;
else //if (orientationOnPhoto == Constants.ORIENTATION_LANDSCAPE_INVERTED)
rotationInDegrees = 180;
}
Matrix matrix = new Matrix();
//if (rotationInDegrees != 0f)
matrix.preRotate(rotationInDegrees);
bmp = Bitmap.createBitmap(bmpAux, 0, 0, bmpAux.getWidth(), bmpAux.getHeight(), matrix, true);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_overlay);
getSupportActionBar().hide();
camera_view = (FrameLayout)findViewById(R.id.camera_view);
takePhotoIV = (ImageView)findViewById(R.id.camera_takepicture);
takePhotoIV.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(!PermissionsManager.getInstance(CameraOverlay.this).hasGivenPermission("android.permission.CAMERA"))
return;
orientationOnPhoto = mOrientation;
mCamera.takePicture(null, null, mPicture);
takePhotoIV.setVisibility(View.INVISIBLE);
}
});
sendTV = (TextView)findViewById(R.id.send_photo);
sendTV.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Here we send the photo stored on "bmp" to backend
resetCamera();
}
});
}
public void onResume()
{
super.onResume();
if(PermissionsManager.getInstance(CameraOverlay.this).hasGivenPermission("android.permission.CAMERA"))
{
try {
mCamera = Camera.open(cameraMode);//camera mode is an enumerated to use FRONT or BACK camera
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFlashMode(cameraFlash);
mCamera.setParameters(parameters);
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if(mCamera != null) {
mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
}
}
public void resetCamera()
{
if(!PermissionsManager.getInstance(CameraOverlay.this).hasGivenPermission("android.permission.CAMERA"))
return;
mCamera.stopPreview();
mCamera.release();
camera_view.removeAllViews();
mCamera = Camera.open(cameraMode);
try {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFlashMode(cameraFlash);
mCamera.setParameters(parameters);
} catch (RuntimeException e) {
Log.d("ERROR", "Error setting parameters: " + e.getMessage());
}
mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
}
此代码在我目前为止测试的所有设备上都正常运行:
现在,一些拥有三星Galaxy S7(Android 6)的用户报告说,当他们拍照时,它没有显示在相机视图中。相机的相框布局不会冻结,相机似乎仍在等待用户拍照。
但是如果用户点击发送,则照片会被发送到后端,因此已调用PictureCallback并且已正确创建了位图bmp。但是,为什么照片没有在其表面显示?
我试图找到关于此的任何文档但没有成功,但三星Galaxy S7与android.hardware.camera有什么问题?我应该将Camera2用于此设备吗?