There have been several posts about this that I have reviewed and I've tried a half a dozen of the proposed solutions. I have something almost identical to this working without throwing an exception in another app I wrote but I'm just not able to get this not to throw an exception, although the file does get transferred! The permission is being set and the file does transmit just fine, but an exception still gets thrown although it does not crash the app.
What I have is this:
fun shareVideo(videoFile: File, context: Context) {
if(videoFile.exists()) {
Timber.i("Video file exists and the length in bytes is: ${videoFile.length()}")
} else {
Timber.w("Video file does not exist. Exiting.")
return
}
val uris = arrayListOf<Uri>()
val uri = FileProvider.getUriForFile(context.applicationContext, context.packageName + ".provider", videoFile)
Timber.i("Uri: $uri + path: ${uri.path}")
uris.add(uri)
val intent = Intent()
intent.action = Intent.ACTION_SEND_MULTIPLE
intent.putExtra(Intent.EXTRA_SUBJECT, "Shared files")
intent.type = "video/mp4"
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
Timber.i("Intent: $intent")
try{
ContextCompat.startActivity(context, Intent.createChooser(intent, "Shared Videos"), null)
} catch (e: Exception) {
Timber.e("Exception starting activity. \nException was ${e.message}\n Stack trace to follow:\n ${e.stackTrace}")
}
}
The stack trace looks like this:
2021-03-07 14:21:59.570 6039-6207/com.company.app E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.company.app.provider/external_files/1615148514218.mp4 from pid=32136, uid=1000 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:820)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:684)
at android.content.ContentProvider$Transport.query(ContentProvider.java:239)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:106)
at android.os.Binder.execTransactInternal(Binder.java:1154)
at android.os.Binder.execTransact(Binder.java:1123)
The Timber log output looks like this:
2021-03-07 14:33:32.713 7396-7396/com.company.app I/StorageUtilsKt: Video file exists and the length in bytes is: 7511455
2021-03-07 14:33:32.719 7396-7396/com.company.app I/StorageUtilsKt: Uri: content://com.company.app.provider/external_files/1615149206171.mp4 + path: /external_files/1615149206171.mp4
2021-03-07 14:33:37.337 7396-7396/com.company.app I/StorageUtilsKt: Intent: Intent { act=android.intent.action.SEND_MULTIPLE typ=video/mp4 flg=0x10000001 (has extras) }
2021-03-07 14:33:38.604 7396-7589/com.company.app E/DatabaseUtils: Writing exception to parcel
So the file is there, and I see it in the attachment that it does add it and I do get it via email/etc. and can view it, but the exception is thrown in the logs.
My provider_paths.xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="cache" path="/"/>
<external-cache-path name="external_cache" path="." />
<external-path name="external" path="." />
<external-files-path name="external_files" path="." />
<files-path name="app_videos" path="." />
</paths>
And my manifest has this in it:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
Everything looks exactly like the app I have that works yet this one throws that exception.
Can anyone see what's wrong with what I am doing?