Копирование файлов в Android из uri в личную папку приложения

avatar
Ziad H.
8 августа 2021 в 21:59
301
1
1

Мое приложение должно взять изображение из галереи и поместить его в каталог данных приложения. Моя реализация заключалась в том, что я попытался поделиться изображением из галереи непосредственно в приложении и использовать его uri, чтобы скопировать его из исходной позиции в каталог приложения Android.

После получения URI изображения:

copyFile(new File(mImageUri.getPath()), getFilesDir());

Метод copyFile:

public void copy(File src, File dst) throws IOException {
         try (InputStream in = new FileInputStream(src)) {
             try (OutputStream out = new FileOutputStream(dst)) {
                 // Transfer bytes from in to out
                 byte[] buf = new byte[1024];
                 int len;
                 while ((len = in.read(buf)) > 0) {
                     out.write(buf, 0, len);
                 }
             }
         }
     }

Проблема в том, что я получаю исключение FileNotFound, как мне это исправить?

Источник
CommonsWare
8 августа 2021 в 22:05
1

Uri не является файлом. Используйте ContentResolver и openInputStream(), чтобы получить InputStream для содержимого, указанного вашим Uri.

Ziad H.
11 августа 2021 в 01:35
0

Я заменил файл inputStream на этот InputStream in = getContentResolver().openInputStream(src), но он все равно не работает. @CommonsWare

Ответы (1)

avatar
Oleg Ukhanyov
9 ноября 2021 в 10:14
1

Во-первых, используйте этот файл:

private fun openFile() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        addCategory(Intent.CATEGORY_OPENABLE)
        type = "application/pdf"
    }

    fileRequest.launch(intent)
}

fileRequest :

    private val fileRequest =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { resultData ->
        resultData?.data?.also { data ->
            val myFile = File(
                requireContext().filesDir,
                "test_file.pdf"
            ) // filesDir - Your app's ordinary, persistent files reside directory
            val inputStream: InputStream =
                requireActivity().contentResolver.openInputStream(data.data!!)!!
            val outputStream: OutputStream = FileOutputStream(myFile)
            val buf = ByteArray(1024)
            var len: Int
            while (inputStream.read(buf).also { len = it } > 0) {
                outputStream.write(buf, 0, len)
            }
            outputStream.close()
            inputStream.close()
        }
    }

Измените строку type = "application/pdf", чтобы указать, какие файлы вы хотите скопировать

Кроме того, fileRequest объявлен в области фрагмента (если вам это не нравится, старый "startActivityForResult", он будет работать нормально.

Кроме того, openInputStream(data.data!!), data.data!! — это uri выбранного файла