我正在使用Xamarin編寫Android應用程序,該應用程序具有用於使用Camera
API捕獲圖片的自定義活動。這項活動完全適用於我測試過的所有設備,但是有些用戶在嘗試拍攝照片時報告應用程序崩潰。很明顯,所有這些用戶都使用三星手機,不幸的是我沒有一個可以測試。在三星手機上拍照失敗
謝天謝地,我已經能夠捕獲到異常和堆棧跟蹤,但是我很遺憾,可能會導致這個問題。下面是異常,堆棧跟蹤和有問題的代碼。
這是一個相當簡單的活動,全屏相機預覽,閃光切換和捕捉按鈕。它使用定製的CameraHelper
類來設置和與Camera
API進行交互。在用戶能夠進行交互並觸發TakePicture
方法之前,配置攝像頭並通過OnSurfaceTextureAvailable
方法顯示預覽。
異常堆棧跟蹤
java.lang.RuntimeException: takePicture failed
android.hardware.Camera.native_takePicture(Native Method):0
android.hardware.Camera.takePicture(Camera.java:1523):0
android.hardware.Camera.takePicture(Camera.java:1468):0
md5efa7d89b8a471e1a97a183b83296df21.CameraHelper.n_onAutoFocus(Native Method):0
md5efa7d89b8a471e1a97a183b83296df21.CameraHelper.onAutoFocus(CameraHelper.java:39):0
方法在CameraHelper
// Implements Camera.IPictureCallback and Camera.IAutoFocusCallback
public void OnSurfaceTextureAvailable(object sender, TextureView.SurfaceTextureAvailableEventArgs e)
{
// Get the camera and set its orientation
try
{
_camera = Camera.Open(_cameraInt);
}
catch (Exception ex)
{
_callback.OnInitializationFailed(ex);
return;
}
var orientation = GetDisplayOrientation();
_camera.SetDisplayOrientation(orientation);
// Set the camera parameters
var cameraParameters = _camera.GetParameters();
if (cameraParameters.SupportedFocusModes != null && cameraParameters.SupportedFocusModes.Contains(Camera.Parameters.FocusModeContinuousPicture))
cameraParameters.FocusMode = Camera.Parameters.FocusModeContinuousPicture;
if (cameraParameters.SupportedFlashModes != null && cameraParameters.SupportedFlashModes.Contains(Camera.Parameters.FlashModeAuto))
{
cameraParameters.FlashMode = Camera.Parameters.FlashModeAuto;
HasFlash = true;
}
cameraParameters.JpegQuality = JPEG_QUALITY;
// Set the picture resolution
var pictureSize = GetIdealPictureSize(cameraParameters.SupportedPictureSizes, MAX_MEGAPIXELS);
_imageWidth = pictureSize.Width;
_imageHeight = pictureSize.Height;
cameraParameters.SetPictureSize(pictureSize.Width, pictureSize.Height);
// Set the preview resolution to best match the TextureView
var previewSize = GetIdealPreviewSize(cameraParameters.SupportedPreviewSizes, _previewTexture.Height, _previewTexture.Width);
cameraParameters.SetPreviewSize(previewSize.Width, previewSize.Height);
// Begin outputting camera preview
_camera.SetParameters(cameraParameters);
_camera.SetPreviewTexture(_previewTexture.SurfaceTexture);
_camera.StartPreview();
UpdatePreviewTextureMatrix(); // Ensure the preview is displayed without warping
// Wait for the preview
EventHandler<TextureView.SurfaceTextureUpdatedEventArgs> h = null;
_previewTexture.SurfaceTextureUpdated += h = (s, e2) =>
{
_previewTexture.SurfaceTextureUpdated -= h;
_callback.OnCameraPreviewReady();
_ready = true;
};
}
public void TakePicture()
{
if (!_ready || _busy)
{
var e = new Exception("Camera not ready");
OnTakePictureFailed(e);
return;
}
_busy = true;
_camera.AutoFocus(this);
}
public void OnAutoFocus(bool success, Camera camera)
{
try
{
_camera.TakePicture(null, null, this);
}
catch (Exception e)
{
// On Samsung phones the exception is always thrown here
OnTakePictureFailed(e);
}
}
public void OnPictureTaken(byte[] data, Camera camera)
{
_busy = false;
var rotation = GetPictureRotation();
_callback.OnPictureTaken(data, rotation, _imageWidth, _imageHeight);
}
private void OnTakePictureFailed(Exception e)
{
_busy = false;
_callback.OnTakePictureFailed(e);
}
相機可用並且預覽顯示沒有問題,異常只扔在三星設備。
看來,'startPreview()'方法是不在拍照之前被呼叫。拍攝照片後,您可能需要再次調用它。看看這個'Camera'類的8個頂級步驟:http://developer.android.com/reference/android/hardware/Camera.html –
嗨,Jon,預覽開始。你可以在我上面發佈的代碼中看到這一點。 –