Andrei
Andrei

Reputation: 44680

Android IMAGE_CAPTURE intent saves photo after onActivityResult

I am trying to take photo using IMAGE_CAPTURE intent and show this photo on the screen immediately. What I do:

File photoFile = createImageFile();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(intent, REQUEST_CAMERA);

Create image file method:

private File createImageFile() {
    File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File photoFile = null;
    try {
        photoFile = File.createTempFile("photo", ".jpg", dir);
        mPhotoPath = photoFile.getAbsolutePath();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return photoFile;
}

When onActivityResult is called I execute:

Bitmap photo = BitmapFactory.decodeFile(mPhotoPath);
mPhoto.setImageBitmap(photo);

Here is a problem. Apparently IMAGE_CAPTURE activity saves image to a file in background and my onActivityResult gets executed before image is saved. Because of this my photo == null. Although it works if I put breakpoint before BitmapFactory.decodeFile call. I fixed it with an ugly hack:

while (photo == null) {
    photo = BitmapFactory.decodeFile(mPhotoPath);
}

So, am I doing something wrong? Why it works this way?

I am testing on Marshmallow Nexus 5.

Upvotes: 1

Views: 381

Answers (1)

CommonsWare
CommonsWare

Reputation: 1007534

Apparently IMAGE_CAPTURE activity saves image to a file in background and my onActivityResult gets executed before image is saved

I would consider that to be a bug in the specific camera app that is handling your request. There are hundreds, if not thousands, of such camera apps, and bugs like this are somewhat common.

I fixed it with an ugly hack

Busy loops like that are never a good idea. Among other things, it will freeze your UI if done in the main application thread, and it will seriously chew up CPU even if done on a background thread.

I would try a FileObserver to watch for when the file is closed, to be more event-driven. If, for whatever reason, you can't get that to work:

  • make sure you are doing your watch-for-the-file logic in a background thread
  • add reasonable SystemClock.sleep() periods between tries (e.g., 50ms)

Upvotes: 1

Related Questions