【问题标题】:How to upload an image to a server using http request in kotlin?如何在 kotlin 中使用 http 请求将图像上传到服务器?
【发布时间】:2019-12-20 17:56:11
【问题描述】:

我已经编写了使用kotlin将图像上传到服务器的代码,即用户通过相机拍照然后当用户单击发送按钮时将图像显示在imageView中,我希望ImageView中的图像是发送到服务器,但我不知道如何将 ImageView 中的图像更改为可以发送到服务器的文件。

我设计了代码来捕获图像并在图像视图中设置图像以预览它,但不知道使用 http 请求将其上传到服务器。

用于打开相机并将图像设置为图像视图:

private fun openCamera(){

    val values = ContentValues()

    values.put(MediaStore.Images.Media.TITLE, "New Picture")

    values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera")

    private fun openCamera() {
    val values = ContentValues()
    values.put(MediaStore.Images.Media.TITLE, "New Picture")
    values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera")
    image_uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)

    val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri)
    startActivityForResult(cameraIntent, IMAGE_CAPTURE_CODE)
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {

    when (requestCode) {
        PERMISSION_CODE_CAM -> {
            if (grantResults.size!! > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openCamera()
            } else {
                Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    if (resultCode == Activity.RESULT_OK && resultCode == IMAGE_CAPTURE_CODE) {
        imageView.setImageURI(image_uri)
    }

}

我想使用 http 请求将图像上传到服务器,我在 java 中得到了很多代码,但在 kotlin 中没有。我不知道在 kotlin 中上传。

【问题讨论】:

  • 使用改造库的最简单方法,它是多部分发布请求。 square.github.io/retrofit
  • 我尝试过改造,但每次点击上传按钮时应用都会崩溃。

标签: android kotlin httprequest retrofit image-uploading


【解决方案1】:

因为这个问题仍然悬而未决。我们可以使用非常易于使用的 OKHTTP 库,并且我们必须编写非常少的代码。这里我写了一篇关于这个话题的详细文章

Upload Image or File to Server in Android Kotlin

我不会再复制相同的代码,我已经写了一个 UploadUtility 类。只需从上面的链接将其复制到您的项目中,剩下的就交给它了。

【讨论】:

    【解决方案2】:

    API接口

    @Multipart
    @POST("your_url")
    suspend fun uploadImage(
        @Part file:MultipartBody.Part
    ): Response<String>
    

    Kotlin 代码

            val file: File = ImagePicker.getFile(data)!!
    
    
            val requestFile =RequestBody.create("multipart/form-data".toMediaTypeOrNull(),file)
            val requestFile=RequestBody.create(MediaType.parse("image/*"),file)
            val body = MultipartBody.Part.createFormData("profile_picture", file.name, requestFile)
            uploadImage(body)
    

    【讨论】:

      【解决方案3】:

      这是使用 kotlin 改造代码 100% 工作的图像上传

       private fun UploedImage(User_id:String , newfile: File) {
              Commons.showProgressDialog(this@StoreDetailActivity)
      
             
              //creating a file
              var requestFile: RequestBody? = null
              var document: MultipartBody.Part
              var ImageUloloadgetCall: Call<ImageUloloadgetUrlModel?>? = null
              if (newfile != null) {
                  val MEDIA_TYPE_IMAGE = "image/*".toMediaTypeOrNull()
      
                  requestFile = create(MEDIA_TYPE_IMAGE, newfile)
      
      
                  document = createFormData(
                      "image",
                      newfile.getName(),
                      requestFile
                  )
      
                  val userId= create("text/plain".toMediaTypeOrNull(), User_id)
      
                  ImageUloloadgetCall = getApiInstance().ImageUpload(
                      alldata,
                      document
                  )
              }
              ImageUloloadgetCall!!.enqueue(object : Callback<ImageUloloadgetUrlModel?> {
                  override fun onResponse(
                      call: Call<ImageUloloadgetUrlModel?>,
                      response: Response<ImageUloloadgetUrlModel?>
                  ) {
                      dismissProgressDialog()
                      if (!response.isSuccessful()) {
                          Log.d(
                              TAG,
                              "onResponse: fail " + response.code()
                          )
                          Toast.makeText(
                              this@StoreDetailActivity,
                              "" + response.message(),
                              Toast.LENGTH_SHORT
                          ).show()
                          return
                      }
                      Log.d(
                          TAG,
                          "onResponse: success" + response.code() + response.body()
                      )
                      if (response.body() != null) {
                          var imageUloloadgetUrlModel: ImageUloloadgetUrlModel? = null
                          try {
                              imageUloloadgetUrlModel = response.body()
      
      
      
                               
                          } catch (e: Exception) {
                              Toast.makeText(
                                  this@StoreDetailActivity,
                                  "Error in response",
                                  Toast.LENGTH_SHORT
                              ).show()
                              return
                          }
                      } else {
                          Toast.makeText(
                              this@StoreDetailActivity,
                              "Invalid response from server",
                              Toast.LENGTH_SHORT
                          ).show()
                      }
                  }
      
                  override fun onFailure(call: Call<ImageUloloadgetUrlModel?>, t: Throwable) {
                      dismissProgressDialog()
                  }
              })
          }
      

      【讨论】:

        【解决方案4】:

        您可以使用这些函数通过相机捕捉图像:

        public static Uri getTakenPictureUri(Context mContext, Intent data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};
        
            Cursor cursor = mContext.getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();
        
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();
        
            picturePath = "file://" + picturePath;
            LogHelper.trace("Selected file uri:" + picturePath);
        
            return Uri.parse(picturePath);
        }
        
        public static File createImageFile() throws IOException {
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            String imageFileName = "JPEG_" + timeStamp + "_";
            File storageDir = MyPharmacy.getmInstance().getExternalCacheDir();
            LogHelper.trace("createImageFile:" + storageDir.getAbsolutePath());
            File image = File.createTempFile(
                    imageFileName,
                    ".jpg",
                    storageDir
            );
            return image;
        }
        
        public static File openCamera(Activity mActivity, int requestCode) {
            Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            try {
                File photoFile = createImageFile();
                if (photoFile != null) {
                    Uri photoURI = FileProvider.getUriForFile(MyPharmacy.getmInstance(), BuildConfig.APPLICATION_ID + ".provider", photoFile);
                    camera.putExtra(MediaStore.EXTRA_OUTPUT,
                            photoURI);
                    if (camera.resolveActivity(mActivity.getPackageManager()) != null) {
                        mActivity.startActivityForResult(camera, requestCode);
                        return photoFile;
                    }
                }
            } catch (IOException ex) {
            }
            return null;
        }
        
        public static File openCamera(Fragment fragment, int requestCode) {
            Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            try {
                File photoFile = createImageFile();
                if (photoFile != null) {
                    Uri photoURI = FileProvider.getUriForFile(MyPharmacy.getmInstance(), BuildConfig.APPLICATION_ID + ".provider", photoFile);
                    camera.putExtra(MediaStore.EXTRA_OUTPUT,
                            photoURI);
                    if (camera.resolveActivity(fragment.getActivity().getPackageManager()) != null) {
                        fragment.startActivityForResult(camera, requestCode);
                        return photoFile;
                    }
                }
            } catch (IOException ex) {
            }
            return null;
        }
        

        然后使用下面的代码通过改造上传它

        public static void uploadImage(final String filePath,
                                                   final String token,
                                                   final APIResponseCallback<UploadResponse> cb) {
            if (filePath != null && !filePath.isEmpty()) {
                final File file = new File(filePath);
                if (file.exists()) {
        
                    Glide.with(App.getmInstance().getContext()).load(file).asBitmap().override(700, 700).into(new SimpleTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
                            OutputStream os = null;
                            try {
                                String realPath = StorageHelper.getRealPathFromUri(App.getmInstance().getContext(), Uri.fromFile(file));
                                os = new BufferedOutputStream(new FileOutputStream(file));
                                bitmap.compress(Bitmap.CompressFormat.JPEG, 80, os);
                                os.flush();
                                os.close();
                            } catch (java.io.IOException e) {
                                e.printStackTrace();
                            }
        
        
                            if (file != null) {
                                // creates RequestBody instance from file
                                RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
                                // MultipartBody.Part is used to send also the actual filename
                                MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
                                // adds another part within the multipart request
                                String descriptionString = "Image";
                                RequestBody description = RequestBody.create(okhttp3.MultipartBody.FORM, descriptionString);
                                // executes the request
                                ServiceGenerator.getAPIServices().uploadImage(body, description, token).enqueue(new Callback<UploadResponse>() {
                                    @Override
                                    public void onResponse(Call<UploadResponse> call, Response<UploadResponse> response) {
                                        if (response.isSuccessful()) {
                                            cb.onSuccess(response.body());
                                        } else {
                                            checkError(response, token);
                                        }
                                    }
        
                                    @Override
                                    public void onFailure(Call<UploadResponse> call, Throwable t) {
                                        cb.onError(t);
                                    }
                                });
                            }
                        }
                    });
                }
            }
        }
        

        API接口是:

        @Multipart
        @POST("Uploads/image/upload")
        Call<UploadResponse> uploadImage(@Part MultipartBody.Part file,
                                                     @Part("description") RequestBody description,
                                                     @Query("access_token") String token);
        

        此外,您可以将这些代码转换为 kotlin 等效代码。

        【讨论】:

        • 我已经提到我在 java 中得到了很多代码,但在 kotlin 中没有,你再次提供了 java 的代码。我无法从中获得任何帮助。 :( 因为我不够好,无法转换代码。
        • 您所要做的就是复制并粘贴代码。 Android Studio 会为您转换它们。 ?
        • 可以分享一下你开发的这个项目的源码吗?
        • 对不起。这个项目归我工作的公司所有,我不能分享这个项目。
        • 好的。谢谢你。 :-)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-31
        • 2022-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-12
        • 1970-01-01
        相关资源
        最近更新 更多