[解決済み] Retrofit 2で画像をアップロードする際、プログレスバーを表示させることは可能ですか?
2023-03-23 08:19:37
質問
現在、私は
Retrofit 2
を使用していますが、私のサーバーに写真をアップロードしたいと思っています。
私は、古いバージョンでは
TypedFile
クラスでアップロードすることができます。そして、もしプログレスバーを使いたいのであれば、このクラスで
writeTo
メソッドを
TypedFile
クラスで使用されます。
を使用する場合、進捗状況を表示することは可能ですか?
retrofit 2
ライブラリの使用時に進捗を表示することはできますか?
どのように解決するのですか?
まず、Retrofit 2のバージョンが2.0 beta2以上であることが必要です。
次に、新しいクラスを作成します。
RequestBody
:
public class ProgressRequestBody extends RequestBody {
private File mFile;
private String mPath;
private UploadCallbacks mListener;
private String content_type;
private static final int DEFAULT_BUFFER_SIZE = 2048;
public interface UploadCallbacks {
void onProgressUpdate(int percentage);
void onError();
void onFinish();
}
コンテンツタイプを追加して、画像以外のタイプにも対応できるようにしました。
public ProgressRequestBody(final File file, String content_type, final UploadCallbacks listener) {
this.content_type = content_type;
mFile = file;
mListener = listener;
}
@Override
public MediaType contentType() {
return MediaType.parse(content_type+"/*");
}
@Override
public long contentLength() throws IOException {
return mFile.length();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
long fileLength = mFile.length();
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
FileInputStream in = new FileInputStream(mFile);
long uploaded = 0;
try {
int read;
Handler handler = new Handler(Looper.getMainLooper());
while ((read = in.read(buffer)) != -1) {
// update progress on UI thread
handler.post(new ProgressUpdater(uploaded, fileLength));
uploaded += read;
sink.write(buffer, 0, read);
}
} finally {
in.close();
}
}
private class ProgressUpdater implements Runnable {
private long mUploaded;
private long mTotal;
public ProgressUpdater(long uploaded, long total) {
mUploaded = uploaded;
mTotal = total;
}
@Override
public void run() {
mListener.onProgressUpdate((int)(100 * mUploaded / mTotal));
}
}
}
<ブロッククオート
3つ目は、インターフェイスの作成です。
@Multipart
@POST("/upload")
Call<JsonObject> uploadImage(@Part MultipartBody.Part file);
<ブロッククオート
/* 上記のJsonObjectは独自のモデルで置き換えることができますので、この点だけ注意してください。 ということです。*/
これで、アップロードの進捗を確認することができます。
あなたの
activity
(または
fragment
):
class MyActivity extends AppCompatActivity implements ProgressRequestBody.UploadCallbacks {
ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
progressBar = findViewById(R.id.progressBar);
ProgressRequestBody fileBody = new ProgressRequestBody(file, this);
MultipartBody.Part filePart =
MultipartBody.Part.createFormData("image", file.getName(), fileBody);
Call<JsonObject> request = RetrofitClient.uploadImage(filepart);
request.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if(response.isSuccessful()){
/* Here we can equally assume the file has been downloaded successfully because for some reasons the onFinish method might not be called, I have tested it myself and it really not consistent, but the onProgressUpdate is efficient and we can use that to update our progress on the UIThread, and we can then set our progress to 100% right here because the file already downloaded finish. */
}
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
/* we can also stop our progress update here, although I have not check if the onError is being called when the file could not be downloaded, so I will just use this as a backup plan just in case the onError did not get called. So I can stop the progress right here. */
}
});
}
@Override
public void onProgressUpdate(int percentage) {
// set current progress
progressBar.setProgress(percentage);
}
@Override
public void onError() {
// do something on error
}
@Override
public void onFinish() {
// do something on upload finished,
// for example, start next uploading at a queue
progressBar.setProgress(100);
}
}
関連
-
[解決済み】Android 8:クリアテキストのHTTPトラフィックが許可されない
-
[解決済み] グリッドレイアウトにおけるフリングジェスチャーの検出
-
[解決済み] なぜフラグメントなのか、そしてアクティビティの代わりにフラグメントを使用するのはどんなときか?
-
[解決済み] Retrofit 2.0を使用したPOSTマルチパートフォームデータ(画像付き
-
[解決済み] プログラム的に電話をかけるには?
-
[解決済み] HttpPostによる画像送信
-
[解決済み] バイト配列の画像ファイルをビットマップに変換するには?
-
[解決済み] Androidのadb logcatでTAG名で特定のメッセージを除外する方法は?
-
[解決済み] ProjectScopeServices に Factory タイプのサービスはありません。
-
[解決済み] 文字列リソースにHTML?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] BottomSheetDialogFragmentの状態をexpandedに設定する。
-
[解決済み] AndroidでラジオボタンにOnClickListenerを設定するには?
-
[解決済み] Android Navigation Architecture Component - 現在表示されているフラグメントを取得する
-
[解決済み] AppCompat-v7 21でアクションバー/ツールバーにアイコンを表示する。
-
[解決済み] バイト配列の画像ファイルをビットマップに変換するには?
-
[解決済み] これはどういうことですか?失敗 [INSTALL_FAILED_CONTAINER_ERROR]?
-
[解決済み] Androidアプリケーションのヒープサイズを大きくするには?
-
[解決済み] react nativeアプリのバージョン番号を更新する方法
-
[解決済み] アンドロイドのdatepickerダイアログで最大の日付を設定するには?
-
[解決済み] BottomNavigationViewを新しいNavControllerで使用する際に、フラグメントを生かす方法はありますか?