Question

I have the following code in an Android activity where I am trying to save an image with a custom file name.

I tried copying code for this from the top answer on this post: Android - Taking photos and saving them with a custom name to a custom destination via Intent

My code is below:

    //camera stuff
    Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

    //folder stuff
    File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
    imagesFolder.mkdirs();
    File image = new File(imagesFolder, "QR_" + timeStamp + ".png");
    Uri uriSavedImage = Uri.fromFile(image);

    imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
    Log.d(LOG_TAG, "writing photo to: " + uriSavedImage.toString());
    startActivityForResult(imageIntent, 1);

When I run this activity, it shows a picture on the screen, I have to tap the touchpad to accept (this is running on Glass), and it prints the following in DDMS:

writing photo to: file:///mnt/sdcard/MyImages/QR_20140106_181934.jpg

However, when I check that directory in the file explorer through DDMS, it is empty. It successfully created the directory MyImages but didn't save any file in that directory.

Instead, it has created the following file with the image I just took: /mnt/sdcard/DCIM/Camera/20140106_181935_635.jpg

So it captures the correct image but just ignores where I told it to save it. Any ideas what I'm doing wrong?

Was it helpful?

Solution

The file may not be completely written when you look at it, so use a FileWatcher like the one in the GDK docs:

private static final int TAKE_PICTURE_REQUEST = 1;

private void takePicture() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, TAKE_PICTURE_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == TAKE_PICTURE_REQUEST && resultCode == RESULT_OK) {
        String picturePath = data.getStringExtra(
                CameraManager.EXTRA_PICTURE_FILE_PATH);
        processPictureWhenReady(picturePath);
    }

    super.onActivityResult(requestCode, resultCode, data);
}

private void processPictureWhenReady(final String picturePath) {
    final File pictureFile = new File(picturePath);

    if (pictureFile.exists()) {
        // The picture is ready; process it.
    } else {
        // The file does not exist yet. Before starting the file observer, you
        // can update your UI to let the user know that the application is
        // waiting for the picture (for example, by displaying the thumbnail
        // image and a progress indicator).

        final File parentDirectory = pictureFile.getParentFile();
        FileObserver observer = new FileObserver(parentDirectory.getPath()) {
            // Protect against additional pending events after CLOSE_WRITE is
            // handled.
            private boolean isFileWritten;

            @Override
            public void onEvent(int event, String path) {
                if (!isFileWritten) {
                    // For safety, make sure that the file that was created in
                    // the directory is actually the one that we're expecting.
                    File affectedFile = new File(parentDirectory, path);
                    isFileWritten = (event == FileObserver.CLOSE_WRITE
                            && affectedFile.equals(pictureFile));

                    if (isFileWritten) {
                        stopWatching();

                        // Now that the file is ready, recursively call
                        // processPictureWhenReady again (on the UI thread).
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                processPictureWhenReady(picturePath);
                            }
                        });
                    }
                }
            }
        };
        observer.startWatching();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top