Samsung phones crash images

I am writing an Android application using Xamarin that has a custom activity view used to capture images using the API Camera. This job works fine on all the devices I tested, however some users reported an application crash completely when trying to take a picture. It was quickly obvious that all these users used Samsung phones, and unfortunately, I do not have one test for testing.

Fortunately, I managed to grab the exception and stack trace, but I don't understand what might cause this problem. Exception, stack trace and problematic code below.

This is a fairly simple job with full-screen camera viewing, a flash switch, and a capture button. It uses its own CameraHelperclass to configure and interact with the API Camera. The camera is configured and the preview is displayed by the method OnSurfaceTextureAvailablebefore the user can interact and launch the method TakePicture.

Exception stack trace

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

Methods in 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);
}

The camera is available, and the preview is displayed without problems, and the exception applies only to Samsung devices.

+4
source share
1 answer

, Samsung Galaxy - , Samsung Galaxy OnAutoFocus . , Camera.TakePicture , , , , .

, , , , Camera.TakePicture:

public void OnAutoFocus(bool success, Camera camera)
{
  if (_hasAttemptedFocus) return;
  else _hasAttemptedFocus = true;

  _camera.TakePicture(null, null, this);
}

public void OnPictureTaken(byte[] data, Camera camera)
{
  _busy = _hasAttemptedFocus = false;

  // Do something with the image
}
+2

All Articles