Xamarin 如何让camera2 api再次工作?
我正在使用Xamarin/Android(不是表单),试图将Camera2BasicAPI示例集成到我的项目中。 我没有改变样本中的任何内容,我只对使用主摄像头和拍摄快照感兴趣 我的项目有一个主要活动,camera2是它的一个片段,我这样称呼它:Xamarin 如何让camera2 api再次工作?,xamarin,android-camera2,Xamarin,Android Camera2,我正在使用Xamarin/Android(不是表单),试图将Camera2BasicAPI示例集成到我的项目中。 我没有改变样本中的任何内容,我只对使用主摄像头和拍摄快照感兴趣 我的项目有一个主要活动,camera2是它的一个片段,我这样称呼它: string fragmentTag = this.Resources.GetString(Resource.String.camera_form); // Begin the transaction FragmentTransaction
string fragmentTag = this.Resources.GetString(Resource.String.camera_form);
// Begin the transaction
FragmentTransaction trans = this.FragmentManager.BeginTransaction();
// Replace the old fragment with the new one.
trans.Add(Resource.Id.fragment_container, camera2BasicFragment, fragmentTag);
// Add the transaction to the back stack.
// The tag is added so we can use PopBackStack to skip a screen on the back key
trans.AddToBackStack(fragmentTag);
// Don't forget to commit
trans.Commit();
一切都是第一次工作。它拍摄照片并将其保存到文件夹中
第二次运行时,它会显示一个预览,然后当我拍照时,它会在此处崩溃,抛出的位置是:
public void CaptureStillPicture()
{
try
{
var activity = Activity;
if (null == activity || null == mCameraDevice)
{
return;
}
// This is the CaptureRequest.Builder that we use to take a picture.
if (stillCaptureBuilder == null)
stillCaptureBuilder = mCameraDevice.CreateCaptureRequest(CameraTemplate.StillCapture);
stillCaptureBuilder.AddTarget(mImageReader.Surface);
// Use the same AE and AF modes as the preview.
stillCaptureBuilder.Set(CaptureRequest.ControlAfMode, (int)ControlAFMode.ContinuousPicture);
SetAutoFlash(stillCaptureBuilder);
// Orientation
int rotation = (int)activity.WindowManager.DefaultDisplay.Rotation;
stillCaptureBuilder.Set(CaptureRequest.JpegOrientation, GetOrientation(rotation));
mCaptureSession.StopRepeating();
try
{
mCaptureSession.Capture(stillCaptureBuilder.Build(), new CameraCaptureStillPictureSessionCallback(this), null);
}
catch (System.Exception e)
{
throw;
}
}
catch (CameraAccessException e)
{
e.PrintStackTrace();
}
}
出现此错误时:
{Java.Lang.IllegalArgumentException: CaptureRequest contains unconfigured Input/Output Surface!
at Java.Interop.JniEnvironment+InstanceMethods.CallIntMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <286213b9e14c442ba8d8d94cc9dbec8e>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeAbstractInt32Method (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00014] in <286213b9e14c442ba8d8d94cc9dbec8e>:0
at Android.Hardware.Camera2.CameraCaptureSessionInvoker.Capture (Android.Hardware.Camera2.CaptureRequest request, Android.Hardware.Camera2.CameraCaptureSession+CaptureCallback listener, Android.OS.Handler handler) [0x00078] in <b781ed64f1d743e7881ac038e0fbdf85>:0
at RvsMobileApp.Activities.Camera2BasicFragment.CaptureStillPicture () [0x000b7] in C:\Source\RVS\rvs-mobile-app\src\Rvs.Mobile.App\Activities\Camera2BasicFragment.cs:807
--- End of managed Java.Lang.IllegalArgumentException stack trace ---
java.lang.IllegalArgumentException: CaptureRequest contains unconfigured Input/Output Surface!
at android.hardware.camera2.CaptureRequest.convertSurfaceToStreamId(CaptureRequest.java:674)
at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:1066)
at android.hardware.camera2.impl.CameraDeviceImpl.capture(CameraDeviceImpl.java:936)
at android.hardware.camera2.impl.CameraCaptureSessionImpl.capture(CameraCaptureSessionImpl.java:173)
at md5bbb797339b35f7667da89d6634e22c37.CameraCaptureListener.n_onCaptureCompleted(Native Method)
at md5bbb797339b35f7667da89d6634e22c37.CameraCaptureListener.onCaptureCompleted(CameraCaptureListener.java:37)
at android.hardware.camera2.impl.CameraCaptureSessionImpl$1.lambda$onCaptureCompleted$3(CameraCaptureSessionImpl.java:640)
at android.hardware.camera2.impl.-$$Lambda$CameraCaptureSessionImpl$1$OA1Yz_YgzMO8qcV8esRjyt7ykp4.run(Unknown Source:8)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.os.HandlerThread.run(HandlerThread.java:65)
}
base: {Java.Lang.RuntimeException}
JniPeerMembers: {Android.Runtime.XAPeerMembers}
{Java.Lang.IllegalArgumentException:CaptureRequest包含未配置的输入/输出表面!
在Java.Interop.JniEnvironment+InstanceMethods.CallIntMethod(Java.Interop.JniObjectReference实例,Java.Interop.JniMethodInfo方法,Java.Interop.JniArgumentValue*args)[0x00069]中:0
在Java.Interop.jnipermembers+JniInstanceMethods.InvokeAbstractInt32Method(System.String encodedMember,Java.Interop.IJavaPeerable self,Java.Interop.JniArgumentValue*参数)[0x00014]中:0
在Android.Hardware.Camera2.CameraCaptureSessionInvoker.Capture(Android.Hardware.Camera2.CaptureRequest,Android.Hardware.Camera2.CameraCaptureSession+CaptureCallback listener,Android.OS.Handler处理程序)[0x00078]中:0
在C:\Source\RVS\RVS mobile app\src\RVS.mobile.app\Activities\Camera2BasicFragment.CaptureStillPicture()[0x000b7]中的RvsMobileApp.Activities.Camera2BasicFragment.cs:807
---托管Java.Lang.IllegalArgumentException堆栈跟踪的结束---
java.lang.IllegalArgumentException:CaptureRequest包含未配置的输入/输出表面!
位于android.hardware.camera2.CaptureRequest.convertSurfaceToStreamId(CaptureRequest.java:674)
位于android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:1066)
位于android.hardware.camera2.impl.CameraDeviceImpl.capture(CameraDeviceImpl.java:936)
在android.hardware.camera2.impl.CameraCaptureSessionImpl.capture(CameraCaptureSessionImpl.java:173)中
在MD5BB797339B35F7667DA89D6634E22C37.CameraCaptureListener.n_onCaptureCompleted(本机方法)
位于MD5BB797339B35F7667DA89D6634E22C37.CameraCaptureListener.onCaptureCompleted(CameraCaptureListener.java:37)
在android.hardware.camera2.impl.CameraCaptureSessionImpl$1.lambda$onCaptureSessionCompleted$3(CameraCaptureSessionImpl.java:640)
在android.hardware.camera2.impl.-$$Lambda$CameraCaptureSessionImpl$1$OA1Yz_YgzMO8qcV8esRjyt7ykp4.run(未知来源:8)
位于android.os.Handler.handleCallback(Handler.java:873)
位于android.os.Handler.dispatchMessage(Handler.java:99)
位于android.os.Looper.loop(Looper.java:214)
运行(HandlerThread.java:65)
}
基:{Java.Lang.RuntimeException}
JNIperMembers:{Android.Runtime.XAPeerMembers}
起初,我认为这是内存泄漏,所以我确定我的片段正在自我毁灭。按下finished按钮时,我是如何结束片段的:
case Resource.Id.camera_finished:
// EventHandler<DialogClickEventArgs> nullHandler = null;
Activity activity = Activity;
if (activity != null)
{
// Send all of the data to the service
// SendPhotosAndDataToService();
// Call the paren activitity's back to END this Fragment
activity.FragmentManager.BeginTransaction().Remove(this).CommitNow();
//activity.OnBackPressed();
}
break;
case Resource.Id.camera\u已完成:
//EventHandler nullHandler=null;
活动=活动;
if(活动!=null)
{
//将所有数据发送到服务
//SendPhotosAndDataToService();
//打电话给paren Activity结束这个片段
activity.FragmentManager.BeginTransaction().Remove(this.CommitNow();
//activity.OnBackPressed();
}
打破
以下是我重现错误的步骤:
启动摄影机(加载片段)
查看预览
拍照
返回主活动(关闭片段)
启动摄影机(加载片段)
查看预览
拍张照片
只要我不拍任何照片,我就可以根据需要多次加载和卸载片段
我在谷歌上搜索了“CaptureRequest包含未配置的输入/输出界面!”,但没有获得足够的信息来真正理解问题。
我认为在第一次跑步后,有些东西没有清理干净。
我已经研究这个问题好几天了。在还原相机片段时,请重新初始化stillCaptureBuilder。更好的是,当片段被销毁时,请确保清理stillCaptureBuilder。正如Alex Cohn指出的,我在阅读本文时发现: 这是一个很好的资源,顺便说一句,示例代码并没有发布stillCaptureBuilder,所以它可以再次使用
public void CaptureStillPicture()
{
try
{
var activity = Activity;
if (null == activity || null == mCameraDevice)
{
return;
}
// THIS WAS NOT RELEASING THE RESOURCES AND SHOULD BE REMOVED FROM THE SAMPLE!
//// This is the CaptureRequest.Builder that we use to take a picture.
////if (stillCaptureBuilder == null)
//// stillCaptureBuilder = mCameraDevice.CreateCaptureRequest(CameraTemplate.StillCapture);
// This is the proper code
var stillCaptureBuilder = mCameraDevice.CreateCaptureRequest(CameraTemplate.StillCapture);
stillCaptureBuilder.AddTarget(mImageReader.Surface);
// Use the same AE and AF modes as the preview.
stillCaptureBuilder.Set(CaptureRequest.ControlAfMode, (int)ControlAFMode.ContinuousPicture);
SetAutoFlash(stillCaptureBuilder);
// Orientation
int rotation = (int)activity.WindowManager.DefaultDisplay.Rotation;
stillCaptureBuilder.Set(CaptureRequest.JpegOrientation, GetOrientation(rotation));
mCaptureSession.StopRepeating();
mCaptureSession.AbortCaptures();
try
{
mCaptureSession.Capture(stillCaptureBuilder.Build(), new CameraCaptureStillPictureSessionCallback(this), null);
}
catch (System.Exception e)
{
throw;
}
}
catch (CameraAccessException e)
{
e.PrintStackTrace();
}
}
我正在记录这一点,以便任何其他与camera2斗争的人都可以学习。
一如既往地感谢您当您卸载片段时,不会破坏stillCaptureBuilder,会不会发生崩溃?请注意,在上,此生成器已创建,但仅当它为null时才创建。这是正确答案,我们同时找到了它。(这是我使用不完全理解的代码时得到的)。如何“清理”stillCaptureBuilder?@Darius在固定代码中,
stillCaptureBuilder
实例是CaptureSillPicture()
方法的本地实例。在原始代码中,它是fragment类的成员。我所说的clean只不过是指stillCaptureBuilder=null
。我同意在这种情况下,不需要跨CaptureStillPicture()请求保留stillCaptureBuilder
的实例。