Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload multiple images to server in a queue

Use case: Upload images in a queue in background to the server, images can be web urls or image file stored on the phone's memory.

What I want Limit the number of items in queue to 3 and show blurred images as placeholders for the actual images being uploaded in a recyclerview in an activity with a progress bar on each placeholder indicating how much of it has been uploaded. On top of every placeholder are three buttons to either pause, cancel or resume the upload of the image.

Current Situation: Right now, I was using Multipart in Retrofit 1.9.0 to upload images and this service call was being done inside the activity.

I am not able to figure out how to cancel, pause or resume a multipart-POST request using Retrofit or any other library in general and how to tie a UI event with an api service thread. I can update the UI from service, but how do I update something in the service from an event in UI (pause/resume/cancel)?

How should I proceed with this use case? Do I need to use service? Can I show progress indicators in another activity based on the requests being executed in the service? What should be the architecture for this process? I don't need the code for it, but if there are some useful references related to this, I would like to read and test it out to finally derive my approach.

like image 493
Amit Tiwari Avatar asked Aug 08 '16 07:08

Amit Tiwari


2 Answers

This is how you can do: this is the sample code to upload the Image from device by passing the path of the image..similarly you can do it for Image url, Steps:1) Create a thread which will run for each image. 2) after that each image upload will give you the response. 3) now for each image you can update your UI.

//TODO: Multiple file upload
public class FileUpload implements Runnable {
    Context context;
    String uploadApiUrl, uploadFilePath, fileType;
    int uploadId;
    LocalQueenDataBase localQueenDataBase;
    Activity activity;

    public FileUpload(Context context, ,String uploadApiUrl, String uploadFilePath, String fileType, int uploadId) {
        this.context = context;
        this.uploadApiUrl = uploadApiUrl;
        this.uploadFilePath = uploadFilePath;
        this.fileType = fileType;
        this.uploadId = uploadId;
        localQueenDataBase = new LocalQueenDataBase(context);
        Thread uploader = new Thread(this);
        uploader.start();
    }

    @Override
    public void run() {
        try {
            executeMultipartPost();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void executeMultipartPost() throws Exception {
        try {
            String originalPath = uploadFilePath;
            if (uploadFilePath == null) {
                uploadFilePath = originalPath;
            }
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("your api url");
            httppost.addHeader("put your header if required")
            FileBody bin = new FileBody(new File(uploadFilePath));
            StringBody fileTypeBody = new StringBody(fileType);
            StringBody uploadIdBody = new StringBody(uploadId + "");

            MultipartEntity reqEntity = new MultipartEntity();
            reqEntity.addPart("file", bin);
            reqEntity.addPart("fileType", fileTypeBody);
            reqEntity.addPart("uploadId", uploadIdBody);
            httppost.setEntity(reqEntity);

            HttpResponse response = httpclient.execute(httppost);
            HttpEntity resEntity = response.getEntity();
            String retSrc = EntityUtils.toString(resEntity);//Render your response
            //TODO: update your UI for each uploaded image by creating the Handler
             Message msg = handler.obtainMessage();
             handler.sendMessage(msg);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

final Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        try {
            uploadGalleryRecyclerAdapter = new UploadGalleryRecyclerAdapter(getApplicationContext(), PostUpdateActivity.this, localQueenDataBase.getGallery());
            postUpdateRV.setAdapter(uploadGalleryRecyclerAdapter);
            if (localQueenDataBase.getGallery().size() > 3)
                gallerylayoutManager.scrollToPosition(localQueenDataBase.getGallery().size() - 2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.handleMessage(msg);
    }
};

Hope this will help you.

like image 162
Sanat Chandravanshi Avatar answered Oct 04 '22 18:10

Sanat Chandravanshi


I highly recommend you to use Square's Tape while your uploading multiple files/images at once looking at the ease of use, efficiency,error handling, queuing system. If you are using only one file at time try to use any of multi-part file upload in any android Http clients

This is what Square's Tape:

Tape is a collection of queue-related classes for Android and Java by Square, Inc.

QueueFile is a lightning-fast, transactional, file-based FIFO. Addition and removal from an instance is an O(1) operation and is atomic. Writes are synchronous; data will be written to disk before an operation returns. The underlying file is structured to survive process and even system crashes and if an I/O exception is thrown during a mutating change, the change is aborted.

An ObjectQueue represents an ordering of arbitrary objects which can be backed either by the filesystem (via QueueFile) or in memory only.

TaskQueue is a special object queue which holds Tasks, objects which have a notion of being executed. Instances are managed by an external executor which prepares and executes enqueued tasks.

like image 36
Riyaz Parasara Avatar answered Oct 04 '22 19:10

Riyaz Parasara