How to show progress while upload file to Cloudina

2019-04-02 01:27发布

问题:

I implemented the uploading function the file to Cloudinary.

Cloudinary cloudinary = new Cloudinary(Constants.CLOUDINARY_URL);
    try {
        FileInputStream is = new FileInputStream(new File(filePath));
        Uploader uploader = cloudinary.uploader();
        Map map = uploader.upload(is, new HashMap());
        return map;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

Now I would like to show the uploading percent in progress bar while upload. But I can't find any callback function to get uploading percent. Please help me. Thanks.

回答1:

cprakashagr answer actually works wonders. Just to elaborate on his answer, you will need to download the latest cloudinary library off github by doing this:

git clone https://github.com/cloudinary/cloudinary_java.git

Then you will have to make the changes according to his link:

https://github.com/cloudinary/cloudinary_java/pull/41

You cannot use Android Studio to make these changes as this is a maven project so you will need to use another IDE, like IntelliJ for example.

This is how I made the changes:

  1. You will need to add on the class: UploadCallback
  2. You will need to replace the class Uploader with his class: https://github.com/cprakashagr/cloudinary_java/blob/master/cloudinary-core/src/main/java/com/cloudinary/Uploader.java

Once you have done this, go into the main folder of your cloudinary_java, and then enter into Terminal. Go and type in mvn install and press enter. You will see that mvn will build the jars for the different folders in your directory. After the build is complete, if you navigate into the cloudinary-core folder for example, you will see the cloudinary-core jar.

You must copy the cloudinary-core jar from the folder and add it into your android project "libs" folder in the root of your android project. Once you have done that and it appears there, right click on the jar in Android Studios and click "Add as Library" so that android studios will add it as a dependency.

The cloudinary-android jar does not need to be added as a jar as you can grab a copy off gradle. Your final gradle file should look something like this:

compile('com.cloudinary:cloudinary-android:1.2.2') {
        exclude module: 'cloudinary-core'
    }
    compile files('/Users/XXX/Documents/myApp/libs/cloudinary-core-1.4.2-SNAPSHOT.jar')

Rebuild your android studio project and you will see that the UploadCallback is now an object you can use in your android project. This is the way you know your jar build was successfully modified.

Now inside a service class, add your code for cloudinary direct upload. You will need to put the code inside a service class because you cannot do network operations on a UI thread and you will get an error if you tried:

    Map config = new HashMap();
    config.put("cloud_name", "XXX");
    Cloudinary mobileCloudinary = new Cloudinary(config);
    Map map = null;
    try {
        map = mobileCloudinary.uploader()
                .uploadLarge(this,
                        intent.getSerializableExtra(getString(R.string.file)),
                        ObjectUtils.asMap("public_id", 123),
                                "tags", "myphoto",
                                "folder", "mylibrary",
                                "unsigned", true,
                                "upload_preset", "XXX"),
                        51200);

    } catch (IOException e) {
        e.printStackTrace();
    }
    String imageUrl = map.get("url").toString();
    Timber.e("imageUrl " + imageUrl);

You must set the buffer to be large enough (but not too large) to make sure your callback is actually called. When I first tried this code out, I set the buffer to something really large, like 200000000, and the callback was not called because the upload would have happened all in one go. If you set it to a small value, like 2048, the callback will be called regularly however, the upload will become really slow. It is up to you to determine an adequate size which will work well for your app. For me it was 51200 which means for every 50kb of the file which is uploaded, a callback will occur.

Once it is working, you will need to transmit the progress information from the service class back to your activity class so you can display the progress on screen. I use a messageHandler to do so. This is the message method in my service class:

public void sendMessage(float progress) {
    Message message = Message.obtain();
    message.arg1 = Math.round(progress);
    try {
        messageHandler.send(message);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

This is my messageHandler on my activity class:

public class MessageHandler extends Handler {
    @Override
    public void handleMessage(final Message message) {
        Timber.e("transfer: " + message.arg1);
    }
}


回答2:

The callback is not implemented from the cloudinary team yet. Though there have been few works around.

Check this link.

You need to import or build new JARs from the cloudinary source. For that, either you use this repository or make required changes to their original repository.

Let me know if you have some questions.

EDIT: On how to use it

Import these two cloudinary sources in your Android project (src/java dir):

  1. Cloudinary Core Lib Source
  2. Cloudinary Android Lib Source

Do changes as per my pull request.

And call the method uploadLarge as per the changed signature. Like:

cloudinary.uploader().uploadLarge(UploadCallback : uploadCallback, File : file, Map : options, int : bufferSize);

For buffer size, please assure you use at least 5242881. This is the limitation from cloudinary server. The minimum packet needs to be 5.001 MB at least.