I am kind of stuck on this one and have been working on it for a little while with no luck. I have an android application which allows the user to take photos/videos. The files are stored on external storage using a FileProvider. I have been trying (without luck) to get the videos to show up in the Photos app and have not been able to. The Intent.ACTION_MEDIA_SCANNER_SCAN_FILE and sendBroadcast works perfect for images but does not work on video. I know the videos are being captured, they are being saved in the correct location, and are not corrupted (i can play them in VideoView using FileProvider content Uri) I have not attempted to update this to Android 10 yet as my minimum target is 24 and i cannot seem to get it to work for that.
Creating the Intent.ACTION_MEDIA_SCANNER_SCAN_FILE and sendBroadcast the video does not show up. If i use MediaScannerConnection it does not show up. If i manually insert with the content resolver using the content URI it shows up in Photos but video is not playable and there is no preview. If i manually insert into the content resolver with the absolute path it does not show up at all in Photos Below is the code i use to take the video and add to the MediaStore
File Provider
<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/file_paths" />
</provider>
File Provider Paths
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="Image" path="Image" />
<external-files-path name="Recording" path="Recording"/>
<external-files-path name="Video" path="Video"/>
</paths>
Methods to create the file and call Intent to capture video
private fun takeVideo() {
Intent(MediaStore.ACTION_VIDEO_CAPTURE).also{ videoIntent ->
val videoFile: File? = try{
createVideoFile()
}catch(ex: IOException){
Toast.makeText(mMainActivityHelper.contextProvider(), R.string.error_taking_photo, Toast.LENGTH_SHORT).show()
Log.w("OPENING_VIDEO_FILE", "Error opening video file with message = " + ex.message)
return
}
mFilePath = Uri.parse(videoFile?.absolutePath)
videoFile?.also{
videoIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
mFileUri = FileProvider.getUriForFile(mMainActivityHelper.contextProvider(), "FileProvider", it)
videoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri)
mMainActivityHelper.startActivityForResult(videoIntent, MainActivity.TAKE_VIDEO)
}
}
}
@Throws(IOException::class)
private fun createVideoFile(): File? {
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val externalDir = mMainActivityHelper.externalFilesDirProvider(null)
val imagePath = File(externalDir, "NuNoteVideo")
if(!imagePath.exists())
imagePath.mkdir()
return File(imagePath.path, "MPEG_${timeStamp}" + ".mp4")
}
OnActivityResult code i have tried and none of it has worked. I have tried with both the content URI and the absolute path with no luck
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data)
when{
requestCode == TAKE_VIDEO && resultCode == Activity.RESULT_OK->{
val cv = ContentValues(3).apply {
val absolutePath = myObjectWithThePath.mFilePath.toString()
val name = absolutePath.substring(absolutePath.lastIndexOf("/") + 1)
put(MediaStore.Video.Media.TITLE, name)
put(MediaStore.Video.Media.DISPLAY_NAME, name)
put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
put(MediaStore.Video.Media.DATE_ADDED, Date().time)
put(MediaStore.MediaColumns.DATA, absolutePath)
contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, this)
}
Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { mediaScanIntent ->
val fileUri = myObjectWithThePath.mFileUri
if(fileUri != null) {
val f = File(fileUri)
mediaScanIntent.data = Uri.fromFile(f)
//mediaScanIntent.type = "video/mp4"
sendBroadcast(mediaScanIntent)
}
}
val f = File(myObjectWithThePath.mFilePath.toString())
MediaScannerConnection.scanFile(applicationContext, listOf(f.absolutePath).toTypedArray(), listOf("video/mp4").toTypedArray()){
path, uri ->
print(path)
print(uri) //This shows a URI if i use the absolute path but nothing shows up in the photos app. If i use content uri with FileProvider is null
}
I have looked at many many many anwsers on Stack already and nothing has worked. Any help is greatly appreciated
MediaScanner and ScopedStorage on SDK-29
MediaStore.ACTION_VIDEO_CAPTURE not saving the video in Nougat 7.0
ACTION_MEDIA_SCANNER_SCAN_FILE from external sdcard Lollipop+
Saving photos and videos using Android FileProvider to the gallery
android - save image into gallery
MediaScannerConnection doesn't work
Android How to use MediaScannerConnection scanFile
Android MediaStore insertVideo
Capturing and Saving Videos in Android (API > 24) using File object?