android surfaceview camera,android – 如何在SurfaceView上显示相机预览?

本文详细介绍了如何使用Android Camera2 API在应用中实现相机预览功能,包括权限请求、SurfaceView设置、CameraManager操作、CaptureSession创建及配置CaptureRequest。跟随步骤,一步步搭建完整的相机预览流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要使用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();

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值