Android Jetpack之CameraX使用
16lz
2021-01-23
文章目录
- 添加Gradle依赖
- 权限
- 配置CameraX
- 拍照和录像
- 保存和预览
- 预览照片和录像
参考:
https://developer.android.google.cn/training/camerax
https://codelabs.developers.google.com/codelabs/camerax-getting-started/#0
代码Github:https://github.com/345166018/HxJetpack/tree/master/HxCameraX
添加Gradle依赖
//material组件 implementation 'com.google.android.material:material:1.1.0-alpha10' //camera implementation 'androidx.camera:camera-core:1.0.0-alpha04' implementation 'androidx.camera:camera-camera2:1.0.0-alpha04' implementation 'androidx.camera:camera-view:1.0.0-alpha01' implementation 'androidx.camera:camera-extensions:1.0.0-alpha01' //gesture imageview implementation 'com.github.chrisbanes:PhotoView:2.3.0' //图片加载 implementation 'com.github.bumptech.glide:glide:4.9.0' implementation 'jp.wasabeef:glide-transformations:4.0.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0' //视频播放组件 implementation 'com.google.android.exoplayer:exoplayer-core:2.10.4' implementation 'com.google.android.exoplayer:exoplayer-dash:2.10.4' implementation 'com.google.android.exoplayer:exoplayer-ui:2.10.4'
CameraX需要一些Java 8的方法,app的build.gradle的buildTypes之后添加以下内容:
compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8}
权限
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
private static final String[] PERMISSIONS = new String[]{ Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}; private ArrayList<String> deniedPermission = new ArrayList<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_CODE);...} @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_CODE) { deniedPermission.clear(); for (int i = 0; i < permissions.length; i++) { String permission = permissions[i]; int result = grantResults[i]; if (result != PackageManager.PERMISSION_GRANTED) { deniedPermission.add(permission); } } if (deniedPermission.isEmpty()) { bindCameraX(); } else { new AlertDialog.Builder(this) .setMessage(getString(R.string.capture_permission_message)) .setNegativeButton(getString(R.string.capture_permission_no), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); CaptureActivity.this.finish(); } }) .setPositiveButton(getString(R.string.capture_permission_ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String[] denied = new String[deniedPermission.size()]; ActivityCompat.requestPermissions(CaptureActivity.this, deniedPermission.toArray(denied), PERMISSION_CODE); } }).create().show(); } } }
配置CameraX
@SuppressLint("RestrictedApi") private void bindCameraX() { CameraX.unbindAll(); PreviewConfig config = new PreviewConfig.Builder() //前后摄像头 .setLensFacing(mLensFacing) //旋转角度 .setTargetRotation(rotation) //分辨率 .setTargetResolution(resolution) //宽高比 .setTargetAspectRatio(rational) .build(); preview = new Preview(config); imageCapture = new ImageCapture(new ImageCaptureConfig.Builder() .setTargetAspectRatio(rational) .setTargetResolution(resolution) .setLensFacing(mLensFacing) .setTargetRotation(rotation).build()); videoCapture = new VideoCapture(new VideoCaptureConfig.Builder() .setTargetRotation(rotation) .setLensFacing(mLensFacing) .setTargetResolution(resolution) .setTargetAspectRatio(rational) //视频帧率 .setVideoFrameRate(25) //bit率 .setBitRate(10440).build()); preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() { @Override public void onUpdated(Preview.PreviewOutput output) { textureView = mBinding.textureView; ViewGroup parent = (ViewGroup) textureView.getParent(); parent.removeView(textureView); parent.addView(textureView, 0); textureView.setSurfaceTexture(output.getSurfaceTexture()); } }); CameraX.unbindAll(); CameraX.bindToLifecycle(this, preview, imageCapture, videoCapture); } @Override protected void onDestroy() { CameraX.unbindAll(); super.onDestroy(); }
拍照和录像
@Override public void onClick() { takingPicture = true; File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), System.currentTimeMillis() + ".jpeg"); mBinding.captureTips.setVisibility(View.INVISIBLE); imageCapture.takePicture(file, new ImageCapture.OnImageSavedListener() { @Override public void onImageSaved(@NonNull File file) { onFileSaved(file); } @Override public void onError(@NonNull ImageCapture.UseCaseError useCaseError, @NonNull String message, @Nullable Throwable cause) { showErrorToast(message); } }); } @SuppressLint("RestrictedApi") @Override public void onLongClick() { takingPicture = false; File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), System.currentTimeMillis() + ".mp4"); videoCapture.startRecording(file, new VideoCapture.OnVideoSavedListener() { @Override public void onVideoSaved(File file) { onFileSaved(file); } @Override public void onError(VideoCapture.UseCaseError useCaseError, String message, @Nullable Throwable cause) { showErrorToast(message); } }); }
保存和预览
private void onFileSaved(File file) { outputFilePath = file.getAbsolutePath(); String mimeType = takingPicture ? "image/jpeg" : "video/mp4"; MediaScannerConnection.scanFile(this, new String[]{ outputFilePath}, new String[]{ mimeType}, null); PreviewActivity.startActivityForResult(this, outputFilePath, !takingPicture, "完成"); }
预览照片和录像
private void previewImage(String previewUrl) { mPreviewBinding.photoView.setVisibility(View.VISIBLE); Glide.with(this).load(previewUrl).into(mPreviewBinding.photoView); } private void previewVideo(String previewUrl) { mPreviewBinding.playerView.setVisibility(View.VISIBLE); player = ExoPlayerFactory.newSimpleInstance(this, new DefaultRenderersFactory(this), new DefaultTrackSelector(), new DefaultLoadControl()); Uri uri = null; File file = new File(previewUrl); if (file.exists()) { DataSpec dataSpec = new DataSpec(Uri.fromFile(file)); FileDataSource fileDataSource = new FileDataSource(); try { fileDataSource.open(dataSpec); uri = fileDataSource.getUri(); } catch (FileDataSource.FileDataSourceException e) { e.printStackTrace(); } } else { uri = Uri.parse(previewUrl); } ProgressiveMediaSource.Factory factory = new ProgressiveMediaSource.Factory( new DefaultDataSourceFactory(this, Util.getUserAgent(this, getPackageName()))); ProgressiveMediaSource mediaSource = factory.createMediaSource(uri); player.prepare(mediaSource); player.setPlayWhenReady(true); mPreviewBinding.playerView.setPlayer(player); }
更多相关文章
- Android之权限管理
- Android 为【apk】文件签名,增加修改系统时间等权限
- 详解 Android 的 Activity 组件 -
- Android之Activity组件
- Android兼容android7.0、及Android8.0以上apk安装权限问题(二)
- Android架构组件-Navigation的使用(一)
- Android最新优秀而实用的开源组件1
- Android Jetpack架构组件Navigation管理Fragment框架
- android 概述 及四大组件