如何在Retrofit 2中上传图像文件

Azl*_*mal 39 android retrofit2

我有一个像下面的邮递员的形象.如何在Retrofit 2中做同样的事情.在此输入图像描述

我已经宣布了这样的界面.

@Multipart
@POST("/api/Pharmarcy/UploadImage")
Call<ResponseBody> uploadPrescriptionImage(
        @Query("accessToken") String token,
        @Query("pharmarcyRequestId") int pharmacyRequestedId,
        @Part MultipartBody.Part image);
Run Code Online (Sandbox Code Playgroud)

and*_*ann 88

@Multipart
@POST("user/updateprofile")
Observable<ResponseBody> updateProfile(@Part("user_id") RequestBody id,
                                       @Part("full_name") RequestBody fullName,
                                       @Part MultipartBody.Part image,
                                       @Part("other") RequestBody other);

//pass it like this
File file = new File("/storage/emulated/0/Download/Corrections 6.jpg");
RequestBody requestFile =
        RequestBody.create(MediaType.parse("multipart/form-data"), file);

// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
        MultipartBody.Part.createFormData("image", file.getName(), requestFile);

// add another part within the multipart request
RequestBody fullName = 
        RequestBody.create(MediaType.parse("multipart/form-data"), "Your Name");

service.updateProfile(id, fullName, body, other);
Run Code Online (Sandbox Code Playgroud)

看看我传递multipart和string params的方式.希望对你有帮助!

  • @Ultimo_m 这些是 API 请求参数。 (3认同)

Gil*_*oot 11

对于具有 inputStream 的用户,您可以使用Multipart.

@Multipart
@POST("pictures")
suspend fun uploadPicture(
        @Part part: MultipartBody.Part
): NetworkPicture
Run Code Online (Sandbox Code Playgroud)

然后在您的存储库类中:

suspend fun upload(inputStream: InputStream) {
   val part = MultipartBody.Part.createFormData(
         "pic", "myPic", RequestBody.create(
              MediaType.parse("image/*"),
              inputStream.readBytes()
          )
   )
   uploadPicture(part)
}
Run Code Online (Sandbox Code Playgroud)

如果您的后端不允许多部分,您可以将输入流转换为字节并将字节数组作为请求正文发送,如下所示。

// In your service
 @PUT
 suspend fun s3Upload(
     @Header("Content-Type") mime: String,
     @Url uploadUrl: String, 
     @Body body: RequestBody 
 )
// In your repository
val body = RequestBody.create(MediaType.parse("application/octet"), inputStream.readBytes())
networkService.s3Upload(mime, url, body)
Run Code Online (Sandbox Code Playgroud)

要获得输入流,您可以执行类似的操作。

在您的片段或活动中,您需要创建一个返回InputStream. InputStream 的优点是它可以用于云上的文件,如 google drive 和 dropbox。

pickImagesLauncher.launch("image/*")View.OnClickListener或呼叫onOptionsItemSelected。(请参阅活动结果 API)。

private val pickImagesLauncher =
           registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
                uri?.let {
                    val stream = contentResolver.openInputStream(it)
                    itemViewModel.uploadPicture(stream)
                }
            }

override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)

      btn.setOnClickListener {
         pickImagesLauncher.launch("image/*")
     }
 }

Run Code Online (Sandbox Code Playgroud)

  • @Mohsents我在仅限Compose的应用程序中尝试了registerForActivityResult,但我不能推荐它。你最终会得到一些尴尬的代码。如果您打算开发仅 Compose 的应用程序,请坚持使用 onActivityResult。 (2认同)

小智 8

我完全同意@tir38 和@android_griezmann。这是 Kotlin 中的版本:

interface servicesEndPoint {
@Multipart
@POST("user/updateprofile")
fun updateProfile(@Part("user_id") id:RequestBody, @Part("full_name") fullName:RequestBody, @Part image: MultipartBody.Part, @Part("other") other:RequestBody): Single<UploadPhotoResponse>

companion object {
        val API_BASE_URL = "YOUR_URL"

        fun create(): servicesPhotoEndPoint {
            val retrofit = Retrofit.Builder()
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(API_BASE_URL)
                .build()
            return retrofit.create(servicesPhotoEndPoint::class.java)
        }
    }
}

// Pass it like this
val file = File(RealPathUtils.getRealPathFromURI_API19(context, uri))
val requestFile: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file)

// MultipartBody.Part is used to send also the actual file name
val body: MultipartBody.Part = MultipartBody.Part.createFormData("image", file.name, requestFile)

// Add another part within the multipart request
val fullName: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), "Your Name")

servicesEndPoint.create().updateProfile(id, fullName, body, fullName)
Run Code Online (Sandbox Code Playgroud)

要获取真实路径,请使用 RealPathUtils。在这个问题中检查@Harsh Bhavsar 的答案中的此类:How to get the Full file path from URI

getRealPathFromURI_API19 ,您需要READ_EXTERNAL_STORAGE权限。


Kes*_*era 6

上传图片请参阅此处单击此链接在此输入图像描述

http://mushtaq.16mb.com/retrofit_example/uploads/

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

class AppConfig {

    private static String BASE_URL = "http://mushtaq.16mb.com/";

    static Retrofit getRetrofit() {

        return new Retrofit.Builder()
                .baseUrl(AppConfig.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
}

========================================================
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;

interface ApiConfig {
    @Multipart
    @POST("retrofit_example/upload_image.php")
    Call<ServerResponse> uploadFile(@Part MultipartBody.Part file,
                                    @Part("file") RequestBody name);

    /*@Multipart
    @POST("ImageUpload")
    Call<ServerResponseKeshav> uploadFile(@Part MultipartBody.Part file,
                                    @Part("file") RequestBody name);*/

    @Multipart
    @POST("retrofit_example/upload_multiple_files.php")
    Call<ServerResponse> uploadMulFile(@Part MultipartBody.Part file1,
                                       @Part MultipartBody.Part file2);
}

//https://drive.google.com/open?id=0BzBKpZ4nzNzUMnJfaklVVTJkWEk
Run Code Online (Sandbox Code Playgroud)