Search code examples
androidrx-javarx-android

Uploading multiple image to AWS server using rxJava


I am trying to upload multiple image to ASW using rxJava. I have found a kotlin example.

Upload multiple images(nearly 100) from Android to Amazon S3?.

I tried to implement it using Java. but couldn't find any proper method. can anyone help me with that?

public void processImageFiles(){
        uploadedImageInfo = new ArrayList<>();

        List<Single<Boolean>> uploadList = new ArrayList<>();

         for(File file : selectedImageList){
            String fileExtension = MimeTypeMap.getFileExtensionFromUrl(file.toString());
            String fileName = Calendar.getInstance().getTimeInMillis() + sharedPref.getSharedPrefData(SharedPref.USER_ID) + "." + fileExtension;
            String uploadedFileLink = "https://" + ApiClient.BUCKET_NAME + "." + ApiClient.AWS_END_POINT + "/" + fileName;
            RecordData recordData =  new RecordData();
            recordData.setUrl(uploadedFileLink);
            recordData.setFileType(fileExtension);
            recordData.setFileName(fileName);
            uploadedImageInfo.add(recordData);
            uploadList.add(uploadToAWS(file, recordData));
        }
         

    }


    public Single<Boolean> uploadToAWS(File imageFile, RecordData data) {

        return Single.create(emitter -> {

            AmazonS3 s3Client = new AmazonS3Client(new BasicAWSCredentials(ApiClient.ACCESS_KEY, ApiClient.SECRET_KEY));
            String uploadLink = ApiClient.BUCKET_NAME;
            s3Client.setEndpoint(ApiClient.AWS_END_POINT);
            s3Client.setRegion(Region.getRegion(Regions.US_EAST_1));
            TransferUtility transferUtility = new TransferUtility(s3Client, mContext);
            TransferObserver transferObserver = transferUtility.upload(uploadLink, data.getFileName(), imageFile, CannedAccessControlList.PublicRead);
            mContext.registerReceiver(TransferNetworkLossHandler.getInstance(mContext), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

            transferObserver.setTransferListener(new TransferListener() {

                @Override
                public void onStateChanged(int id, TransferState state) {

                    Log.e("onStateChanged", state.name() + "");
                    if (state.name().equals(TransferState.COMPLETED.name())) {
                        emitter.onSuccess(true);
                    } else {
                        emitter.onError(null);
                    }

                }

                @Override

                public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {

                    //Implement the code to handle the file uploaded progress.
                    Log.e("e", bytesCurrent + "");

                }

                @Override

                public void onError(int id, Exception exception) {
                    emitter.onError(exception);

                }

            });
        });
    }

Solution

  • I've already reply to similar questions for running multiple requests in parallel. you can find them here

    I can suggest you this implementation :

    public final class RecordData {
        private final String url;
        private final String fileType;
        private final String fileName;
    
        public RecordData(String url, String fileType, String fileName) {
            this.url = url;
            this.fileType = fileType;
            this.fileName = fileName;
        }
    
        public String getUrl() {
            return url;
        }
    
        public String getFileType() {
            return fileType;
        }
    
        public String getFileName() {
            return fileName;
        }
    }
    
    public RecordData toRecord(File file) {
        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(file.toString());
        String fileName = Calendar.getInstance().getTimeInMillis() + sharedPref.getSharedPrefData(SharedPref.USER_ID) + "." + fileExtension;
        String uploadedFileLink = "https://" + ApiClient.BUCKET_NAME + "." + ApiClient.AWS_END_POINT + "/" + fileName;
        return new RecordData(uploadedFileLink, fileExtension, fileName);
    }
    
    public void processImageFiles(List<File> selectedImageList) {
        Observable.fromIterable(selectedImageList)
                .flatMapSingle(file -> uploadToAWS(file, toRecord(file)).subscribeOn(Schedulers.io()))
                .subscribe();
    }