Programmable Media

Android image and video upload

Last updated: Dec-15-2024

Cloudinary provides support for uploading media directly from your mobile application to your Cloudinary product environment, without going through your servers first. This method allows for faster uploading and a better user experience. It also reduces load on your servers and reduces the complexity of your applications.

This page covers common usage patterns for Android image and video upload with Cloudinary.

For details on all available upload functionality, see the Upload guide, and the upload method of the Upload API Reference.

For security reasons, mobile applications shouldn't contain your Cloudinary product environment credentials. You can use a signed upload, but that requires generating an authentication signature on your backend. In most cases, you will probably use unsigned uploads that generally provide all the functionality you need for your mobile application, while restricting upload options that require more security.

Help us improve our SDK
We'd love to hear your thoughts on using our Android SDK. Please take a moment to complete this short survey.
Thanks for your time!

MediaManager upload method

The upload request is managed by the MediaManager's upload method, which accepts the file to upload as its only parameter. The file can be specified as either: the path to the local file, a byte array, a Resource ID, or a URI.

The upload request is then dispatched to a background queue via the MediaManager's dispatch method, optionally with a set of fully customizable rules and limits letting you choose when each upload request should actually run and how. Requests are automatically rescheduled to be retried later if a recoverable error is encountered (e.g. network disconnections, timeouts). The upload results are dispatched asynchronously and global callbacks can be defined, as well as specific callbacks per request.

The following simple example uploads an image called imageFile.jpg using the default signed upload options:

Unsigned upload

Unsigned upload is an option for performing upload without the need to generate a signature on your backend. Unsigned upload options are controlled by an upload preset: to use this feature, you first need to enable unsigned uploading for your Cloudinary product environment from the Upload Presets page of your Cloudinary Console Settings.

An upload preset is used to define which upload options will be applied to images that are uploaded unsigned with that preset specified. You can edit the preset at any point in time (or create additional upload presets), to define the parameters that will be used for all images that are uploaded unsigned from your mobile application.

The following simple example uploads an image called imageFile.jpg using an upload preset called sample_preset:

The method returns a requestId that can be used to identify the upload request.

Signed upload

Important

Signed uploads require a signature which needs to be created using your api_secret. You should never expose your secret in client side code and therefore you need to generate an authentication signature on your backend. Android signed upload with backend support should be implemented in conjunction with one of Cloudinary's backend frameworks (Java, .NET, etc). The various backend frameworks implement helpers to be used in conjunction with iOS, as well as automatically generate the authentication signature for the upload.

To implement signed uploads from an Android device to your Cloudinary product environment you must provide a class that implements the SignatureProvider interface. You class must implement a synchronous HTTPS call to your backend signature generation endpoint, which must return an object with a timestamp, your API key, and the signature itself.

To enable signed uploads you need to update your call to the MediaManager's init method with the name of an instance of your class (init(Context, SignatureProvider, Map)). Your class will be implemented whenever an upload must be signed.

For example:

Upload options

Use the MediaManager's option method to add an upload parameter to the upload request. The method accepts 2 parameters: the first specifies the name of the upload parameter and the second its value. For example, to upload an image called samplepic.jpg and set thepublic_id option to sample1:

If you want to include more than one upload parameter in the request you can either chain another option method for each parameter, or use the MediaManager's options method to pass a Map of all parameters. Note that if you use the options method it must come before any other method passing upload parameters.

For example, to upload an image called dog.jpg, set the public_id to my_dog, and add the tag animal:

Which is equivalent to:

Note
For security reasons, only this restricted set of upload options can be specified directly when performing unsigned upload calls. All other upload parameters can only be specified within the upload preset.

Upload response

By default, uploading is performed asynchronously. Once finished, the uploaded image is immediately available for transformation and delivery.

An upload call returns a JSON object with content similar to the following:

The response includes HTTP and HTTPS URLs for accessing the uploaded media asset as well as additional information regarding the uploaded asset: the public ID, resource type, width and height, file format, file size in bytes, a signature for verifying the response, and more.

Chunked upload

The SDK includes the uploadLarge method which offers more tolerance for network issues. This method uploads a large file to the cloud in chunks, and is required for any files that are larger than 100 MB. By default, the chunk size is set to 20 Megabytes but can be set to as low as 5 Megabytes with the chunkSize parameter. For example, uploading a large video file called myVid.mp4 as a raw file and setting the chunk size to 6 Megabytes:

Timeout options

The Android SDK offers 2 extra parameters for overriding the default timeout values when trying to upload a file:

  • connect_timeout - the maximum amount of time in milliseconds to wait for a connection to be established.
  • read_timeout - the maximum amount of time in milliseconds to wait for data available for read.

By default, these timeout values vary between different mobile devices. You can override the default timeout values, and give a single value to all devices, by adding these parameters with the option method.

For example, to upload an image and set both timeouts to 10 seconds:

Callbacks

You can track upload progress by getting callbacks on the following events: onStart, onProgress, onSuccess, onError, and onReschedule. The upload results are dispatched asynchronously, with 2 options for adding callback functionality:

  1. Implement the UploadCallBack interface for specific callbacks per request.
  2. Extend the ListenerService for global callbacks, even when your app has been shut down, or is running in the background.

Implement the UploadCallBack interface

Create a class that implements the UploadCallBack interface, and add functionality by overriding specific callback events with your own code. Use the MediaManager's callback method to add the name of an instance of your class to the upload request. The callback is specific to the current upload request only. The following example includes some example code for the onProgress event:

Extend the ListenerService

Extend the ListnerService service, and add functionality by overriding specific callback events with your own code. Callback events for all upload requests will be routed to your service, even when your app has been shut down, or is running in the background.

The following example includes some example code extending the ListenerService :

Make sure to register your class in the manifest, with both a service tag and a cloudinaryCallbackService meta-data tag, both within the application tag.

For example, if your class is called UploadListner:

Preprocess uploads

Use the preprocess method to make changes to an image before initiating the upload request.

Preprocess image uploads

Image preprocessing is defined by an object of type ImageProcessChain that loads the image with a BitmapDecoder using the specified size, runs predefined processing steps, and then saves the image with a BitmapEncoder using the specified format and quality. The following types of processing steps are currently available:

Step Type Parameter Description
Limit (width, height) Scales down the image to fit within a bounding box of the given dimensions.
DimensionsValidator (min_width, max_width, min_height, max_height) Verifies the minimum and maximum dimensions for the image. Throws an error if the image does not fit within these dimensions.
Crop (point, point) Crops the image as defined by two points that reference the corners of the desired rectangle (any two points that create a diagonal within the image is a valid crop).
BitmapEncoder (format, quality) Saves the image using the given format (JPEG, PNG or WEBP) and quality.

Important
If you include preprocessing in your upload request, you also need to pass an Android context instance when calling the dispatch method.

Examples:

  1. To limit an image to a size of 1000x1000 pixels, make sure that the image is at least 10x10 pixels in size and change the format to WEBP with a quality of 80:

    The limitDimensionsChain shortcut method can be used instead of loading the decoder and adding the limit step separately. For example, the following code accomplishes the same as the example code above:

  2. To crop the image to a rectangle given by the points 250,250 and 750,750:

Note
In the case that you need to create your own preprocessing step you can implement the Preprocess interface with your own custom code and then declare it as an additional addStep.

Preprocess video uploads

Video preprocessing is defined by an object of type VideoProcessChain for preprocessing a video. The following types of processing steps are currently available:

Step Type Parameter Description
Transcode (FrameRate, Width, Height, KeyFramesInterval, TargetAudioBitrateKbps, and TargetVideoBitrateKbps) Transcodes a video according to the given parameters.

Important
If you include preprocessing in your upload request, you also need to pass an Android context instance when calling the dispatch method.

For example, to transcode a video to a frame rate of 30 frames/sec, a size of 1280x720 pixels, a keyframe interval of 3 seconds, an audio bitrate of 128 Kbps, and a video bitrate of 3 Mbps:

Note
In the case that you need to create your own preprocessing step you can implement the Preprocess interface with your own custom code and then declare it as an additional addStep.

Upload policy

Use the policy method to configure the MediaManager's upload request to run under specific circumstances. The policy is defined by an object of type UploadPolicy that has the following properties:

Property Type Description
networkPolicy NetworkType Limit the upload to a specific type of network connection
Possible values:
-UploadPolicy.NetworkType.NONE
-UploadPolicy.NetworkType.ANY(default)
-UploadPolicy.NetworkType.UNMETERED
requiresCharging boolean Upload only when the mobile device is currently charging. Default: false
requiresIdle boolean Upload only when the mobile device is currently idle. Default: false
maxRetries int The maximum number of times to retry the upload. Default: 5
backoffCriteria backoffMillis, backoffPolicy The backoff policy to implement before retrying.
    backoffMillis long The time to wait in milliseconds before retrying. Default: 120000 (2 minutes)
    backoffPolicy BackoffPolicy Whether the time between successive upload attempts increases linearly (2, 4, 6, 8, etc) or exponentially (2, 4, 8, 16, etc)
Possible values:
-UploadPolicy.BackoffPolicy.LINEAR
-UploadPolicy.BackoffPolicy.EXPONENTIAL (default)

For example, to request that a specific upload runs only on an unmetered network (e.g. wifi), with a maximum of 7 retries, and waits 5 minutes before retrying with a linear backoff policy:

Immediate upload

If you need to start an upload immediately with no delay, you can use the startNow method to bypass the managed upload process controlled by the policy method. The startNow method replaces the dispatch method, and you will also need to pass an Android context instance when calling the method.

For example, to start an upload immediately:

Important
Take note of the following considerations before using the startNow method:
  • The upload will run on a background thread instead of the device's background jobs infrastructure.
  • The policy method is ignored and the upload will not benefit from automatic retries and smart scheduling - a failure is a failure.
  • The upload will not count against the total running jobs and will ignore the maximum allowed jobs - 'start now' ignores every other limitation.

Cancel an upload

If you need to cancel an upload in progress, you can use either the cancelRequest method and pass the ID of the request to cancel, or use the cancelAllRequests method to cancel all requests and jobs in progress.

To cancel a single request:

To cancel all requests:

Global policy

To override the default policy for all upload requests, use the setGlobalUploadPolicy method of the MediaManager class. Call the method before using any other methods of the MediaManager class, preferably in Application.onCreate(). The global policy is defined by an object of type GlobalUploadPolicy, which inherits the same properties as the UploadPolicy object described above, with one additional property:

Property Type Description
maxConcurrentRequests int The maximum number of upload requests that can run concurrently. Default: 5

For example, to set the default for upload requests to run only on an unmetered network (e.g. wifi), with no more than 3 upload requests to run concurrently:

Android upload widget

The Android upload widget offers an interactive user interface that enables your users to edit and then upload files to your Cloudinary product environment. The widget, requiring just a couple lines of code to integrate, eliminates the need to develop certain in-house interactive media upload capabilities. Currently, the widget provides an interactive cropping capability and allows rotation of an image before uploading.

You call the upload widget using the startActivity method of the UploadWidget, passing an Android Activity for context (if the method is called from within an activity, this is a valid context), and a request code of your choice.

This will automatically launch the default file picker, allow the user to crop/rotate their images as desired, and also upload the images to Cloudinary via the dispatch queue.

Android upload widget options

If you wish to customize the behavior of the widget, you can add an options object to the method that determines how the images are uploaded. The options object supports 2 parameters as follows:

  • An action specifying how to upload the files, either via the upload queue (DISPATCH), or immediately (START_NOW). You can also specify NONE if you want to intercept the results before uploading.
  • A list of URIs (android resource points), which is typically returned from the default Android file picker or the camera API, or null to let the widget launch the default file picker to select the files to upload.

For example, to call the upload widget with a list of URIs, and dispatch the upload via the queue:

The following example shows how to call the widget with the default file picker, and then upload the files immediately:

Intercepting the edited images

If you specify NONE as action for the upload widget options, you can intercept the results (edited images) from the upload widget by adding code within the calling Activity and overriding the onActivityResult method. Using a static helper method, each result can be directly transformed into an UploadRequest and then customized, if necessary, and dispatched. All the requested edits made by the user, including rotation and cropping, will be automatically added to the request, as preprocessing steps, before uploading to Cloudinary.

For example:

✔️ Feedback sent!

Rate this page: