Загрузка изображения с Android на мой сервер (в доступе отказано) - PullRequest
0 голосов
/ 08 февраля 2020

Я пытаюсь загрузить изображение, выбранное из галереи, на мой сервер Springboot, но когда моя служба пытается опубликовать изображение, я получаю разрешение на доступ к пути к файлу. Я добавил эти разрешения в мой AndroidManifest:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- permission below just in case, should not be needed I believe -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

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

Поскольку у меня возникла проблема с разрешением, я также снова запросил разрешение при попытке отправить этот объект отчета, содержащий изображения (Uri).

Но все равно я получаю эту ошибку:

Caused by: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20200206_120434.jpg (Permission denied)

Каждое попадание, которое я найду по этой ошибке в Google, будет указывать на кого-то, кто не запрашивает разрешение в режиме реального времени, но я даже делаю это когда-то многому я верю.

Вот некоторые связанные фрагменты моего кода:

else if (view.getId() == R.id.stubNewBreedingReportSelectImageButt) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
                } else {
                    getPhotoFromPhone(); // this starts the intent to pick an image
                }
            } 
        }

else if (view.getId() == R.id.stubNewBreedingReportSubmitButt) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
                } else {
                    submitNewBreedingReport();
                }
            } 
        }

Это из моего метода onClick (View view). Первый работает, так как мне разрешено выбирать изображение из галереи. Второму, вероятно, не нужно проверять разрешения на основе каждого найденного мною примера проектов, загружающих изображения из android.

В моем методе onActivityResult (int requestCode, int resultCode, Intent data) я раздуваю это msgstr "добавить просмотр деталей изображения". Я также сохраняю выбранный Uri как частный Uri selectedImg в действии для будущего использования. Кажется, все это работает очень хорошо.

Затем, когда я отправляю изображение (в методе submitNewReport ()), я использую ExecutorService (java class), чтобы запустить новый asyn c поток для загрузить. В этом Callable <> я получаю экземпляр Springs RestTemplate и пытаюсь опубликовать изображение, но когда мой restTemplate пытается вызвать и извлечь файл из моего Uri, я получаю отказано в разрешении.

Это метод загрузки в моих приложениях ImageService:

public Gallery uploadPictureWithInfo(Uri uri, Map<String,Object> imgParams, Context context) {
        if (uri.getPath() != null) {
            File resourceFile = new File(getPathFromUri(uri,context));
            //if (resourceFile.exists()) {
                Gallery saved = null;
                Map<String,Object> params = new HashMap<>();
                params.put(PARAM_FILE, new FileSystemResource(resourceFile));
                if (imgParams.get(PARAM_GALLERY_ID) != null || (long) imgParams.get(PARAM_GALLERY_ID) > (long) 0)  {
                    params.put(PARAM_GALLERY_ID, imgParams.get(PARAM_GALLERY_ID));
                    if (imgParams.get(PARAM_DESCRIPTION) != null) {
                        params.put(PARAM_DESCRIPTION, imgParams.get(PARAM_DESCRIPTION));
                    }
                    if (imgParams.get(PARAM_PHOTOGRAPH) != null) {
                        params.put(PARAM_PHOTOGRAPH, imgParams.get(PARAM_PHOTOGRAPH));
                    }
                    if (imgParams.get(PARAM_USER_ID) != null && (long) imgParams.get(PARAM_USER_ID) > 0) {
                        params.put(PARAM_USER_ID, imgParams.get(PARAM_USER_ID));
                    }
                    HttpEntity requestEntity = new HttpEntity<>(params, AquaDbConfig.getImageHeaders());
                    ResponseEntity<Gallery> responseEntity =
                            restTemplate.exchange(AquaDbConfig.getApiUrl() + "/images/uploadImgWithInfo", HttpMethod.POST, requestEntity, Gallery.class);
                    if (responseEntity.hasBody()) {
                        saved = responseEntity.getBody();
                    }
                    return saved;
                }
            //}
        }
        return null;
    }


public static String getPathFromUri(Uri uri, Context context) {
        String[] filePath = { MediaStore.Images.Media.DATA };
        Cursor c = context.getContentResolver().query(uri,filePath, null, null, null);
        c.moveToFirst();
        int columnIndex = c.getColumnIndex(filePath[0]);
        String picturePath = c.getString(columnIndex);
        c.close();
        return picturePath;
    }

Я закомментировал проверку для file.isExist (), чтобы пройти этот тест, поскольку в противном случае он не будет генерировать трассировку стека.

Итак, мой вопрос: КАК я могу прочитать файл изображения, когда я отправлю его на сервер? Я немного читал о классе FileProvider, но мне кажется, что он используется для отправки файлов через Intents новым Activites или другим приложениям. Мне не кажется, что это предназначено для этого, потому что я никогда не оставляю свою активность за исключением выбора изображения в галерее. Различные этапы создания этого объекта ReportedBreeding обрабатываются завышенными ViewStubs, а не новыми активами. Кроме того, используемый мной Uri относится не к каталогам, которые я создал для своего приложения, а к галерее изображений пользователей (внешнее хранилище).

Я также попытался объявить свой ImageService как Сервис в манифесте android. хотя я не уверен, что мы говорим об одном и том же виде услуг. Затем я добавил это разрешение, но оно не делало различий:

        <service
            android:name=".service.MyImageFactory"
            android:permission="android.permission.READ_EXTERNAL_STORAGE">
        </service>

Если вы знаете, как получить разрешение полностью до этого метода POST RestTemplate (который в моих рассмотренных примерах больше никому не нужен) или как мне обойти эту проблему, поделитесь пожалуйста! Я начинаю немного расстраиваться и застревать. Для меня проблема в том, почему android требуется еще одна проверка разрешений и как я могу предоставить ее или обойти ее в моем методе uploadPictureWithInfo (..)?

1 Ответ

0 голосов
/ 10 февраля 2020

Попробуйте запросить разрешение для WRITE_EXTERNAL_STORAGE перед getPhotoFromPhone ()

...