android camera2 API使用程式碼
阿新 • • 發佈:2018-12-18
public class MainActivity extends AppCompatActivity { private final int REQUEST_CAMERA_PERMISSION = 0; private TextureView mTextureView; private ImageButton mCaptureBtn; private CameraManager mCameraManager; private CameraDevice mCameraDevice; private String mCameraId; private Size mPreviewSize; private int mWidth; private int mHeight; private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice cameraDevice) { mCameraDevice = cameraDevice; createCameraPreview(); } @Override public void onDisconnected(CameraDevice cameraDevice) { mCameraDevice.close(); mCameraDevice = null; } @Override public void onError(CameraDevice cameraDevice, int i) { mCameraDevice.close(); mCameraDevice = null; } }; private HandlerThread mBackgroundThread; private Handler mBackgroundHandler; private static SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 0); ORIENTATIONS.append(Surface.ROTATION_90, 90); ORIENTATIONS.append(Surface.ROTATION_180, 180); ORIENTATIONS.append(Surface.ROTATION_270, 270); } private CameraCaptureSession mSession; private CaptureRequest.Builder mBuilder; private CameraCaptureSession.CaptureCallback mSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) { super.onCaptureStarted(session, request, timestamp, frameNumber); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mCameraManager = (CameraManager) getSystemService(CAMERA_SERVICE); mTextureView = (TextureView) findViewById(R.id.camera_texture_view); mCaptureBtn = (ImageButton) findViewById(R.id.capture_btn); mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { mWidth = width; mHeight = height; getCameraId(); openCamera(); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { } }); } private void getCameraId() { try { for (String cameraId : mCameraManager.getCameraIdList()) { CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId); if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) { continue; } mCameraId = cameraId; return; } } catch (CameraAccessException e) { e.printStackTrace(); } } private Size getPreferredPreviewSize(Size[] sizes, int width, int height) { List<Size> collectorSizes = new ArrayList<>(); for (Size option : sizes) { if (width > height) { if (option.getWidth() > width && option.getHeight() > height) { collectorSizes.add(option); } } else { if (option.getHeight() > width && option.getWidth() > height) { collectorSizes.add(option); } } } if (collectorSizes.size() > 0) { return Collections.min(collectorSizes, new Comparator<Size>() { @Override public int compare(Size s1, Size s2) { return Long.signum(s1.getWidth() * s1.getHeight() - s2.getWidth() * s2.getHeight()); } }); } return sizes[0]; } private void openCamera() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { Log.e("CameraNew", "Lacking privileges to access camera service, please request permission first."); ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_CAMERA_PERMISSION); } try { mCameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, null); startBackgroundThread(); } catch (CameraAccessException e) { e.printStackTrace(); } } public void startBackgroundThread() { mBackgroundThread = new HandlerThread("Camera Background"); mBackgroundThread.start(); mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); } public void stopBackgroundThread() { if (mBackgroundThread != null) { mBackgroundThread.quitSafely(); try { mBackgroundThread.join(); mBackgroundThread = null; mBackgroundHandler = null; } catch (InterruptedException e) { e.printStackTrace(); } } } private void createCameraPreview() { try { SurfaceTexture texture = mTextureView.getSurfaceTexture(); assert texture != null; CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(mCameraId); StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); int deviceOrientation = getWindowManager().getDefaultDisplay().getOrientation(); int totalRotation = sensorToDeviceRotation(characteristics, deviceOrientation); boolean swapRotation = totalRotation == 90 || totalRotation == 270; int rotatedWidth = mWidth; int rotatedHeight = mHeight; if (swapRotation) { rotatedWidth = mHeight; rotatedHeight = mWidth; } mPreviewSize = getPreferredPreviewSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight); texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); Log.e("CameraActivity", "OptimalSize width: " + mPreviewSize.getWidth() + " height: " + mPreviewSize.getHeight()); Surface surface = new Surface(texture); mBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mBuilder.addTarget(surface); mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { if (null == mCameraDevice) { return; } mSession = cameraCaptureSession; mBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); try { mSession.setRepeatingRequest(mBuilder.build(), mSessionCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { Toast.makeText(MainActivity.this, "Camera configuration change", Toast.LENGTH_SHORT).show(); } }, null); } catch (CameraAccessException e) { e.printStackTrace(); } } private static int sensorToDeviceRotation(CameraCharacteristics characteristics, int deviceOrientation) { int sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); deviceOrientation = ORIENTATIONS.get(deviceOrientation); return (sensorOrientation + deviceOrientation + 360) % 360; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == REQUEST_CAMERA_PERMISSION) { if (grantResults.length <= 0 || grantResults[0] == PackageManager.PERMISSION_DENIED) { // Permission denied Toast.makeText(this, "User denied permission, can't use take photo feature.", Toast.LENGTH_SHORT).show(); } else { } } } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); if (mSession != null) { mSession.close(); mSession = null; } if (mCameraDevice != null) { mCameraDevice.close(); mCameraDevice = null; } stopBackgroundThread(); }