要使用Camera2 API从相机显示预览,您应该执行以下步骤:
>获得使用相机设备的权限
>使用CameraManager打开与相机的连接
准备表面预览
>使用打开的相机设备和所需的曲面(它不仅可以包括预览曲面)创建CaptureSession
> CaptureSession创建后,您需要创建并配置CaptureRequest并将其提交给CaptureSession
需要注意的是,准备表面和打开连接到相机是独立的过程,所以您需要确保它们都是在创建CaptureSession之前完成的.
以下是在屏幕上显示相机预览的活动示例:
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,Handler.Callback {
static final String TAG = "CamTest";
static final int MY_PERMISSIONS_REQUEST_CAMERA = 1242;
private static final int MSG_CAMERA_OPENED = 1;
private static final int MSG_SURFACE_READY = 2;
private final Handler mHandler = new Handler(this);
SurfaceView mSurfaceView;
SurfaceHolder mSurfaceHolder;
CameraManager mCameraManager;
String[] mCameraIDsList;
CameraDevice.StateCallback mCameraStateCB;
CameraDevice mCameraDevice;
CameraCaptureSession mCaptureSession;
boolean mSurfaceCreated = true;
boolean mIsCameraConfigured = false;
private Surface mCameraSurface = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.mSurfaceView = (SurfaceView) findViewById(R.id.SurfaceViewPreview);
this.mSurfaceHolder = this.mSurfaceView.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
try {
mCameraIDsList = this.mCameraManager.getCameraIdList();
for (String id : mCameraIDsList) {
Log.v(TAG,"CameraID: " + id);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
mCameraStateCB = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
Toast.makeText(getApplicationContext(),Toast.LENGTH_SHORT).show();
mCameraDevice = camera;
mHandler.sendEmptyMessage(MSG_CAMERA_OPENED);
}
@Override
public void onDisconnected(CameraDevice camera) {
Toast.makeText(getApplicationContext(),Toast.LENGTH_SHORT).show();
}
@Override
public void onError(CameraDevice camera,int error) {
Toast.makeText(getApplicationContext(),Toast.LENGTH_SHORT).show();
}
};
}
@Override
protected void onStart() {
super.onStart();
//requesting permission
int permissionCheck = ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)) {
} else {
ActivityCompat.requestPermissions(this,MY_PERMISSIONS_REQUEST_CAMERA);
Toast.makeText(getApplicationContext(),Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(),Toast.LENGTH_SHORT).show();
try {
mCameraManager.openCamera(mCameraIDsList[1],mCameraStateCB,new Handler());
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
@Override
protected void onStop() {
super.onStop();
try {
if (mCaptureSession != null) {
mCaptureSession.stopRepeating();
mCaptureSession.close();
mCaptureSession = null;
}
mIsCameraConfigured = false;
} catch (final CameraAccessException e) {
// Doesn't matter,cloising device anyway
e.printStackTrace();
} catch (final IllegalStateException e2) {
// Doesn't matter,cloising device anyway
e2.printStackTrace();
} finally {
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
mCaptureSession = null;
}
}
}
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_CAMERA_OPENED:
case MSG_SURFACE_READY:
// if both surface is created and camera device is opened
// - ready to set up preview and other things
if (mSurfaceCreated && (mCameraDevice != null)
&& !mIsCameraConfigured) {
configureCamera();
}
break;
}
return true;
}
private void configureCamera() {
// prepare list of surfaces to be used in capture requests
List sfl = new ArrayList();
sfl.add(mCameraSurface); // surface for viewfinder preview
// configure camera with all the surfaces to be ever used
try {
mCameraDevice.createCaptureSession(sfl,new CaptureSessionListener(),null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
mIsCameraConfigured = true;
}
@Override
public void onRequestPermissionsResult(int requestCode,@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode,grantResults);
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_CAMERA:
if (ActivityCompat.checkSelfPermission(this,Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
try {
mCameraManager.openCamera(mCameraIDsList[1],new Handler());
} catch (CameraAccessException e) {
e.printStackTrace();
}
break;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCameraSurface = holder.getSurface();
}
@Override
public void surfaceChanged(SurfaceHolder holder,int height) {
mCameraSurface = holder.getSurface();
mSurfaceCreated = true;
mHandler.sendEmptyMessage(MSG_SURFACE_READY);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mSurfaceCreated = false;
}
private class CaptureSessionListener extends
CameraCaptureSession.StateCallback {
@Override
public void onConfigureFailed(final CameraCaptureSession session) {
Log.d(TAG,"CaptureSessionConfigure Failed");
}
@Override
public void onConfigured(final CameraCaptureSession session) {
Log.d(TAG,"CaptureSessionConfigure onConfigured");
mCaptureSession = session;
try {
CaptureRequest.Builder previewRequestBuilder = mCameraDevice
.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewRequestBuilder.addTarget(mCameraSurface);
mCaptureSession.setRepeatingRequest(previewRequestBuilder.build(),null,null);
} catch (CameraAccessException e) {
Log.d(TAG,"setting up preview Failed");
e.printStackTrace();
}
}
}
}