Search code examples
androidretrofit

upload pdf and image files using retrofit


my mobile app uploads pdf files and images files to server. I could upload image files using below code.

API definition

@Multipart
@POST("/api/images/upload")
Call<ImageUploadResponse> uploadImage(@Header("x-auth-token") String authHeader, @Part List<MultipartBody.Part> image);

on select of any image file from storage

if (requestCode == SELECT_FILE){
 if (data.getClipData() != null) {
   List<byte[]> imageDataList = new ArrayList<>();
   int count = data.getClipData().getItemCount();
   for (int i = 0; i < count; i++) {
     try {
        bmp = MediaStore.Images.Media.getBitmap(getActivity().getApplicationContext().getContentResolver(),imageUri);
        bmp.compress(Bitmap.CompressFormat.JPEG, 10, baos);
        imageDataList.add(baos.toByteArray());
      } catch (Exception e) {
       e.printStackTrace();
      }
   }
    uploadImage(imageDataList);
 }

build multi part body part request.

private void uploadImage( List<byte[]> imageDataList) {
              
     MultipartBody.Part[]  parts =  new MultipartBody.Part[imageDataList.size()];
     for (int i = 0; i < imageDataList.size(); i++) {
          RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), imageDataList.get(i));
          String fileName = "image" + i + ".jpg";
          MultipartBody.Part body = MultipartBody.Part.createFormData("image", fileName, requestFile);
          parts[i] = body;
  }
 String token = sessionCache.getToken();
 Call<ImageUploadResponse> call = apiInterface.uploadImage(token,parts);
        
 call.enqueue(new Callback<ImageUploadResponse>() {
      @Override
      public void onResponse(Call<ImageUploadResponse> call, Response<ImageUploadResponse> response) {
            List<String> pdfPaths = response.body().getPdf();
            List<String> imagePaths = response.body().getImg();
            Toast.makeText(getContext(), "image scanned/attached",
                                Toast.LENGTH_LONG).show();
           }
        
     @Override
     public void onFailure(Call<ImageUploadResponse> call, Throwablet) {
        
      }
       });
}

How could I upload a pdf file? I am struggling to get the absolute path of pdf file from URI


Solution

  • openInputStream(uri) to get the InputStream and convert the InputStream to byte array solved the problem for image and pdf. get the mime type from clipData and use the same mime type while constructing RequestBody.

     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
      ..............
      ..............
      if (requestCode == SELECT_FILE) {
        if (data.getClipData() != null) {
            List<byte[]> imageDataList = new ArrayList<>();
            int count = data.getClipData().getItemCount(); 
            String mimeType = data.getClipData().getDescription().getMimeType(0);
            for (int i = 0; i < count; i++) {
               Uri imageUri = data.getClipData().getItemAt(i).getUri();
               imageDataList.add(getBytes(imageUri));
            }
           // pass the byte array list to be uploaded.
           handleAttachment(imageDataList, mimeType);
         }
    }
    
    
    private byte[] getBytes(Uri uri) {
       try {
          InputStream inputStream = getActivity()
                       .getApplicationContext().getContentResolver().openInputStream(uri);
                return readBytes(inputStream);
    
            } catch (Exception ex) {
                LOG.d("could not get byte stream",ex)
            }
            return null;
        }
    
      private byte[] readBytes(InputStream inputStream) throws IOException {
            // this dynamically extends to take the bytes you read
            ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
    
            // this is storage overwritten on each iteration with bytes
            int bufferSize = 1024;
            byte[] buffer = new byte[bufferSize];
    
            // we need to know how may bytes were read to write them to the byteBuffer
            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                byteBuffer.write(buffer, 0, len);
            }
    
            // and then we can return your byte array.
            return byteBuffer.toByteArray();
        }
    
        private void handleAttachment(List<byte[]> imageDataList, String mimeType) {
    
            List<MultipartBody.Part> parts = new ArrayList<>();
            for (int i = 0; i < imageDataList.size(); i++) {
                MultipartBody.Part body = null;
                switch (mimeType) {
                    case MimeTypeConst.imageMimeTypeInRequest:
                        RequestBody requestFile = RequestBody.create(MediaType.parse(MimeTypeConst.imageMimeType),
                                imageDataList.get(i));
                        String fileName = "attachment" + i + ".jpg";
                        body = MultipartBody.Part.createFormData("image", fileName, requestFile);
                        break;
                    case MimeTypeConst.pdfMimeType:
                         requestFile = RequestBody.create(MediaType.parse(MimeTypeConst.pdfMimeType),
                                imageDataList.get(i));
                        fileName = "attachment" + i + ".pdf";
                        body = MultipartBody.Part.createFormData("image", fileName, requestFile);
                        break;
                }
                parts.add(body);
            }
            uploadAttachment(parts);
        }