Reputation: 2914
I want to use FileProvider
to obtain photo from camera. I did everything from this tutorial, but authority
parameter causing error.
Tutorial: https://developer.android.com/reference/androidx/core/content/FileProvider
Provider inside AndroidManifest
:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
provider_paths.xml
:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
UPDATE:
This is create file function:
private fun createImageFile(): File {
val timeStamp = SimpleDateFormat(
"yyyyMMdd_HHmmss",
Locale.getDefault()
).format(Date())
val imageFileName = "IMG_" + timeStamp + "_"
val image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
null /* directory */
)
return image
}
This is provider_paths.xml
(I dont want external path because I dont want from user to accept storage permissions to use camera) :
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name = "name"
path = "path" />
</paths>
This is open camera function:
private fun openCamera() {
val tempFile = createImageFile()
photoUri = Uri.fromFile(tempFile)
photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".fileprovider", tempFile)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
if (intent.resolveActivity(a.packageManager) != null) {
a.startActivityForResult(intent, REQUEST_CAMERA_NODE_MISUSE)
}
}
Error: Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/my.package.name/cache/IMG_20190620_102915_7513574861671405500.jpg
Upvotes: 0
Views: 429
Reputation: 2966
Make sure you put your file provider in the manifest as well inside application
tag
<application
...>
....
<provider
android:authorities = "your_string"
android:name = "androidx.core.content.FileProvider"
android:exported = "false"
android:grantUriPermissions = "true">
<meta-data
android:resource = "@xml/file_path"
android:name = "android.support.FILE_PROVIDER_PATHS" />
</provider>
</application>
And my file_path.xml
is like that
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name = "my_images"
path = "Android/data/com.your.package/files/Pictures" />
</paths>
And from the java code
val authorities = "your_string"
val imageUri = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
FileProvider.getUriForFile(context!!, authorities, imageFile)
else
Uri.fromFile(imageFile)
callCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
startActivityForResult(
callCameraIntent,
CAMERA_REQUEST_CODE
)
Update
your file provider authorities in the manifest and your authorities in your code should match.
Your problem is your authorities
is different in manifest and java code
`android:authorities = "${applicationId}.fileprovider"`
in your java code replace this
photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".provider", tempFile)
to this
photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".fileprovider", tempFile)
Second Update
In this function you are passing to the directory which should not be the case:
private fun createImageFile(): File {
val timeStamp = SimpleDateFormat(
"yyyyMMdd_HHmmss",
Locale.getDefault()
).format(Date())
val imageFileName = "IMG_" + timeStamp + "_"
val image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
null /* directory */
)
return image
}
Try this
private fun createImageFile(): File {
val timeStamp = SimpleDateFormat(
"yyyyMMdd_HHmmss",
Locale.getDefault()
).format(Date())
val imageFileName = "IMG_" + timeStamp + "_"
val image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) //null /* directory */
)
return image
}
Upvotes: 1