I've followed this Google tutorial to start an intent to capture an image with new Intent(MediaStore.ACTION_IMAGE_CAPTURE)
. The tutorial recommends using the public directory with getExternalStoragePublicDirectory
which would work great for my app. But then their example instead uses getExternalFilesDir
. Then to pass the URI of the file to the intent with MediaStore.EXTRA_OUTPUT
I have to get a content URI because I'd like to target Android N. Before targeting N I would just pass a file:// URI and everyone but Google was happy. Now on N I started getting the FileUriExposedException
that seems to be not very favorable.
So given that I have a File like this...
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyAppFolder");
if (!storageDir.exists() && !storageDir.mkdir())
Log.w(TAG, "Couldn't create photo folder: " + storageDir.getAbsolutePath());
File image = new File(storageDir, timeStamp + ".jpg");
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
...can I use a built-in provider for the public pictures directory to get a content URI? If so how?
I've tried something like
takePictureIntent.putExtra(
MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(this, MediaStore.AUTHORITY, createImageFile()));
but it just throws
IllegalArgumentException: Missing android.support.FILE_PROVIDER_PATHS meta-data
Is that Authority correct? If I must use my own provider to share the public file then what path can I specify in my FILE_PROVIDER_PATHS meta-data? All of the options I can find are for private directories.
MediaStore
. "If I must use my own provider to share the public file then what path can I specify in my FILE_PROVIDER_PATHS meta-data?" --<external-path>
gives you the root of external storage. There is no way withFileProvider
to specify the directory that you are trying to use specifically. – Typhoeus<external-path>
would be risky. "then are my only options to use a private directory or stop targeting N?" -- no. You can write your ownContentProvider
. Or, you can write a plugin for myStreamProvider
. Or you can use a custom directory on external storage, one that you control its path from the external storage root directory (though this may be what you meant by "private directory"). – TyphoeusFileProvider
. Then inonActivityResult
I can copy the file to its final resting place in the external storage public directory. The custom and third-party ContentProviders seem a bit heavy for the job. – Misstate