2010-01-12 23 views

Respuesta

41

Lo más probable es que requiera un tamaño de vista previa no válido. Si marca los resultados de adb logcat es probable que vea algo como esto:

E/QualcommCameraHardware(22732): Invalid preview size requested: 480x724 

La solución es solicitar el tamaño de vista previa disponible más cercana a la que se desea; Puede obtener una lista de tamaños de vista previa disponibles llamando al getSupportedPreviewSizes en el objeto Camera.Parameters devuelto por Camera.getParameters.

+0

Tiene usted razón, excepto que estaba tratando de ponerlo a 320x480 y 480x320 hubiera funcionado. Esto me lleva a mi siguiente pregunta, ¿por qué se llamó al método SurfaceHolder.Callback.surfaceChanged() con una resolución tan baja que ni siquiera coincide con la relación de aspecto del dispositivo? –

+2

@Erik B - Me doy cuenta de que esto es MUY tarde para responder a este comentario, pero es probable porque tu aplicación está en modo de compatibilidad, y el sistema trata los píxeles en tu aplicación como 0,66 veces la resolución real del dispositivo. Entonces 480x800 se presentará en su aplicación como 320x533, probablemente afeitando unos pocos píxeles horizontal o verticalmente para la barra de estado a menos que su actividad sea a pantalla completa. –

+0

¿Qué haces antes de la API versión 5? (Digamos que quiero ser compatible con Android 1.5) – uvgroovy

26

corregí esto haciendo lo que dijo Romano, con el código:

Camera.Parameters parameters = camera.getParameters(); 
    List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); 
    Camera.Size cs = sizes.get(0); 
    parameters.setPreviewSize(cs.width, cs.height); 
    camera.setParameters(parameters); 
10

Por lo que vale la pena, la fuente de mi problema terminó siendo que yo estaba tratando de llamar parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); sin verificar primero que los modos de flash fueron compatibles al verificar que parameters.getFlashMode() != null.

Hay más de una causa para esta excepción mal documentada, así que verifique todos sus parámetros y no solo que esté usando un supportedPreviewSize.

+0

Esto me ayudó. :) gracias por compartir –

+1

if (! getBaseContext(). getPackageManager(). hasSystemFeature ( PackageManager.FEATURE_CAMERA_FLASH)) { // flash de la cámara no está disponible en el dispositivo } –

2

Ninguno de los anteriores resolvió esto por mí. Sin embargo, agregar este código antes de establecer los parámetros sí lo hizo.

// stop preview before making changes 
    try { 
     mCamera.stopPreview(); 
    } catch (Exception e){ 
     // ignore: tried to stop a non-existent preview 
    } 

//now set your parameters 
0

Algunas proyecto de cámaras de código abierto como opencamera utilice siempre try-catch llamar Camera.setParameters:

private void setCameraParameters(Camera.Parameters parameters) { 
    if(MyDebug.LOG) 
     Log.d(TAG, "setCameraParameters"); 
    try { 
     camera.setParameters(parameters); 
     if(MyDebug.LOG) 
      Log.d(TAG, "done"); 
    } catch (RuntimeException e) { 
     // just in case something has gone wrong 
     if(MyDebug.LOG) 
      Log.d(TAG, "failed to set parameters"); 
     e.printStackTrace(); 
     count_camera_parameters_exception++; 
    } 
} 

además, siempre obtener la última getParameters antes de llamar setParameters así:

void setRotation(int rotation) { 
    Camera.Parameters parameters = this.getParameters(); 
    parameters.setRotation(rotation); 
    setCameraParameters(parameters); 
} 
0

la solución de Sam es correcta, pero la imagen de salida todavía se amplía un poco en varios dispositivos de tableta. Una de las mejores prácticas que encontré en Internet, debemos configurar el host de la cámara para que las propiedades se reutilicen cada vez que se reanude la cámara. Aquí se implementa el método de CameraHost:

@Override 
     public Parameters adjustPreviewParameters(Parameters parameters) { 
      List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); 
      Camera.Size cs = sizes.get(0); 
      parameters.setPreviewSize(cs.width, cs.height); 
      return super.adjustPreviewParameters(parameters); 
     } 
2

Para mí esto sucedería después de tomar una foto y la vista previa se congelaría, hasta que actualicé mi llamada para los parámetros a ser las siguientes. Siempre es importante con este error asegurarse de verificar todos los parámetros que la cámara está solicitando establecer para asegurarse de que cada parámetro que le pide a la cámara que se establezca es posible para la cámara.

Camera.Parameters parameters = myCamera.getParameters(); 

Con el tamaño de vista previa:

if (myCamera.getParameters().getSupportedPreviewSizes() != null){ 
    Camera.Size previewSize = getOptimalPreviewSize(myCamera.getParameters().getSupportedPreviewSizes(), width, height);; 
    parameters.setPreviewSize(previewSize.width, previewSize.height); 
} 

Con los modos de flash/enfoque:

if(parameters.getSupportedFocusModes() != null && parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){ 
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
} 

if (parameters.getSupportedFlashModes() != null && parameters.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_AUTO)){ 
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 

} 

myCamera.setParameters(parameters); 

etc. Todo esto envuelto en un buen intento {} catch() {} Funciona genial. Buena suerte.

Aquí es el tamaño de getOptimalPreview this great tutorial:

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height) 
    { 
     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     Camera.Size optimalSize = null; 

     final double ASPECT_TOLERANCE = 0.1; 
     double targetRatio = (double) height/width; 

     // Try to find a size match which suits the whole screen minus the menu on the left. 
     for (Camera.Size size : sizes){ 

      if (size.height != width) continue; 
      double ratio = (double) size.width/size.height; 
      if (ratio <= targetRatio + ASPECT_TOLERANCE && ratio >= targetRatio - ASPECT_TOLERANCE){ 
       optimalSize = size; 
      } 
     } 

     // If we cannot find the one that matches the aspect ratio, ignore the requirement. 
     if (optimalSize == null) { 
      // TODO : Backup in case we don't get a size. 
     } 

     return optimalSize; 
    } 
Cuestiones relacionadas