Android SDK
Installation
Diese Anleitung verwendet das Android SDK 0.2.1 mit dem Java SDK 2.2.4. Das Android-Paket ist ein AAR
und über Maven Central verfügbar.
Sein POM deklariert die Abhängigkeiten zu Java SDK, tus und WorkManager, sodass Gradle und Maven sie
für Sie hinzufügen.
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>
Verwendung
Alle Interaktionen mit dem SDK beginnen mit der Klasse com.transloadit.android.sdk.AndroidTransloadit.
Authentifizierungsmethoden
Bewahren Sie das Auth Secret in Ihrem Backend auf, auch bei intern verteilten Apps. APK-Inhalte und heruntergeladene Konfigurationen können es nicht vertraulich halten. Erzwingen Sie Signature Authentication für den Workspace oder das Template, den bzw. das die App verwendet. Der Auth Key kann der App bereitgestellt werden; das Auth Secret darf ihr niemals bereitgestellt werden.
Der Konstruktor mit Schlüssel und Secret ist für einen Android-Client ungeeignet. Vertrauenswürdige Serveranwendungen können das Java SDK mit serverseitig gespeicherten Zugangsdaten verwenden.
Signature Authentication im Backend
Das SDK ruft SignatureProvider.generateSignature synchron mit dem exakten serialisierten Wert
params auf, den es senden wird. Mit dem unten verwendeten Konstruktor fügt es
auth, einen frischen nonce und einen Ablaufzeitpunkt
fünf Minuten in der Zukunft hinzu. Ihr Backend muss diesen Ablaufzeitpunkt anhand seiner eigenen Uhr
validieren.
Parsen und serialisieren Sie die Zeichenkette vor dem Signieren nicht erneut, und verwenden Sie eine
Signatur nicht für andere Parameter wieder.
Bevor Sie den folgenden Helper verwenden, implementieren Sie die zugehörige Schnittstelle
SigningBackend mit dem authentifizierten HTTPS-Client Ihrer App. Diese Schnittstelle
ist eine Integrationsgrenze Ihrer Anwendung, kein Dienst des SDK. Senden Sie den unveränderten
paramsJson an Ihr eigenes Backend und übermitteln Sie das Session-Token des
aktuellen Nutzers im Header Authorization der Anfrage. Verwenden Sie einen festen,
vertrauenswürdigen Endpunkt, lehnen Sie Weiterleitungen ab, begrenzen Sie das Timeout der Anfrage und
lösen Sie bei Transportfehlern oder jeder nicht erfolgreichen HTTP-Antwort eine Ausnahme aus. Geben
Sie die vom Backend freigegebene Parameter-Zeichenkette und die Signatur als
SignedParams zurück; geben Sie niemals das Auth Secret zurück.
Das Backend muss die Session authentifizieren und den Upload dieses Nutzers autorisieren, bevor es
signiert. Erlauben Sie nur den erwarteten Auth Key, eine neue Nonce, den Ablaufzeitpunkt und genau
den unten gezeigten Step zur Größenänderung; lehnen Sie zusätzliche Steps, beliebige Templates,
Felder oder Ziele ab. Setzen Sie Ihre Upload-Limits und Kontingentrichtlinien auf dem Server durch.
Deaktivieren Sie bei einem serverseitig verwalteten Template allow_steps_override und
erlauben Sie nur dieses Template. Angemeldet zu sein, ist keine Berechtigung, beliebiges JSON zu
signieren. Signieren Sie die freigegebenen ursprünglichen UTF-8-Bytes mit HMAC-SHA384 und geben Sie
das Präfix sha384: gefolgt von den 96 Hexadezimalziffern zurück.
Assembly erstellen
Speichern Sie diesen vollständigen Helper als MobileImageUpload.java. Er bindet jede
zurückgegebene Signatur an die exakten Parameter des SDK und lehnt fehlende Sessions, nicht
übereinstimmende Parameter und fehlerhafte Signaturen ab.
Die Autorisierung bleibt Aufgabe des Backends; diese clientseitigen Prüfungen können sie nicht ersetzen.
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);
}
}
Übergeben Sie Ihren Auth Key, das Session-Token des aktuellen Nutzers und Ihre Backend-Implementierung
an MobileImageUpload.createClient. Das Token authentifiziert die Anfrage an Ihr eigenes Backend; es
ist weder ein Auth Secret von Transloadit noch ein API-Token von Transloadit. Erneuern Sie eine
abgelaufene Session, bevor Sie einen neuen Client erstellen. Das SDK erstellt
auth selbst, daher kann der Signatur-Callback weder auth.max_size
noch auth.max_number_of_files hinzufügen. Wenn Ihre Richtlinie diese Limits erfordert, setzen Sie
sie in einem serverseitig verwalteten Template durch oder erstellen Sie die Assembly im Backend. Die
Anzahl lokal hinzugefügter Dateien ist kein serverseitiges Autorisierungslimit.
Erstellen Sie ein Objekt vom Typ AndroidAssembly mit client.newAssembly(listener, context),
übergeben Sie es zusammen mit einem lesbaren lokalen Bild an MobileImageUpload.addImage und rufen
Sie anschließend assembly.saveAsync() auf. Stellen Sie ein Objekt vom Typ
AndroidAssemblyListener bereit, das onUploadProgress, onUploadFinished,
onAssemblyFinished, onUploadFailed und onAssemblyStatusUpdateFailed implementiert.
Der Abschluss des Uploads ist vom Abschluss der Verarbeitung getrennt. Prüfen Sie in der
zurückgegebenen Antwort status() und hasError() und behandeln
Sie zusätzlich Ausnahmen; API-Fehler werden nicht immer als Ausnahme ausgelöst.
Das Signieren erledigt synchrone Arbeit im Thread des Aufrufers. saveAsync() führt
die Übermittlung der Assembly im Executor des SDK aus, direkte synchrone SDK-Aufrufe müssen jedoch
außerhalb des UI-Threads laufen. Listener-Callbacks verwenden standardmäßig den Hauptthread. Halten
Sie Assembly und Listener in einem geeigneten Lifecycle-Owner, vermeiden Sie es, eine zerstörte
Activity festzuhalten, und verwalten Sie Abbrüche und Hintergrundarbeit in Ihrer App. Das SDK
unterstützt außerdem Hintergrund-Uploads mit WorkManager, wie unten gezeigt.
Das Verhalten auf Geräten und im Lifecycle muss in Ihrer Android-Anwendung getestet werden.
Hintergrund-Uploads mit WorkManager
Verwenden Sie AndroidAssemblyWorkConfig, um AndroidAssemblyUploadWorker über WorkManager
einzureihen.
Der Worker verwendet tus und SharedPreferences für fortsetzbare Uploads. Halten Sie die lokale Datei
verfügbar, bis der Job abgeschlossen ist.
WorkManager speichert die Signatur-Header dauerhaft in seinen Jobdaten. Verwenden Sie einen von Ihrem
Backend ausgestellten uploadToken, der auf diesen Upload beschränkt und für die
geplante Lebensdauer des Jobs gültig ist. Wenn er abläuft oder abgelehnt wird, lässt der Worker den
Job fehlschlagen; reihen Sie dann eine neue Anfrage mit frischen Zugangsdaten ein. Das Erneuern der
Session der App aktualisiert die Zugangsdaten in bereits eingereihten Jobs nicht.
Der Worker sendet die serialisierten Parameter des SDK als UTF-8-Anfragekörper einer POST-Anfrage
vom Typ application/json.
Konfigurieren Sie einen festen HTTPS-Signaturendpunkt, der direkt und ohne Weiterleitungen antwortet.
Wenden Sie die oben beschriebene Autorisierungsrichtlinie des Backends an, signieren Sie den
unveränderten Anfragekörper und geben Sie ein JSON-Objekt mit einem Feld
signature zurück.
Verwenden Sie ein serverseitig verwaltetes Template, das die freigegebenen Steps zur Größenänderung
enthält. Ihr Backend muss genau dieses Template und diese Notification URL zulassen. Das SDK fügt
auth hinzu, wenn der Worker die Assembly übermittelt.
Erstellen Sie paramsJson mit den freigegebenen Optionen:
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());
Mit waitForCompletion(true) wartet der Job, bis die Assembly abgeschlossen ist. Das SDK liest
die Status-URL der Assembly direkt, sodass Ihr Backend nur die Erstellung der Assembly signieren muss.
Mit waitForCompletion(false), wie in diesem Beispiel, ist der Job nach dem Upload abgeschlossen;
verfolgen Sie die Verarbeitung in Ihrem Backend mithilfe von Assembly Notifications mit einem
freigegebenen Wert für notify_url in Ihren Parametern.
Beispiel
Die getaggten Beispiele veranschaulichen die Android-Integration. Wenden Sie die oben genannten Anforderungen an das Signieren im Backend auf jedes Beispiel an, das Sie übernehmen; kopieren Sie keine App-seitigen Secrets aus älteren Beispielen.
Dokumentation
Die vollständige API-Dokumentation finden Sie im Javadoc.