问题描述
在我的主要活动中,我使用片段将两个用例分开,分别是ImageCapture和VideoCapture。每个片段都有一个TextureView,CameraX API在其中设置预览和用例以及一个按钮,以开始录制或拍照。主要活动布局具有FragmentLayout来包含片段,并带有在两者之间切换的按钮。
当我尝试过快地在两个片段之间切换时发生错误。
E/BufferQueueProducer: [ImageReader-4608x3456f100m2-25122-3](this:0x756dff9000,id:31,api:4,p:25122,c:25122) connect: already connected (cur=4 req=4)
E/Legacy-CameraDevice-JNI: connectSurface: Unable to connect to surface,error Invalid argument (-22).
LegacyCameraDevice_nativeConnectSurface: Error while configuring surface Invalid argument (-22).
E/AndroidRuntime: FATAL EXCEPTION: RequestThread-0
Process: com.vid.poly,PID: 25122
java.lang.UnsupportedOperationException: Unknown error -22
at android.hardware.camera2.legacy.LegacyExceptionUtils.throwOnError(LegacyExceptionUtils.java:77)
at android.hardware.camera2.legacy.LegacyCameraDevice.connectSurface(LegacyCameraDevice.java:702)
at android.hardware.camera2.legacy.RequestThreadManager.configureOutputs(RequestThreadManager.java:414)
at android.hardware.camera2.legacy.RequestThreadManager.-wrap0(Unknown Source:0)
at android.hardware.camera2.legacy.RequestThreadManager$5.handleMessage(RequestThreadManager.java:721)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
我一直到处逛逛,发现了类似的问题,这些问题可以帮助我减少遇到的错误数量,但该问题似乎是我的应用程序特有的。我读到缓冲队列属于TextureView(我认为),它涉及设置用例。但是我有两个仅属于“图片”或“视频”的TextureViews,为什么仍然说它“已经连接”。在切换片段之前,我调用CameraX.unbindAll(),这样是否应该完全删除用例呢?
public class PictureFragment extends Fragment {
private static final String TAG = "PictureFragment";
private Preview preview;
TextureView textureView;
PreviewConfig pConfig;
TextView textView = null;
View view;
public PictureFragment() {
// Required empty public constructor
Log.i(TAG,"The Picture fragment has started");
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_picture,container,false);
textView = view.findViewById(R.id.fragment_picture_text);
textView.setText("This is from within the onCreateView function");
textureView = view.findViewById(R.id.picture_texture);
startCamera();
setupPictures();
return view;
}
@Override
public void onDestroy() {
super.onDestroy();
CameraX.unbindAll();
}
private void updateTransform() {
Matrix mx = new Matrix();
float w = textureView.getMeasuredWidth();
float h = textureView.getMeasuredHeight();
float cx = w / 2f;
float cy = h / 2f;
int rotationDgr;
int rotation = (int) textureView.getRotation();
switch (rotation) {
case Surface.ROTATION_0:
rotationDgr = 0;
break;
case Surface.ROTATION_90:
rotationDgr = 90;
break;
case Surface.ROTATION_180:
rotationDgr = 180;
break;
case Surface.ROTATION_270:
rotationDgr = 270;
break;
default:
return;
}
mx.postRotate((float) rotationDgr,cx,cy);
textureView.setTransform(mx);
}
private void startCamera() {
CameraX.unbindAll();
Rational aspectRatio = new Rational(textureView.getWidth(),textureView.getHeight());
Size screen = new Size(textureView.getWidth(),textureView.getHeight());
pConfig = new PreviewConfig.Builder().setTargetAspectRatio(aspectRatio).setTargetResolution(screen).build();
}
private void setupPictures() {
preview = new Preview(pConfig);
preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() {
@Override
public void onUpdated(Preview.PreviewOutput output) {
ViewGroup parent = (ViewGroup) textureView.getParent();
parent.removeView(textureView);
parent.addView(textureView);
textureView.setSurfaceTexture(output.getSurfaceTexture());
updateTransform();
}
});
ImageCaptureConfig imageCaptureConfig = new ImageCaptureConfig.Builder().setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY).
setTargetRotation(getActivity().getWindowManager().getDefaultDisplay().getRotation()).build();
final ImageCapture imgCap = new ImageCapture(imageCaptureConfig);
view.findViewById(R.id.snap_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File imageOutputFile = createOutputFile(true);
imgCap.takePicture(imageOutputFile,new ImageCapture.OnImageSavedListener() {
@Override
public void onImageSaved(@NonNull File file) {
String msg = "Pic capture at " + file.getAbsolutePath();
Toast.makeText(getActivity().getBaseContext(),msg,Toast.LENGTH_SHORT).show();
}
@Override
public void onError(@NonNull ImageCapture.UseCaseError useCaseError,@NonNull String message,@Nullable Throwable cause) {
String msg = "Pic Capture failed: " + message;
Toast.makeText(getActivity().getBaseContext(),Toast.LENGTH_SHORT).show();
if (cause != null) {
cause.printStackTrace();
}
}
});
}
});
CameraX.bindToLifecycle(this,preview,imgCap);
}
private File createOutputFile(boolean picture) {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String extension = picture ? ".jpg" : ".mp4";
String imageFileName = "MP4_" + timeStamp + "_";
File storageDir = new File("/storage/emulated/0/DCIM/Camera/");
File outputFile = null;
try {
outputFile = File.createTempFile(
imageFileName,/* prefix */
extension,/* suffix */
storageDir /* directory */
);
} catch (IOException e) {
e.printStackTrace();
}
return outputFile;
}
}
VideoFragment类看起来与PictureFragment相同。我认为您可以使用两个PictureFragments复制问题。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)