androidkotlinmediastore

MediaStore creates a new file with instead of overwriting the existing one


I want to write to a file periodically and always replace it if already exists. The problem is that, using MediaStore, instead of overwriting the file, it creates a new one with the same name and appends a number to it

fun exportToFile(fileName: String, content: String) {
    // save to downloads folder
    val contentValues = ContentValues().apply {
        put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
        put(MediaStore.MediaColumns.MIME_TYPE, "text/plain")
        put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
    }

    val extVolumeUri: Uri = MediaStore.Files.getContentUri("external")
    val fileUri = context.contentResolver.insert(extVolumeUri, contentValues)

    // save file
    if (fileUri != null) {
        val os = context.contentResolver.openOutputStream(fileUri, "wt")

        if (os != null) {
            os.write(content.toByteArray())
            os.close()
        }
    }
}

If I call exportToFile("test.txt", "Hello world"), it writes a file test.txt. If I call the same function again, it creates a new one called test(1).txt in the same folder. How do I override this and make it write to the same file?


Solution

  • Thanks to Sam Chen's answer and with some adaptations, this is my Kotlin solution

    fun exportToFile(fileName: String, content: String) {
        val contentValues = ContentValues().apply {
            put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
            put(MediaStore.MediaColumns.MIME_TYPE, "text/plain")
            put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
        }
    
        val extVolumeUri: Uri = MediaStore.Files.getContentUri("external")
    
        // query for the file
        val cursor: Cursor? = context.contentResolver.query(
            extVolumeUri,
            null,
            MediaStore.MediaColumns.DISPLAY_NAME + " = ? AND " + MediaStore.MediaColumns.MIME_TYPE + " = ?",
            arrayOf(fileName, "text/plain"),
            null
        )
    
        var fileUri: Uri? = null
    
        // if file found
        if (cursor != null && cursor.count > 0) {
            // get URI
            while (cursor.moveToNext()) {
                val nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
                if (nameIndex > -1) {
                    val displayName = cursor.getString(nameIndex)
                    if (displayName == fileName) {
                        val idIndex = cursor.getColumnIndex(MediaStore.MediaColumns._ID)
                        if (idIndex > -1) {
                            val id = cursor.getLong(idIndex)
                            fileUri = ContentUris.withAppendedId(extVolumeUri, id)
                        }
                    }
                }
            }
    
            cursor.close()
        } else {
            // insert new file otherwise
            fileUri = context.contentResolver.insert(extVolumeUri, contentValues)
        }
    
        if (fileUri != null) {
            val os = context.contentResolver.openOutputStream(fileUri, "wt")
    
            if (os != null) {
                os.write(content.toByteArray())
                os.close()
            }
        }
    }