【问题标题】:How do I send image to the server using retrofit如何使用改造将图像发送到服务器
【发布时间】:2019-08-30 10:06:32
【问题描述】:

我正在尝试使用改造、multipart/form-data 将图像发送到服务器。但我得到一个错误。

我试过用 Postman 发送图片,没问题。

@Multipart
@POST("requests/11006/history")
fun sendMessageWithImg(
    @Header("X-Device-UDID") deviceUDID: String = "",
    @Header("Authorization") token: String,
    @Part image: MultipartBody.Part
): Call<ResponseBody>


private fun upload(fileUri: Uri) {
    val tokenStorage = TokenStorage(this)
    val token = tokenStorage.getToken()
    val originalFile = FileUtils.getFile(this, fileUri)

    val filePart = RequestBody.create(
        MediaType.parse(contentResolver.getType(fileUri)),
        originalFile)

    val file: MultipartBody.Part = MultipartBody.Part.createFormData("image[]", originalFile.name, filePart)

    val client = ApiService.create()

    val call: Call<ResponseBody> = client
        .sendMessageWithImg(
            token = "Bearer $token",
            image = file)

    call.enqueue(object : Callback<ResponseBody>{

        override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
            print(call)
        }

        override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
            print(response)
        }

    })
}

错误是 - 10000 毫秒后无法从 /fec0::9c04 连接到 .30::681c:587(端口 443)。(端口 38630)

【问题讨论】:

  • 只有图片上传失败吗?你能从你的移动应用访问你的服务器来做其他事情吗?
  • 您仅在此 Web 服务 (Api) 或所有 api 上遇到错误

标签: android retrofit multipartform-data


【解决方案1】:

试试这个代码

@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);

【讨论】:

    【解决方案2】:

    以下是可能发生的情况:

    1- 您的手机无法连接到服务器,因为它没有连接到互联网或与您的服务器相同的网络。确保连接正常。

    2- 手机可以到达服务器,但图像太大,超过了 Http 客户端使用的默认超时时间 10 秒。如果您使用 OkHttp 作为 Retrofit 的 Http 客户端,那么您可以将此超时值更改为更高的值 (Check this link for more info):

    OkHttpClient okHttpClient = new OkHttpClient.Builder()  
            .connectTimeout(1, TimeUnit.MINUTES)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(15, TimeUnit.SECONDS)
            .build();
    
    Retrofit.Builder builder = new Retrofit.Builder()  
            .baseUrl("http://10.0.2.2:3000/")
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create());
    

    3- 问题也可能出在服务器端。如果服务器上设置的图像大小限制低于图像的实际大小,则可能是它失败的原因。

    【讨论】:

      【解决方案3】:
       //add perimissiom in mainfests
         <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
          <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
      
          //interface    
              @Multipart
              @POST("requests/11006/history")
              fun sendMessageWithImg(
                                 @Part("X-Device-UDID") RequestBody deviceUDID,
                                  @Part("Authorization") RequestBody token,
                 @Part List<MultipartBody.Part> file1
              ): Call<ResponseBody>
      
           //below code placed in your Activity java class inside of oncreate
          chooseanimage.setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                          Intent intent = new Intent();
                          intent.setType("image/*");
                          intent.setAction(Intent.ACTION_GET_CONTENT);
                          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                              intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                              // intent.putExtra(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
      
                              Log.i("cameraa", "01");
                          }
                          startActivityForResult(Intent.createChooser(intent, "select"), 0);
                      }
                  });
      
                  if (Build.VERSION.SDK_INT < 23) {
                      //Do not need to check the permission
                  } else {
                      RequestMultiplePermission();
                  }
      
      
      
            upload..setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
      
                      uploadalbum(fileUris);
      });
      
      
      
                 //below code placed in your Activity java class outside of oncreate
                        private void RequestMultiplePermission() {
      
                          // Creating String Array with Permissions.
                          ActivityCompat.requestPermissions(Create_Project.this, new String[]
                                  {
                                          CAMERA,
                                          WRITE_EXTERNAL_STORAGE
                                  }, RequestPermissionCode);
                      }
                       @NonNull
                          private RequestBody createPartFromString(String descriptionString) {
                              return RequestBody.create(
                                      okhttp3.MultipartBody.FORM, descriptionString);
                          }
      
                          @NonNull
                          private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) {
                              // https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
                              // use the FileUtils to get the actual file by uri
                              //   File file = new File(strImgaepath);
                              File file = FileUtils.getFile(this, fileUri);
                              // create RequestBody instance from file
                              RequestBody requestFile =
                                      RequestBody.create(
                                              MediaType.parse(getContentResolver().getType(fileUri)),
                                              file
                                      );
      
                              // MultipartBody.Part is used to send also the actual file name
                              return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
                          }
      
      
             @Override
              protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      
                  if (requestCode == 0 && data != null) {
      
      
                      ClipData clipData = data.getClipData();
      
                      if (data.getClipData() != null) {
                          int count = data.getClipData().getItemCount();
                          int currentItem = 0;
                          while (currentItem < count) {
                              Uri imageUri = data.getClipData().getItemAt(currentItem).getUri();
                              //do something with the image (save it to some directory or whatever you need to do with it here)
                              currentItem = currentItem + 1;
                              Log.d("Uri Selected", imageUri.toString());
                              try {
                                  // Get the file path from the URI
                                  String path = FileUtils.getPath(this, imageUri);
                                  Log.d("Multiple File Selected", path);
      
                                  fileUris.add(imageUri);
                                  //  MyAdapter mAdapter = new MyAdapter(Create_Project.this, arrayList);
                                  // listView.setAdapter(mAdapter);
      
                              } catch (Exception e) {
                                  //   Log.e(TAG, "File select error", e);
                              }
                          }
                      } else if (data.getData() != null) {
                          //do something with the image (save it to some directory or whatever you need to do with it here)
                          final Uri uri = data.getData();
                          Log.i("sara", "Uri = " + uri.toString());
                          try {
                              // Get the file path from the URI
                              final String path = FileUtils.getPath(this, uri);
                              Log.d("Single File Selected", path);
      
                              fileUris.add(uri);
      
                              if (fileUris != null) {
                                  setimage.setVisibility(View.VISIBLE);
                              }
      
                          } catch (Exception e) {
                              Log.e("sara", "File select error", e);
                          }
                      }
                  }
      
      
      
      
      
              }
      
      
          //upolad image
           private void uploadalbum(ArrayList<Uri> fileUris) {
                  pDialog = new ProgressDialog(this);
                  pDialog.show();
                  pDialog.setMessage("Loading");
                  pDialog.setIndeterminate(false);
                  pDialog.setCancelable(false);
                  ApiGetPost service = ApiConstant.getMainUrl(getApplicationContext()).create(ApiGetPost.class);
      
      
                  List<MultipartBody.Part> parts = new ArrayList<>();
                  for (int i = 0; i < fileUris.size(); i++) {
      
                      parts.add(prepareFilePart("file_upload[]", fileUris.get(i)));
                      Log.i("sara", String.valueOf(fileUris.get(i)));
                  }
      
      
                  updateMyProfile = service.upload(createPartFromString(strtitle),
      
                          createPartFromString(""),
                          createPartFromString(""), parts);
      
                  updateMyProfile.enqueue(new Callback<ModelLogin>() {
                      @Override
                      public void onResponse(Call<ModelLogin> call, Response<ModelLogin> response) {
                          pDialog.dismiss();
                          ModelLogin user = response.body();
                          String sa = String.valueOf(user.getStatus());
                          String msg = user.getMessage();
      
                          if (sa.equals("true")) {
                              Toast.makeText(getApplicationContext(), "" + msg, Toast.LENGTH_SHORT).show();
      
      
                          }
      
                      }
      
                      @Override
                      public void onFailure(Call<ModelLogin> call, Throwable t) {
      
                      }
                  });
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-17
        • 2017-04-12
        • 2018-09-21
        • 1970-01-01
        • 2018-10-05
        • 2017-06-30
        • 1970-01-01
        相关资源
        最近更新 更多