java.io.FileNotFoundException ошибка в Apache poi, android

Нужно открыть xlsx файл в Android, использую apache poi, но получаю ошибку "java.io.FileNotFoundException: /file/sdcard/Download/file.xlsx (No such file or directory)"

Делаю так: 1. Через интент открываю пикер

Intent xlsxPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
        xlsxPickerIntent.addCategory(Intent.CATEGORY_OPENABLE);
        xlsxPickerIntent.setType("*/*");
        startActivityForResult(xlsxPickerIntent, REQUEST_CODE.OPENEXTERNAL);
  1. В onActivityResult получаю Uri и вызываю метод

          Uri xlsxFileUri = data.getData();
           importXlsx(xlsxFileUri);
    
  2. Сам метод

    public void importXlsx(Uri uri) {
    try {
            FileInputStream file = new FileInputStream(new File(uri.getEncodedPath()));
            XSSFWorkbook wb = new XSSFWorkbook(file);
    
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
    

В манифесте разрешение на запись/чтение есть, проверка на PERMISSION_GRANTED тоже. Apache poi версия 3.17


Ответы (1 шт):

Автор решения: Barmaley Red Star

В новых версиях Android механизм работы с файловой системой сильно ограничен. Теперь паттерн действий (для вашего случая, когда требуется "открыть" файл) должен быть такой:

1) Через Intent.ACTION_GET_CONTENT вызывается системный пикер файла (вы это и делаете)

2) Получив ссылку на файл, нужно открыть поток чтения из Uri через ContentResolver в виде openInputStream() - этого у вас нет

3) Далее создать файл в частном хранилище new File(context.getFilesDir(), filename);

4) Записать ваш поток (из шага 2) в этот созданный файл

5) И теперь открыть этот файл (созданный в шаге 3 и скопированный в шаге 4) своим POI

Смысл в том, что внешние файлы вам доступны только как InputStream (то есть для чтения), а если нужно открыть файл как нормальный файл, то он должен находиться в частном каталоге приложения в context.getFilesDir()

→ Ссылка