#android #kotlin
Вопрос:
Я разрабатываю приложение, использующее Android 11 и Kotlin. Я успешно записал файл в папку загрузки на устройстве. При повторной записи в папку с тем же именем файла в результате получается другой файл с тем же именем. Итак, теперь у меня есть два файла с одинаковым именем.
Поэтому сначала я подумал, что просто удалю файл, а затем напишу его снова. Я потратил часы и часы, пытаясь сделать это, но безрезультатно. Код удаления будет выполняться без исключений, но файл никогда не будет удален. Я почти уверен, что установил правильные разрешения, используя
if (!isWriteExternalStoragePermissionGranted()) { val permissions = arrayOf(WRITE_EXTERNAL_STORAGE) for (i in permissions.indices) { requestPermission(permissions[i], i) } } private fun isWriteExternalStoragePermissionGranted(): Boolean { val permissionCheck = ActivityCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) return permissionCheck == PackageManager.PERMISSION_GRANTED }
Затем я подумал, что урежу содержимое файла и просто перепишу содержимое файлов. Это не сработало. Просто повторяйте копию файла снова и снова. Я потратил на это почти целый день. Это действительно не должно быть так сложно. Я перепробовал множество примеров.. ничего не работает. Вот мой код для написания файла…
fun writeToFile(applicationContext: Context, filename: String, data: String) { try { val resolver = applicationContext.contentResolver val values = ContentValues() values.put(MediaStore.MediaColumns.DISPLAY_NAME, filename) values.put(MediaStore.MediaColumns.MIME_TYPE, "text/xml") values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS) val uri = resolver.insert(MediaStore.Files.getContentUri("external"), values) //val cr: ContentResolver = getContentResolver() val os: OutputStream? = uri?.let { resolver.openOutputStream(it,"wt") } if (os != null) { os.write(data.toByteArray()) os.flush() os.close() } /* if (uri != null) { resolver.openFileDescriptor(uri, "wt")?.use { FileOutputStream(it.fileDescriptor).use { it.write(data.toByteArray() ) } } } */ } catch (e: FileNotFoundException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } }
Вот мой код для первого удаления файла, который никогда не работает. Я перепробовал несколько вариантов…
fun deleteFile(context: Context, filename: String, applicationContext: Context){ val myFile = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), filename) if (myFile.exists()) { myFile.delete() } } fun deleteFile(context: Context, filename: String, applicationContext: Context){ val resolver = applicationContext.contentResolver val values = ContentValues() values.put(MediaStore.MediaColumns.DISPLAY_NAME, filename) values.put(MediaStore.MediaColumns.MIME_TYPE, "text/xml") values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS) val uri = resolver.insert(MediaStore.Files.getContentUri("external"), values) if (uri != null) { resolver.delete(uri, null, null) } }
Комментарии:
1. У вас есть доступ только для чтения/записи к файлам
Downloads
, созданным при установке вашего приложения. У вас нет доступа к файламDownloads
из других приложений или предыдущих установок вашего собственного приложения, где приложение было удалено, а затем переустановлено. Итак, возможно, исходныйscanned_bar_codes.xml
файл был создан какой-то предыдущей установкой вашего приложения.2.
the result is another file with the same name.
Это не очень похоже на одно и то же имя файла.3. Первый файл удаления () — это чепуха. Второй тоже, как вы сделали новую вставку() и, следовательно, получили новый uri. Вместо этого вы должны использовать uri, полученный при первой вставке (), в которой вы создали файл.
4. этот второй файл (1) является результатом вставки. Другими словами, функция «создать файл» просто создает 2-й, 3-й файл и так далее. Это похоже на то, как если бы я скопировал и вставил исходный файл в тот же каталог… следите?
5. Я просто хочу это сделать.. Запишите файл в папку Dowload. В какой-то более поздний момент времени запишите файл с тем же именем в папку загрузки. Но..ПРЕЖДЕ чем сделать это, удалите файл, уже находящийся в папке загрузки с тем же именем. Затем запишите файл. Это.. или просто откройте существующий файл в этой папке для загрузки…и просто перепишите содержимое файла новыми данными
Ответ №1:
Вы должны использовать uri, полученный при первой вставке (), в которой вы создали файл.