当前位置: 移动技术网 > 移动技术>移动开发>Android > Android使用OkHttp上传图片的实例代码

Android使用OkHttp上传图片的实例代码

2019年07月24日  | 移动技术网移动技术  | 我要评论

简介

上传图片是一个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<string,any>,
      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<string,any>,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<string,any>,
        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 <t> 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),在回调里面处理返回的数据。

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网