【问题标题】:Android 将文件上传到 s3 存储桶 - 错误请求
【发布时间】:2022-01-23 16:43:30
【问题描述】:

我正在尝试将文件上传到 s3 存储桶,但收到 400 错误请求或找不到文件。

我尝试了各种解决方案,但仍然没有运气。

解决方案 1:

我关注了this instructions

class InputStreamRequestBody(
    private val contentResolver: ContentResolver,
    private val uri: Uri
): RequestBody() {

    override fun contentType(): MediaType? =
        contentResolver.getType(uri)?.toMediaTypeOrNull()

    override fun writeTo(sink: BufferedSink) {
        contentResolver.openInputStream(uri)?.source()?.use(sink::writeAll)
    }

    override fun contentLength(): Long =
        contentResolver.query(uri, null, null, null, null)?.use { cursor ->
            val sizeColumnIndex: Int = cursor.getColumnIndex(OpenableColumns.SIZE)
            cursor.moveToFirst()
            cursor.getLong(sizeColumnIndex)
        } ?: super.contentLength()
    }

像这样使用它

@Multipart
@PUT
fun uploadFile(@Url url: String, @Part file: MultipartBody.Part): Single<Response<Any>>

val file = File(uri.path)
val requestBody = InputStreamRequestBody(contentResolver!!, uri)
val filePart = MultipartBody.Part.createFormData("file", file.name, requestBody)

packageApi.uploadFile(url, filePart)

这会导致错误请求

解决方案 2:

和之前一样,但这次没有 Multipart

@PUT
fun uploadFile(@Url url: String, @Body file: RequestBody): Single<Response<Any>>

val requestBody = InputStreamRequestBody(contentResolver!!, uri)
packageApi.uploadFile(url, requestBody)

这也会导致错误请求

解决方案 3:

现在我放弃了InputStreamRequestBody类,使用here提到的传统方式

@Multipart
@PUT
fun uploadFile(@Url url: String, @Part file: MultipartBody.Part): Single<Response<Any>>

val file = File(uri.path)
val requestFile = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val body = MultipartBody.Part.createFormData("file", file.name, requestFile)

packageApi.uploadFile(url, body)

这会导致 java.io.FileNotFoundException: /document/image:95: open failed: ENOENT (No such file or directory)

感谢任何建议/解决方案!

【问题讨论】:

    标签: android amazon-s3 retrofit okhttp


    【解决方案1】:

    我在我的项目中这样做了

      val key: String = AWS_DIRECTORY + fileFullName
          var transferUtility: TransferUtility? = null
          private var s3Client: AmazonS3? = null
          val region = Region.getRegion(Regions.AP_SOUTH_1)
          s3Client = AmazonS3Client(awsCredentials, region)
        transferUtility=TransferUtility.builder().s3Client(s3Client).context(activityContext)
                    .defaultBucket(AWS_BUCKET)
                    .build()
    
     val uploadObserver = transferUtility?.upload(
                AWS_BUCKET,
                key,
                file,
                CannedAccessControlList.PublicRead
            )
    
       uploadObserver?.setTransferListener(object : TransferListener {
    
                    override fun onStateChanged(id: Int, state: TransferState) {
                        if (TransferState.COMPLETED == state) {
    
                           
                        } else if (TransferState.FAILED == state) {
                          
                        }
                    }
                    override fun onProgressChanged(id: Int, bytesCurrent: Long, bytesTotal: Long) {
                        }
    
                    override fun onError(id: Int, ex: Exception) {
                   
                    }
                })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-25
      • 2015-05-05
      • 2018-03-25
      • 2018-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      相关资源
      最近更新 更多