okhttp3图片压缩上传_Android使用OkHttp上传图片的实例代码

简介

上传图片是一个APP的常见功能,可以是通过OOS上传到阿里云,也可以直接上传到Server后台,OOS有提供相应的SDK,此处忽略。下面通过OkHttp来实现图片的上传

代码

直接上代码UploadFileHelper.kt

object UploadFileHelper {

//--------ContentType

private val MEDIA_OBJECT_STREAM = MediaType.parse("multipart/form-data")

//--------上传延时时间

private val WRITE_TIME_OUT:Long = 50

private val mOkHttpClient by lazy { OkHttpClient() }

//------基本参数----------

val version = AppConstant.API_VERSION

val platform = AppConstant.API_PLATFORM

val methodName = AppConstant.API_UPLOADFILE_METHOD

val token = ignoreException("") { UserModel.token() }

val userId = ignoreException(0) { UserModel.id() }

//------------------------

//不带参数同步上传文件

fun syncUploadFile(actionUrl: String = "",file: File,maxW: Int = 256,maxH: Int = 256):String?{

val uploadFile = optionFileSize(file,maxW,maxH,null)

if(uploadFile!=null){

val response = createNoParamsOkHttpCall(actionUrl,uploadFile).execute()

if(uploadFile.exists())

uploadFile.delete()

return getResponseToPath(response.body()!!.string())

}

return null

}

//不带参数异步上传文件

fun asyncUploadFile(actionUrl:String = "", file: File,maxW: Int = 256,maxH: Int = 256,

uploadCallBackListener: UploadCallBackListener? = null){

val uploadFile = optionFileSize(file,maxW,maxH,uploadCallBackListener)

if(uploadFile!=null)

createNoParamsOkHttpCall(actionUrl,uploadFile).enqueue(object: Callback{

override fun onFailure(c: Call, e: IOException) {

uploadCallBackListener?.onUploadFailure(e.toString())

}

override fun onResponse(c: Call, response: Response) {

if(uploadFile.exists())

uploadFile.delete()

uploadCallBackListener?.onUploadSuccess(getResponseToPath(response.body()!!.string()))

response.body()!!.close()

}

})

}

//带参数同步上传文件

fun syncParamsUploadFile(actionUrl: String= "",file: File,params:HashMap,

maxW: Int = 256,maxH: Int = 256):String?{

val uploadFile = optionFileSize(file,maxW,maxH,null)

if(uploadFile!=null){

params.put("filename",uploadFile)

val response = createParamsOkHttpCall(actionUrl,params,null,false).execute()

if(uploadFile.exists())

uploadFile.delete()

return getResponseToPath(response.body()!!.string())

}

return null

}

//带参数异步上传文件

fun asyncParamsUploadFile(actionUrl: String= "",file: File,params:HashMap,maxW: Int = 256,maxH: Int = 256,

uploadCallBackListener: UploadCallBackListener? = null, isProgress:Boolean = true){

val uploadFile = optionFileSize(file,maxW,maxH,uploadCallBackListener)

if(uploadFile!=null){

params.put("filename",uploadFile)

createParamsOkHttpCall(actionUrl,params,uploadCallBackListener,isProgress).enqueue(object :Callback{

override fun onFailure(c: Call, e: IOException) {

uploadCallBackListener?.onUploadFailure(e.toString())

}

override fun onResponse(c: Call, response: Response) {

if(uploadFile.exists())

uploadFile.delete()

uploadCallBackListener?.onUploadSuccess(getResponseToPath(response.body()!!.string()))

response.body()!!.close()

}

})

}

}

//------创建一个没有带参数的Call

fun createNoParamsOkHttpCall(actionUrl: String,file: File):Call{

val requestUrl = "${AppConstant.HOST}/$actionUrl"

val requestBody = RequestBody.create(MEDIA_OBJECT_STREAM,file)

val request = Request.Builder().url(requestUrl).post(requestBody).build()

return mOkHttpClient.newBuilder().writeTimeout(WRITE_TIME_OUT,TimeUnit.SECONDS).build().newCall(request)

}

//------创建一个带参数的Call

fun createParamsOkHttpCall(actionUrl: String,params:Map,

uploadCallBackListener: UploadCallBackListener? = null,

isProgress:Boolean = true):Call{

//-----AppConstant.HOST 上传图片的Server的BASE_URL http://xxx.com

val requestUrl = "${AppConstant.HOST}/$actionUrl"

val builder = MultipartBody.Builder()

builder.setType(MultipartBody.FORM)

val newParams = mutableMapOf(

"version" to version,

"platform" to platform,

"methodName" to methodName,

"token" to token,

"user_id" to userId)

newParams.putAll(params)

newParams.forEach( action = {

if(it.value is File){

builder.addFormDataPart(it.key, (it.value as File).name,

if(isProgress) createProgressRequestBody(MEDIA_OBJECT_STREAM!!,(it.value as File),uploadCallBackListener)

else RequestBody.create(null, (it.value as File)))

}else{

builder.addFormDataPart(it.key,it.value.toString())

}

})

val body = builder.build()

val request = Request.Builder().url(requestUrl).post(body).build()

return mOkHttpClient.newBuilder().writeTimeout(WRITE_TIME_OUT,TimeUnit.SECONDS).build().newCall(request)

}

//创建带进度RequestBody

fun createProgressRequestBody(contentType:MediaType,file:File,

uploadCallBackListener: UploadCallBackListener? = null):RequestBody{

return object:RequestBody(){

override fun contentType(): MediaType = contentType

override fun contentLength() = file.length()

override fun writeTo(sink: BufferedSink) {

ignoreException {

val source = Okio.source(file)

val buf = Buffer()

val remaining = contentLength()

var current: Long = 0

var readCount: Long = source.read(buf, 2048)

while (readCount != -1L) {

sink.write(buf, readCount)

current += readCount

uploadCallBackListener?.onUploadProgress(current,remaining)

readCount = source.read(buf, 2048)

}

}

}

}

}

//根据图片大小简单压缩

fun optionFileSize(file: File,maxW:Int,maxH:Int,uploadCallBackListener: UploadCallBackListener?):File?{

try {

val uploadFile = File(AppBridge.AppContext().externalCacheDir, file.hashCode().toString())

ImageUtils.resize(file, maxW, maxH, uploadFile)

return uploadFile

} catch (e: Exception) {

uploadCallBackListener?.onUploadFailure("压缩图片失败")

return null

}

}

//解析Server返回的数据获取图片路径,

/*

{"code":200,"msg":"上传成功","data":{"path":""}}

*/

fun getResponseToPath(response:String):String{

val dataJsonObj = JSONObject(response).get("data") as JSONObject

return dataJsonObj.get("path") as String

}

//回调方法

interface UploadCallBackListener{

fun onUploadFailure(error:String)

fun onUploadProgress(currentSize:Long,totalSize:Long)

fun onUploadSuccess(path:String)

}

}

inline fun ignoreException(def: T, f: () -> T): T {

try {

return f()

} catch(e: Exception) {

Timber.e(e, "")

return def

}

}

最后根据是否要带参数、同步或异步调用其中对应的方法可以了

syncUploadFile(xxx)

asyncUploadFile(xxx)

syncParamsUploadFile(xxx)

asyncParamsUploadFile(xxx)

总结

首先根据是否要带参数上传,如果不带参数上传,直接创建RequestBody;如果带参数上传,创建MultipartBody.Builder(),然后把所有参数addFormDataPart进去,其中addFormDataPart方法有个RequestBody参数通过是否要监听进度创建,如果需要进度,需重写RequestBody的writeTo()方法,如果不监听进度,直接创建RequestBody,最后builder.build()得到RequestBody

通过上步骤得到的RequestBody以及上传图片的Server路径,可以配置出一个Request对象。

把Request对象通过.newCall(request)配置在OkHttpClient得到Call对象

最后Call调用同步.execute()或者异步.enqueue(callBack),在回调里面处理返回的数据。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值