Last updated: Jan-25-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.
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 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
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:
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:
- Implement the UploadCallBack interface for specific callbacks per request.
- 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. |
context
instance when calling the dispatch
method.Examples:
-
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: -
To crop the image to a rectangle given by the points 250,250 and 750,750:
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. |
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:
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:
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: