0

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
kdopen
  • 8,032
  • 7
  • 44
  • 52
  • Why do you think it was your picture's `data` that was freed by GC? – kichik Jun 08 '15 at 21:52
  • Because every time that GC is executed I don't get the message of the log saying that the onPictureTaken is being executed. For example, you can notice that there is a message "D/MyCamera(1248): onPictureTaken" and then the following ones: "06-08 15:46:51.854: D/DataReceive(1248): handling data" and "06-08 15:46:51.854: E/DataReceive(1248): Data handled". when GC is carried out, I don't get these messages. – Pedro Henrique Jun 09 '15 at 02:23
  • Have you considered `takePicture()` is just failing? You are not checking its return value. – kichik Jun 09 '15 at 02:32
  • Maybe it's because you release the camera object at the end of your callback? At any point, there is no reason to assume GC is causing this. It seems like just a side-effect of a failure resulting in internal buffers being freed. – kichik Jun 09 '15 at 04:48
  • Thanks for helping, Kichik. I tried removing the code that releases the camera object, but it didn't work. I am still facing this problem. Each five photos taken, one gets failed when the following messages appear on the LogCat: 06-09 10:52:04.194: D/dalvikvm(9747): GC_FOR_ALLOC freed 8K, 3% free 17140K/17652K, paused 16ms, total 17ms 06-09 10:52:04.194: I/dalvikvm-heap(9747): Grow heap (frag case) to 17.009MB for 250953-byte allocation – Pedro Henrique Jun 09 '15 at 15:58

1 Answers1

0

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.