Upload large Files in Chunks with Okhttp3

wer112

Top Contributor
Konrad hat gesagt, auch wenn er nicht zur Zielgruppe gehört, würde er gerne den Fortschritt sehen und die Dateien in Chunks hochladen.

Deswegen habe ich ChatGPT gefragt, wie man das macht und er gab mir 2 Codes.

Der Erste:

Java:
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;

import java.io.File;
import java.io.IOException;

public class ProgressRequestBody extends RequestBody {

    private final File file;
    private final MediaType contentType;
    private final ProgressListener progressListener;

    // Interface für die Fortschrittsanzeige
    public interface ProgressListener {
        void onProgressUpdate(long bytesWritten, long contentLength);
    }

    public ProgressRequestBody(File file, MediaType contentType, ProgressListener progressListener) {
        this.file = file;
        this.contentType = contentType;
        this.progressListener = progressListener;
    }

    @Override
    public MediaType contentType() {
        return contentType;
    }

    @Override
    public long contentLength() throws IOException {
        return file.length();
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        long fileLength = contentLength();
        byte[] buffer = new byte[4096]; // 4KB Puffer für das Lesen in Chunks
        long bytesWritten = 0;

        try (Source source = Okio.source(file)) {
            long read;
            while ((read = source.read(buffer)) != -1) {
                sink.write(buffer, 0, (int) read);  // Schreibe nur die tatsächlich gelesenen Bytes
                bytesWritten += read;
                progressListener.onProgressUpdate(bytesWritten, fileLength);
            }
        }
    }
}

Dabei wird buffer in while ((read = source.read(buffer)) != -1) rot makiert.

Laut Android Studio:

Code:
while ((read = source.read(buffer)) != -1) {
                                 ^
  required: Buffer,long
  found:    byte[]
  reason: actual and formal argument lists differ in length

Wie bekomme ich das mit den Buffer hin bzw. was muss ich am Code von Chat GPT ändern?

Der zweite Code, der ohne Fehler angezeigt wird:

Java:
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import okhttp3.*;

import java.io.File;
import java.io.IOException;

public class FileUploader {

    private final OkHttpClient client = new OkHttpClient();

    public void uploadFileWithProgress(Context context, String url, File file) {
        ProgressDialog progressDialog = new ProgressDialog(context);
        progressDialog.setMessage("Uploading...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMax(100); // Fortschritt in Prozent (0-100)
        progressDialog.setCancelable(false);
        progressDialog.show();

        // MIME-Typ der Datei
        MediaType mediaType = MediaType.parse("application/octet-stream");  // Passe den Typ an, z.B. "image/jpeg" für Bilder

        // ProgressRequestBody erstellen und ProgressDialog updaten
        ProgressRequestBody requestBody = new ProgressRequestBody(file, mediaType, (bytesWritten, contentLength) -> {
            // Fortschritt im Haupt-Thread aktualisieren
            new Handler(Looper.getMainLooper()).post(() -> {
                int progress = (int) (100 * bytesWritten / contentLength);
                progressDialog.setProgress(progress);
            });
        });

        // Request erstellen
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        // Asynchrone Anfrage senden
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                progressDialog.dismiss();
                System.out.println("Fehler beim Upload: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                progressDialog.dismiss();
                if (response.isSuccessful()) {
                    System.out.println("Upload erfolgreich!");
                } else {
                    System.out.println("Serverfehler: " + response.code());
                }
                response.close();
            }
        });
    }
}

Wie kann ich den ersten Code zum Laufen bekommen?

Ich danke ich jetzt schon mal 👍
 

wer112

Top Contributor
Wie kann ich diese Werte zu diesem Upload hinzufügen:
.addFormDataPart("appname", appname)
.addFormDataPart("dateiname", dateiname)
.addFormDataPart("packagename", packagename)
.addFormDataPart("version", version)
.addFormDataPart("passwort", passwort)
 

Jw456

Top Contributor
Ich habe es hinbekommen, leider stürtzt die App ab, wenn ich im Response if Anwisungen Toast oder AlertDialog versuche.
Einen kleinen Tipp hätte ich.
Wo wirst du sein in der Respons.
Im UI Thread oder doch in einen anderen. (Schaue Doku)
Die Fehler Meldung die du bei Absturz bekommst könnte dir auch helfen.

Du willst eine Ausgabe auf den UI machen ……

Viel Erfolg
 

Ähnliche Java Themen


Oben