Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PictureCallback.onPictureTaken never called

Tags:

android

camera

I am writing an application that needs pictures taken with the camera. The problem occurs when I try to take an actual picture. Here's the code that is troubling me:

    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);

On the emulator it seems to work out but on my phone (Motorola Defy - android 2.1).

The actual problem: on the phone the picturecallback is never happening "onPictureTaken" gets never called. The Shuttercallback is executed but the other is not (and I tried with raw instead of jpeg, same thing).

Does anyone know this problem? I just don't see where the difference lies to the emulator right now. I appreciate your help.

like image 899
Yashima Avatar asked Jun 01 '11 11:06

Yashima


2 Answers

I finally went and debugged the problem. All of a sudden it worked, because debugging is much slower: It's a timing problem. The callback takes some time to be called. While debugging the phone had enough time to finish taking the picture ...

Also don't go calling Camera.stopPreview() and Camera.release() too early.

like image 95
Yashima Avatar answered Oct 06 '22 00:10

Yashima


I was having this exact problem. After much debugging I finally realized that the stupid Camera object was getting garbage collected before it had a chance to call the callbacks!

I fixed it by creating a hard reference to the Camera object that I was using. I made it a member of my PictureTaker class, set it before calling takePicture() and then null it out in the jpeg callback after I receive my data. Then I just have to make sure my PictureTaker object won't get gc'd itself, which I do by keeping it around in my Application subclass for the life of the process.

This always works on my 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;
  }
}
like image 30
John Daley Avatar answered Oct 06 '22 01:10

John Daley