Câu trả lời này là dành cho trang bị thêm 1. Đối với giải pháp tương thích với Retrofit 2 see this answer.
Tôi đã gặp vấn đề tương tự và cuối cùng đã làm được. Tôi đã sử dụng mùa xuân lib trước và những gì tôi hiển thị dưới đây loại làm việc cho mùa xuân nhưng đã không phù hợp kể từ khi tôi đã sai lầm khi sử dụng nó cho InputStream. Tôi đã chuyển tất cả các API của tôi để sử dụng trang bị thêm và tải lên là phiên bản cuối cùng trong danh sách, tôi chỉ ghi đè TypedFile writeTo() để cập nhật cho tôi về các byte được đọc tới OutputStream. Có lẽ điều này có thể được cải thiện nhưng như tôi đã nói tôi đã làm nó khi tôi đang sử dụng mùa xuân vì vậy tôi chỉ tái sử dụng nó. Đây là mã để tải lên và nó hoạt động cho tôi trên ứng dụng của tôi, nếu bạn muốn tải xuống phản hồi thì bạn có thể sử dụng @Streaming và đọc inputStream.
ProgressListener
public interface ProgressListener {
void transferred(long num);
}
CountingTypedFile
public class CountingTypedFile extends TypedFile {
private static final int BUFFER_SIZE = 4096;
private final ProgressListener listener;
public CountingTypedFile(String mimeType, File file, ProgressListener listener) {
super(mimeType, file);
this.listener = listener;
}
@Override public void writeTo(OutputStream out) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
FileInputStream in = new FileInputStream(super.file());
long total = 0;
try {
int read;
while ((read = in.read(buffer)) != -1) {
total += read;
this.listener.transferred(total);
out.write(buffer, 0, read);
}
} finally {
in.close();
}
}
}
MyApiService
public interface MyApiService {
@Multipart
@POST("/files")
ApiResult uploadFile(@Part("file") TypedFile resource, @Query("path") String path);
}
SendFileTask
private class SendFileTask extends AsyncTask<String, Integer, ApiResult> {
private ProgressListener listener;
private String filePath;
private FileType fileType;
public SendFileTask(String filePath, FileType fileType) {
this.filePath = filePath;
this.fileType = fileType;
}
@Override
protected ApiResult doInBackground(String... params) {
File file = new File(filePath);
totalSize = file.length();
Logger.d("Upload FileSize[%d]", totalSize);
listener = new ProgressListener() {
@Override
public void transferred(long num) {
publishProgress((int) ((num/(float) totalSize) * 100));
}
};
String _fileType = FileType.VIDEO.equals(fileType) ? "video/mp4" : (FileType.IMAGE.equals(fileType) ? "image/jpeg" : "*/*");
return MyRestAdapter.getService().uploadFile(new CountingTypedFile(_fileType, file, listener), "/Mobile Uploads");
}
@Override
protected void onProgressUpdate(Integer... values) {
Logger.d(String.format("progress[%d]", values[0]));
//do something with values[0], its the percentage so you can easily do
//progressBar.setProgress(values[0]);
}
}
Các CountingTypedFile chỉ là một bản sao của TypedFile nhưng bao gồm cả ProgressListener.
Nguồn
2014-07-16 04:08:31
Can bạn xây dựng trên trường hợp sử dụng? Hầu hết các yêu cầu Retrofit đơn giản quá ngắn để không cần chỉ báo tiến trình, nhưng tôi đoán bạn đang sử dụng PUT hoặc POST để tải lên một tệp như hình ảnh? – Hober
Chính xác @Hober, bạn có khuyên bạn không nên sử dụng trang bị thêm để tải ảnh lên không? Và nếu có, bạn có đề xuất nào không? –
Tôi đã thực hiện điều này một lúc trước nhưng không thể tìm thấy giải pháp vì vậy tôi đã thực hiện thanh tiến trình không xác định thay thế. – NujnaH