首页 > 解决方案 > 使用 Retrofit 上传多个图像时出现 FileNotFoundException

问题描述

我有一个类,它通过 Retrofit 添加带有图像的新闻。当 Retrofit 想要上传图片时,它向我显示了这个错误: FileNotFoundException 我看到了类似的问题和答案,但没有多张图片。所以我找不到我的解决方案并提出这个问题。这是我改造界面的方法:

@POST("News/SaveNews")
    Call<GetResualt> setNewsLetter(@Body NewsLetterModel newsLetter);

    @Multipart
    @POST("Products/Post")
    Call<GetResualt> uploadNewsLetterImage(@Query("ProductID") String newsLetterId,
                                           @Query("CompanyID") String coId,
                                           @Query("UserID") String uID,
                                           @Query("Token") String token,
                                           @Part List<MultipartBody.Part> files);

这是图像选择后我的 onActivityResult:

ActivityResultLauncher<Intent> mLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK) {
                        if (result.getData() != null) {
                            if (result.getData().getClipData() != null) {
                                int count = result.getData().getClipData().getItemCount();
                                int currentItem = 0;
                                while (currentItem < count) {
                                    Uri imageUri = result.getData().getClipData().getItemAt(currentItem).getUri();
                                    imageUriList.add(imageUri);
                                    partNames.add(currentItem + "");
                                    currentItem++;
                                }
                            } else if (result.getData().getData() != null) {
                                imageUriList.add(result.getData().getData());
                            }
                        }


                        NewsLetterModel newsLetter = new NewsLetterModel();
                        newsLetter.setActiveComment(false);
                        newsLetter.setActiveLike(false);
                        newsLetter.setActiveSave(false);
                        newsLetter.setCategory(category);
                        newsLetter.setCompanyId(BaseCodeClass.CompanyID);
                        newsLetter.setCreatorId(BaseCodeClass.userID);
                        newsLetter.setLinkOut("");
                        newsLetter.setLinkToInstagram("");
                        newsLetter.setNewsDescription(description);
                        newsLetter.setNewsTitle(title);
                        newsLetter.setShow(true);
                        newsLetter.setSpare1("#FFFFFF");
                        newsLetter.setSpare2("#FFFFFF");
                        newsLetter.setSpare3("#FFFFFF");
                        newsLetter.setToken(BaseCodeClass.token);
                        newsLetter.setUserId(BaseCodeClass.userID);
                        uploadNewsLetter(newsLetter);

                    }
                }
        );

这是uploadNewsLetter():

private void uploadNewsLetter(NewsLetterModel newsLetter) {
    Retrofit retrofit;
    JsonApi api;
    retrofit = RetrofitInstance.getRetrofit();
    api = retrofit.create(JsonApi.class);
    Call<GetResualt> call = api.setNewsLetter(newsLetter);
    call.enqueue(new Callback<GetResualt>() {
        @Override
        public void onResponse(Call<GetResualt> call, Response<GetResualt> response) {
            if (response.body().getResualt().equals("100")) {
                String newsId = response.body().getMsg();
                List<MultipartBody.Part> files;

                files = convertUriToFIle(partNames, imageUriList);
                uploadNewsImages(newsId, files);

            }
        }

        @Override
        public void onFailure(Call<GetResualt> call, Throwable t) {
            Log.e("Error", t.getMessage());
        }
    });

}

这是 convertUriToFIle()

   private List<MultipartBody.Part> convertUriToFIle(List<String> partNames, List<Uri> imageUriList) {
        List<MultipartBody.Part> files = new ArrayList<>();
        for (int i = 0; i < imageUriList.size(); i++) {
            File file = new File(imageUriList.get(i).getPath());
            RequestBody requestFile = RequestBody.create(MediaType.parse(FileUtils.MIME_TYPE_IMAGE), file);
            files.add(MultipartBody.Part.createFormData(partNames.get(i), file.getName(), requestFile));
        }
        return files;
    }

这是uploadNewsMessage:

private void uploadNewsImages(String newsLetterId, List<MultipartBody.Part> files) {
    Retrofit retrofit;
    JsonApi api;
    retrofit = RetrofitInstance.getRetrofit();
    api = retrofit.create(JsonApi.class);
    Call<GetResualt> call = api.uploadNewsLetterImage(newsLetterId, BaseCodeClass.CompanyID, BaseCodeClass.userID, BaseCodeClass.token, files);
    call.enqueue(new Callback<GetResualt>() {
        @Override
        public void onResponse(Call<GetResualt> call, Response<GetResualt> response) {
            if (response.body().getResualt().equals("100")) {
                Toast.makeText(getContext(), "خبر با موفقیت ثبت شد", Toast.LENGTH_SHORT).show();
            } else {
                Log.e("Error", response.body().getResualt() + " " + response.body().getMsg());
            }
        }

        @Override
        public void onFailure(Call<GetResualt> call, Throwable t) {
            Log.e("Error", t.getMessage());
        }
    });
}

因此,根据我的代码,首先应用程序上传新闻和除图像之外的其他内容,然后上传图像。但是当它想要上传图像时,它会转到改造的 onFailur 并向我显示这个错误:FileNotFoundException。

标签: androidfile-uploadretrofit

解决方案


在 convertUriToFIle() 使用 FileUtils.getFile(context,uri) 而不是new File(imageUriList.get(i).getPath());


推荐阅读