2

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.

xiangjia kong
  • 46
  • 1
  • 8

2 Answers2

2

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);
    }
}
Simon
  • 19,658
  • 27
  • 149
  • 217
1

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.

cprakashagr
  • 751
  • 11
  • 28
  • Thank you for your answer. You helped me solved a problem that I had for a long time and I did not know how to fix. I managed to implement your solution and have elaborated in more detail in my answer above so others can also get help on this pressing issue. – Simon Apr 23 '16 at 14:16
  • Hi Simon, thanks for trying out my implementation. I would update my answer on how to use it. In fact, we don't have to do that long work. – cprakashagr Apr 23 '16 at 18:23
  • OK - if you have enough reputation points, you can edit my answer to make my implementation easier otherwise, if you don't, you can always add onto your answer to help others who visit this thread. – Simon Apr 23 '16 at 18:26
  • I have updated it buddy. I hope that will decrease a lot of time for all. :) Cheers. Let me know if you have any question. – cprakashagr Apr 23 '16 at 18:36
  • Thanks! I don't know about using the minimum buffer size of 5242881. Thats quite large and the buffer size determines how frequently the listener is called. So if I upload a picture under 5mb, the listener will not be called at all and the progress will jump straight to 100% with nothing being displayed inbetween. – Simon Apr 23 '16 at 18:47
  • Yes. I had a talk with cloudinary team. They constantly reply, "It is in our road map". I think, I had this reply for about 7-8 months. So, I though of making a temporary changes in their source from our client side. As you can see that the callback is not triggered from server. It is just the basic calculation and making a fake representation. The server changes, I cannot make. – cprakashagr Apr 23 '16 at 18:50
  • Thanks - can you please tell me where you found the minimium buffer size of 5242881? I wasn't able to find it anywhere on the net. I have started to notice that a low buffer size results in the image upload being incomplete:http://res.cloudinary.com/winghin123/image/upload/v1461495865/preset_folder/57000e6a4de8c74a69d2cf44_1461495860218.jpg – Simon Apr 24 '16 at 12:08
  • I also believe there is a way to measure the file upload directly within the httpurlconnection method so that we can use the progress in the progressbar: http://stackoverflow.com/questions/36826326/android-uploading-a-photo-with-progress-callback-using-httpurlconnection-in-clo – Simon Apr 24 '16 at 17:16
  • I came to know about this from the JSON response from `UploadStrategy.java` line 106. – cprakashagr Apr 25 '16 at 09:10