'Cannot pass filepath to MediaRecorder in Android 11
I am passing filepath to MediaRecorder for creating video file.
File(filePath).exists()
returns false,
but MediaRecorder fails with IOException,
java.io.FileNotFoundException: /storage/emulated/0/DCIM/XXX/XXX0001.mp4: open failed: EEXIST (File exists)
I have tried creating Uri by getContentResolver().insert()
, but it also gives UNIQUE constraint failed: files._data (code 2067 SQLITE_CONSTRAINT_UNIQUE[2067])
Problem doesn't come in a new phone in which I had never tested my application. Problem starts If I delete video from file Manager.
Solution 1:[1]
Create a temp file and copy whole content in the temp file.
/**
* Create a temp file with the specified format.
* Usage: Image from gallery, Copy file to app directory before upload
*/
@SuppressLint("SimpleDateFormat")
suspend fun createTempFile(fileType: BaseMediaFragment.FileType, extension: String): File? =
withContext(Dispatchers.IO) {
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir: File? =
getApplication<Application>().applicationContext?.getExternalFilesDir(fileType.tempFileDirectory)
if (!storageDir?.exists().isTrue())
storageDir?.mkdirs()
return@withContext File.createTempFile(
"${fileType.tempFilePrefix}_${timeStamp}_", /* prefix */
extension, /* suffix */
storageDir /* directory */
)
}
/**
* Copy the specified input stream to the output file.
*/
private suspend fun copyStreamToFile(inputStream: InputStream, outputFile: File) {
withContext(Dispatchers.IO) {
inputStream.use { input ->
val outputStream = FileOutputStream(outputFile)
outputStream.use { output ->
val buffer = ByteArray(4 * 1024) // buffer size
while (true) {
val byteCount = input.read(buffer)
if (byteCount < 0) break
output.write(buffer, 0, byteCount)
}
output.flush()
}
}
}
```
Solution 2:[2]
You can use this type to set mMediaRecoder
's path:
final ParcelFileDescriptor parcelFileDescriptor = mContext.getContentResolver().
openFileDescriptor(Uri.parse(mVideoProfile.path), "rw");
mMediaRecorder.setOutputFile(parcelFileDescriptor.getFileDescriptor());
mVideoProfile.path = "content://media/external/video/media/751";
Solution 3:[3]
Create directory
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "/XXX");
if (! dir.exists()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM + "/XXX");
getContentResolver().insert(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), values);
} else {
dir.mkdirs();
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | drjansari |
Solution 2 | Antoine |
Solution 3 |