'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