2011-06-01 29 views
12

Estoy escribiendo una aplicación que necesita imágenes tomadas con la cámara. El problema ocurre cuando trato de tomar una foto real. Aquí está el código que me está molestando:PictureCallback.onPictureTaken nunca se llamó

final ShutterCallback shutterCallback = new ShutterCallback() { 
     @Override 
     public void onShutter() { 
      Log.d(TAG, "onShutter"); 
     } 
    }; 

    final PictureCallback callback = new PictureCallback() { 

     @Override 
     public void onPictureTaken(byte[] data, Camera camera) { 
      Log.d(TAG, "onPictureTaken - jpeg"); 
      try { 
       //async task for storing the photo 
       new SavePhotoTask(CameraView.this.ctx, data).execute(); 
      } catch (final SavePhotoException e) { 
       //some exceptionhandling 
      } 
     } 
    }; 
    this.camera = Camera.open(); 
    this.camera.setPreviewDisplay(surfaceHolder); 
    final Camera.Parameters parameters = findBestParameters(w, h); 
    this.camera.setParameters(parameters); 
    this.camera.startPreview(); 
    Log.d(TAG, "takePicture now!"); 
    this.camera.takePicture(shutterCallback, null, callback); 

en el emulador que parece funcionar, pero en mi teléfono (Motorola Defy - Android 2.1).

El problema real: en el teléfono nunca se produce la recuperación de imagen "onPictureTaken" nunca se llama. El Shuttercallback se ejecuta pero el otro no (y lo intenté con raw en lugar de jpeg, lo mismo).

¿Alguien conoce este problema? Simplemente no veo dónde está la diferencia para el emulador en este momento. Aprecio tu ayuda.

Respuesta

15

Finalmente fui y depuré el problema. De repente, funcionó, porque la depuración es mucho más lenta: es un problema de tiempo. La devolución de llamada tarda un tiempo en ser llamada. Durante la depuración, el teléfono tuvo tiempo suficiente para terminar de tomar la foto ...

Además, no llame a Camera.stopPreview() y Camera.release() demasiado pronto.

+0

jesus He perdido tantas horas sin saber cuál era el problema antes de leer esto. ¡Gracias! –

+0

usted probablemente me salvó los días de esfuerzo de depuración – buster

+1

funcionó para mí, stopPreview() fue demasiado pronto – Sudara

10

Estaba teniendo este problema exacto. Después de mucha depuración, finalmente me di cuenta de que el estúpido objeto de la cámara estaba recibiendo basura antes de que tuviera la oportunidad de llamar a las devoluciones de llamada.

Lo arreglé creando una referencia difícil al objeto de la Cámara que estaba usando. Lo hice miembro de mi clase de PictureTaker, lo configuré antes de llamar a takePicture() y luego lo anulé en la devolución de llamada jpeg después de recibir mis datos. Entonces solo tengo que asegurarme de que mi objeto PictureTaker no se obtenga gc'd, lo que hago manteniéndolo en mi subclase de Aplicación durante la vida del proceso.

Esto siempre funciona en mi Droid RAZR:

public class PictureTaker implements Camera.PictureCallback 
{ 
    private Camera mCam; 
    private MyApp theApp; 

    public PictureTaker(MyApp app) 
    { 
    theApp = app; 
    } 

    public void takePicture() 
    { 
    try 
    { 
     mCam = Camera.open(); 
    } 
    catch (Exception e) 
    { 
     System.out.println("Problem opening camera! " + e); 
     return; 
    } 

    if (mCam == null) 
    { 
     System.out.println("Camera is null!"); 
     return; 
    } 

    try 
    { 
     SurfaceView view = MyApp.getPreviewSurface(); // my own fcn 
     mCam.setPreviewDisplay(view.getHolder()); 
     mCam.startPreview(); 
     mCam.takePicture(null, null, this); 
    } 
    catch (Exception e) 
    { 
     System.out.println("Problem taking picture: " + e); 
    } 
    } 

    public void onPictureTaken(byte[] data, Camera cam) 
    { 
    theApp.jpegPictureData(data); // also my own fcn 

    cam.stopPreview(); 
    cam.release(); 

    mCam = null; 
    } 
} 
+0

No he visto esa aplicación en mucho tiempo, pero podría ser que ese era mi problema. Gracias por compartir :) – Yashima

+0

¡El hecho de que gc abandone la cámara cuando solicita una imagen si no mantiene una referencia me hizo reír! –

0

En mi caso no fue llamado a picturetaken en un dispositivo concreto. El problema se debió a que la cámara se estaba abriendo dos veces en onResume() y oncreate().

Cuestiones relacionadas