Hi,
With ODK Collect, every time I capture an image while filling a form,
two copies of the picture are saved: one in the system's default
location for pictures taken with the camera (/sdcard/DCIM/Camera on my
device), plus one in the instance directory.
Eventually, when I delete the saved instance, the copy inside the
instance folder will be deleted with the instance, but the "original"
one will stay there forever until you manually delete it.
I thought this was expected behavior but I don't want the duplicate file
in /sdcard/DCIM. I thought I would change the source code a little bit
so that it would move instead of copying the file, or delete it
after copying. I thought the Camera component (or whatever it is called)
was saving photos into a default location and returning the url, and
that Collect was copying the picture from that url to the instance folder.
However, I had a look at the source code and I found out that ODK
Collect never actually copies the file from a location it doesn't
determine to a location it determines...
Instead, ODK Collect starts an Intent to capture the picture and passes
to this intent the location where to save the image, which is a fixed
temporary file path /sdcard/odk/.cache/temp.jpg. Then, when the intent
returns, it moves the file from this temporary file to the instance
folder (and gives it a unique name). I know it does so as a workaround
to a particular bug in older versions of Android but that's not the
point. (see code below)
So this seems to indicate that the duplication happens outside ODK
before the intent completes and return. That is, when you ask the camera
to capture a photo and save it into a given path, it actually saves two
copies of it, one in the given path and one in its default location
/sdcard/DCIM/Camera.
Is there a way to tell the intent to save the file only into the path
you pass it, and not saving a copy in the default location? (indeed this
is what I would expect it to do when you tell it where you want the file
to be saved). Or is this another Android bug? Or is this impossible by
design (that is, a picture taken via an intent has to be saved in the
default location, even if you are also saving it elsewhere)??
Thanks
m.
From ImageWidget.java:
Intent i = new
Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
Uri.fromFile(new File(Collect.TMPFILE_PATH)));
try {
((Activity) getContext()).startActivityForResult(i,
FormEntryActivity.IMAGE_CAPTURE);
mWaitingForData = true;
} catch (ActivityNotFoundException e) {
Toast.makeText(getContext(),
getContext().getString(R.string.activity_not_found, "image capture"),
Toast.LENGTH_SHORT);
}
From FormEntryActivity.java's onActivityResult:
File fi = new File(Collect.TMPFILE_PATH);
String mInstanceFolder =
mInstancePath.substring(0,
mInstancePath.lastIndexOf("/") + 1);
String s = mInstanceFolder + "/" +
System.currentTimeMillis() + ".jpg";
File nf = new File(s);
if (!fi.renameTo(nf)) {
Log.e(t, "Failed to rename " + fi.getAbsolutePath());
} else {
Log.i(t, "renamed " + fi.getAbsolutePath() + " to "
- nf.getAbsolutePath());
}