我试图在SurfaceView上打开相机硬件.在布局中,我创建了一个SurfaceView,我打开相机,如下面的代码所示.当我运行代码时,CameraAvailableCB中的烤面包机显示并显示“onCameraAvailable”,但SurfaceView上没有任何内容.
码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.mBtnCapture = (Button) findViewById(R.id.actMain_btn_capture); this.mSurfaceView = (SurfaceView) findViewById(R.id.actMain_surfaceView); this.mSurfaceHolder = this.mSurfaceView.getHolder(); this.mSurfaceHolder.addCallback(this); this.mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE); try { cameraIDsList = this.mCameraManager.getCameraIdList(); for (String id : cameraIDsList) { Log.v(TAG,"CameraID: " + id); } } catch (CameraAccessException e) { e.printStackTrace(); } cameraStateCB = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { Toast.makeText(getApplicationContext(),"onOpened",Toast.LENGTH_SHORT).show(); //requesting permission int permissionCheck = ContextCompat.checkSelfPermission(activity,Manifest.permission.CAMERA); if (permissionCheck != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(activity,Manifest.permission.CAMERA)) { } else { ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},MY_PERMISSIONS_REQUEST_CAMERA); Toast.makeText(getApplicationContext(),"request permission",Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(getApplicationContext(),"PERMISSION_ALREADY_GRANTED",Toast.LENGTH_SHORT).show(); } //opening the camera try { mCameraManager.openCamera(cameraIDsList[1],cameraStateCB,new Handler()); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onDisconnected(CameraDevice camera) { Toast.makeText(getApplicationContext(),"onDisconnected",Toast.LENGTH_SHORT).show(); } @Override public void onError(CameraDevice camera,int error) { Toast.makeText(getApplicationContext(),"onError",Toast.LENGTH_SHORT).show(); } }; CameraManager.AvailabilityCallback cameraAvailableCB = new CameraManager.AvailabilityCallback() { @Override public void onCameraAvailable(String cameraId) { super.onCameraAvailable(cameraId); Toast.makeText(getApplicationContext(),"onCameraAvailable",Toast.LENGTH_SHORT).show(); } @Override public void onCameraUnavailable(String cameraId) { super.onCameraUnavailable(cameraId); Toast.makeText(getApplicationContext(),"onCameraUnavailable",Toast.LENGTH_SHORT).show(); } }; this.mCameraManager.registerAvailabilityCallback(cameraAvailableCB,new Handler()); } @Override public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode,permissions,grantResults); switch (requestCode) { case MY_PERMISSIONS_REQUEST_CAMERA: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) // Open Camera break; } } @Override public void surfaceCreated(SurfaceHolder holder) { Log.w(TAG,"surfaceCreated"); } @Override public void surfaceChanged(SurfaceHolder holder,int format,int width,int height) { Log.w(TAG,"surfaceChanged"); } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.w(TAG,"surfaceDestroyed"); }
解决方法
要使用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<Surface> sfl = new ArrayList<Surface>(); 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(); } } } }