GC cleaning the object before calling onPictureTaken method

170 views Asked by At

I have developed an app that takes photos without previewing them to the user. My problem is that before carrying out the OnPictureTaken method, sometimes the GC cleans the object created by the method Camera.takePicture(). Therefore, when it happens, the App is not able to save that photo.

Here is the class which takes the photos:

public class MyCamera implements Camera.PictureCallback {

private Camera mCamera;
private Context context;

public MyCamera(Context c_) {
    Log.d(TAG, "On constructor");   
    context = c_;

    if (Camera.getNumberOfCameras() >= 2) {
        mCamera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
    } else {
        mCamera = Camera.open(CameraInfo.CAMERA_FACING_BACK);
    }
}

public void takePicture() {
    try {

        Log.d(TAG, "On take picture");  

        mCamera.setPreviewTexture(new SurfaceTexture(0));
        mCamera.startPreview();
        Thread.sleep(1000);
        Log.d(TAG, "About to take");    
        mCamera.takePicture(null, null, null, this);
        Log.d(TAG, "Took it");  

    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
 }

@Override
public void onPictureTaken(byte[] data, Camera camera) {

    Log.d(TAG, "onPictureTaken");       
    File pictureFile = getOutputMediaFile(1);

    if (pictureFile == null) {
        Log.d(TAG, "Error creating picture file");
        return;
    }

    try {
        FileOutputStream fos = new FileOutputStream(pictureFile);
        fos.write(data);
        fos.close();

    } catch (Exception e) {
        Log.d(TAG, "Error writing picture");
        e.printStackTrace();
    }
    finally {
        mCamera.release();

    }
}

I tried either changing the callback to a global variable or using it as an implementation for my class, however none of them have worked smoothly.

Here is the logCat:

06-08 15:46:48.554: D/MyAppService(1248): Capture camera this time
06-08 15:46:48.554: D/MyCamera(1248): On constructor
06-08 15:46:48.844: D/MyCamera(1248): On take picture
06-08 15:46:49.884: D/MyCamera(1248): About to take
06-08 15:46:49.884: D/MyCamera(1248): Took it
06-08 15:46:51.844: D/MyCamera(1248): onPictureTaken
06-08 15:46:51.854: D/DataReceive(1248): handling data
06-08 15:46:51.854: E/DataReceive(1248): Data handled
06-08 15:48:12.144: D/dalvikvm(1248): GC_FOR_ALLOC freed 479K, 3% free 17161K/17676K, paused 41ms, total 42ms
06-08 15:48:48.164: D/dalvikvm(1248): GC_EXPLICIT freed 104K, 3% free 17165K/17676K, paused 9ms+2ms, total 46ms
06-08 15:48:48.604: D/MyAppService(1248): Capture camera this time
06-08 15:48:48.604: D/MyCamera(1248): On constructor
06-08 15:48:48.884: D/MyCamera(1248): On take picture
06-08 15:48:49.914: D/MyCamera(1248): About to take
06-08 15:48:49.914: D/MyCamera(1248): Took it
06-08 15:48:51.884: D/dalvikvm(1248): GC_FOR_ALLOC freed 8K, 3% free 17163K/17676K, paused 16ms, total 16ms
06-08 15:48:52.634: I/dalvikvm-heap(1248): Grow heap (frag case) to 17.046MB for 266152-byte allocation
06-08 15:48:52.644: D/dalvikvm(1248): GC_FOR_ALLOC freed <1K, 3% free 17423K/17936K, paused 10ms, total 10ms
1

There are 1 answers

0
Pedro Henrique On BEST ANSWER

I figured out that problem is my method (takePicture), which was being closed before the onPictureTaken was called. I solved the problem putting a delay into the takePhoto method.