Запись файла в папку загрузки (Android 11 SDK 30)

#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, полученный при первой вставке (), в которой вы создали файл.