Android SDK
Install
This guide uses Android SDK 0.2.1 with Java SDK 2.2.4. The Android package is an AAR,
available from Maven Central.
Its POM declares the Java SDK, tus, and WorkManager dependencies, so Gradle and Maven add them for
you.
Gradle:
implementation 'com.transloadit.android.sdk:transloadit-android:0.2.1'
Maven:
<dependency>
<groupId>com.transloadit.android.sdk</groupId>
<artifactId>transloadit-android</artifactId>
<version>0.2.1</version>
<type>aar</type>
</dependency>
Usage
All interactions with the SDK begin with the com.transloadit.android.sdk.AndroidTransloadit class.
Authentication Methods
Keep the Auth Secret on your backend, including for internally distributed apps. APK contents and downloaded configuration cannot keep it confidential. Require Signature Authentication for the Workspace or Template used by the app. The Auth Key can be supplied to the app; the Auth Secret must never be supplied to it.
The key-and-secret constructor is unsuitable for an Android client. Trusted server applications can use the Java SDK with server-held credentials.
Backend Signature Authentication
The SDK calls SignatureProvider.generateSignature synchronously with the exact serialized
params it will send. It adds auth, a fresh nonce, and an expiry five minutes in the future
with the constructor used below. Your backend must validate that expiry against its own clock.
Do not parse and reserialize the string before signing, or reuse a signature for different params.
Before using the helper below, implement its SigningBackend interface using your app’s
authenticated HTTPS client. This interface is an application integration boundary, not an SDK
service. Send the unchanged paramsJson to your own backend and the current user’s session token
in the request’s Authorization header. Use a fixed trusted endpoint, reject redirects, bound the
request timeout, and throw on transport errors or any unsuccessful HTTP response. Return the
backend’s approved params string and signature as SignedParams; never return the Auth Secret.
The backend must authenticate the session and authorize this user’s upload before signing. Allow
only the expected Auth Key, fresh nonce, expiry, and the exact resize Step below; reject additional
Steps, arbitrary Templates, fields, or destinations. Apply your upload limits and quota policy on
the server. For a server-owned Template, disable allow_steps_override and allow only that
Template. Being logged in is not permission to sign arbitrary JSON. Sign the approved original
UTF-8 bytes with HMAC-SHA384 and return a sha384: prefix followed by the 96 hexadecimal digits.
Create an Assembly
Save this complete helper as MobileImageUpload.java. It binds each returned signature to the
SDK’s exact params and refuses missing sessions, mismatched params, and malformed signatures.
The backend still owns authorization; these client checks cannot replace it.
import com.transloadit.android.sdk.AndroidTransloadit;
import com.transloadit.sdk.Assembly;
import com.transloadit.sdk.SignatureProvider;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public final class MobileImageUpload {
private MobileImageUpload() {}
public static final class SignedParams {
public final String params;
public final String signature;
public SignedParams(String params, String signature) {
this.params = params;
this.signature = signature;
}
}
@FunctionalInterface
public interface SigningBackend {
SignedParams approve(String paramsJson, String userSessionToken) throws Exception;
}
public static AndroidTransloadit createClient(
String authKey, String userSessionToken, SigningBackend backend) {
Objects.requireNonNull(backend, "A signing backend is required");
if (userSessionToken == null || userSessionToken.trim().isEmpty()) {
throw new IllegalArgumentException("An authenticated user session is required");
}
SignatureProvider signatures = paramsJson -> {
SignedParams approved = backend.approve(paramsJson, userSessionToken);
if (approved == null || !paramsJson.equals(approved.params)
|| approved.signature == null
|| !approved.signature.matches("sha384:[0-9a-f]{96}")) {
throw new IllegalStateException("Signing was not approved for these parameters");
}
return approved.signature;
};
return new AndroidTransloadit(authKey, signatures);
}
public static void addImage(Assembly assembly, File image) {
assembly.addFile(image, "image");
Map<String, Object> stepOptions = new HashMap<>();
stepOptions.put("width", 75);
stepOptions.put("height", 75);
stepOptions.put("resize_strategy", "pad");
assembly.addStep("resize", "/image/resize", stepOptions);
}
}
Pass your Auth Key, current user session token, and backend implementation to
MobileImageUpload.createClient. The token authenticates your own backend request; it is not a
Transloadit Auth Secret or Transloadit API token. Refresh an expired session before creating a new
client. The SDK constructs auth itself, so the signing callback cannot add auth.max_size or
auth.max_number_of_files. If your policy requires those limits, enforce them in a server-owned
Template or use backend Assembly creation. The number of files added locally is not a server
authorization limit.
Create an AndroidAssembly with client.newAssembly(listener, context), pass it and a readable
local image to MobileImageUpload.addImage, then call assembly.saveAsync(). Supply an
AndroidAssemblyListener implementing onUploadProgress, onUploadFinished,
onAssemblyFinished, onUploadFailed, and onAssemblyStatusUpdateFailed. Upload completion is
separate from processing completion. Check the returned response’s status() and hasError()
as well as handling exceptions; API errors are not always thrown.
Signing performs synchronous work on the caller’s thread. saveAsync() runs Assembly submission
on the SDK’s executor, but direct synchronous SDK calls must run off the UI thread. Listener
callbacks use the main thread by default. Keep the Assembly and listener in a suitable
lifecycle owner, avoid retaining a destroyed Activity, and manage cancellation and background work
in your app. The SDK also supports background uploads through WorkManager, as shown below.
Device and lifecycle behavior need testing in your Android application.
Background uploads with WorkManager
Use AndroidAssemblyWorkConfig to enqueue an AndroidAssemblyUploadWorker through WorkManager.
The worker uses tus and SharedPreferences for resumable uploads. Keep the local file available
until the job finishes.
WorkManager persists the signing headers in its job data. Use an uploadToken issued by your
backend, scoped to this upload, and valid for the job’s scheduled lifetime. If it expires or is rejected,
the worker fails the job; enqueue a new request with fresh credentials. Refreshing the app’s session
does not update credentials in queued jobs.
The worker sends the SDK’s serialized params as the UTF-8 body of an application/json POST.
Configure a fixed HTTPS signing endpoint that responds directly without redirects. Apply the
backend authorization policy above, sign the unchanged request body, and return a JSON object
with a signature field.
Use a server-owned Template containing the approved resize Steps. Your backend must allow that
exact Template and notification URL. The SDK adds auth when the worker submits the Assembly.
Create paramsJson with the approved options:
import androidx.work.WorkManager;
import com.transloadit.android.sdk.AndroidAssemblyWorkConfig;
String paramsJson = "{\"template_id\":\"YOUR_APPROVED_TEMPLATE_ID\","
+ "\"notify_url\":\"https://your-backend.example/transloadit-notify\"}";
AndroidAssemblyWorkConfig config = AndroidAssemblyWorkConfig
.newBuilder(authKey)
.signatureProvider("https://your-backend.example/sign")
.addSignatureProviderHeader("Authorization", "Bearer " + uploadToken)
.paramsJson(paramsJson)
.preferenceName("image_uploads")
.addFile(image, "image")
.waitForCompletion(false)
.build();
WorkManager.getInstance(context).enqueue(config.toWorkRequest());
With waitForCompletion(true), the job waits until the Assembly finishes. The SDK reads the
Assembly’s status URL directly, so your backend only has to sign Assembly creation. With
waitForCompletion(false), as in this example, the job finishes after the upload; track processing
on your backend using Assembly Notifications with an approved notify_url in your params.
Example
The tagged examples illustrate Android integration. Apply the backend signing requirements above to any example you adapt; do not copy app-side secrets from older examples.
Documentation
See the Javadoc for full API documentation.