美文网首页
Android Retrofit2和Kotlin结合上传文件

Android Retrofit2和Kotlin结合上传文件

作者: 郭家大少爷 | 来源:发表于2017-12-18 20:33 被阅读50次

    现在Retrofit2和RxJava2是很流行的框架,可能是我太闭塞的缘故,竟然没有用过这样的框架,请原谅我以前都是在用xUtils3
    今天就来说一下Retrofit2和Kotlin结合上传文件
    1、首先集成工具
    (1)Kotlin就不用说了,Android Studio 3.0 以后自身就有
    (2)Retrofit2集成 在项目文件build.gradle 里添加

    dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:design:26.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    implementation 'com.squareup.okhttp3:okhttp:3.9.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
    }
    

    2、
    (1)编写一个KtvApiService接口

     /**
     * 作者:Galen on 2017/12/16 13:56
     * 邮箱:1270430761@qq.com
     */
    interface KtvApiService {
    @Multipart
    @POST(FACE_DETECT)
    fun detectFace(
            @Part("api_key") api_key: RequestBody,
            @Part("api_secret") api_secret: RequestBody ,
            @Part("return_attributes") return_attributes: RequestBody ,
            @Part part: MultipartBody.Part ): Call<DetectFaceResult>
    @FormUrlEncoded
    @POST(FACE_SET_GETDETAIL)
    fun getFaceSetDetail(@Field("api_key") api_key: String,
                         @Field("api_secret") api_secret: String,
                         @Field("outer_id") outer_id: String):Call<FaceSetDetailResult>
    }
    

    (2)、编写请求地址配置Constants(是一个静态的类)

    /**
     * 作者:Galen on 2017/12/16 13:58
     * 邮箱:1270430761@qq.com
     */
    object Constants {
    val LOCAL_SAVE_FACE_IMAGE = Environment.getExternalStorageDirectory().absolutePath + "/face.jpg"
    val FACE_BASE_URL = "https://api-cn.faceplusplus.com/facepp/v3/"
    const val FACE_DETECT = "detect"
    val FACE_FEATURE = "facequality,blur"
    val FACE_COMPARE = FACE_BASE_URL + "compare"
    val FACE_SEARCH = FACE_BASE_URL + "search"
    val FACE_SET = FACE_BASE_URL + "faceset/"
    val FACE_SET_CREATE = FACE_SET + "create"
    val FACE_SET_ADDFACE = FACE_SET + "addface"
    val FACE_SET_REMOVEFACE = FACE_SET + "removeface"
    val FACE_SET_UPDATE = FACE_SET + "update"
    const val FACE_SET_GETDETAIL ="faceset/getdetail"
    val FACE_SET_DELETE = FACE_SET + "delete"
    val FACE_SET_GETFACESETS = FACE_SET + "getfacesets"
    }
    

    (3)编写返回值 DetectFaceResult(我直接用的GsonFormat转的bean文件)

    /**
     * 作者:Galen on 2017/12/13 19:31
     * 邮箱:1270430761@qq.com
     */
    
    class DetectFaceResult {
    
    /**
     * image_id : rMqAJcCPIa/et7wAJ4BLpw==
     * request_id : 1513164138,f175169b-58c5-43af-ba58-d9150cc72f5c
     * time_used : 404
     * faces : [{"attributes":{"facequality":{"threshold":70.1,"value":74.748},"blur":{"blurness":{"threshold":50,"value":21.626},"motionblur":{"threshold":50,"value":21.626},"gaussianblur":{"threshold":50,"value":21.626}}},"face_rectangle":{"width":338,"top":87,"left":182,"height":338},"face_token":"5e43726aa72d35e5e78040c6b819dfb1"}]
     */
    
    var image_id: String? = null
    var request_id: String? = null
    var time_used: Int = 0
    var faces: List<FacesBean>? = null
    
    class FacesBean {
        /**
         * attributes : {"facequality":{"threshold":70.1,"value":74.748},"blur":{"blurness":{"threshold":50,"value":21.626},"motionblur":{"threshold":50,"value":21.626},"gaussianblur":{"threshold":50,"value":21.626}}}
         * face_rectangle : {"width":338,"top":87,"left":182,"height":338}
         * face_token : 5e43726aa72d35e5e78040c6b819dfb1
         */
    
        var attributes: AttributesBean? = null
        var face_rectangle: FaceRectangleBean? = null
        var face_token: String? = null
    
        class AttributesBean {
            /**
             * facequality : {"threshold":70.1,"value":74.748}
             * blur : {"blurness":{"threshold":50,"value":21.626},"motionblur":{"threshold":50,"value":21.626},"gaussianblur":{"threshold":50,"value":21.626}}
             */
    
            var facequality: FacequalityBean? = null
            var blur: BlurBean? = null
    
            class FacequalityBean {
                /**
                 * threshold : 70.1
                 * value : 74.748
                 */
    
                var threshold: Double = 0.toDouble()
                var value: Double = 0.toDouble()
            }
    
            class BlurBean {
                /**
                 * blurness : {"threshold":50,"value":21.626}
                 * motionblur : {"threshold":50,"value":21.626}
                 * gaussianblur : {"threshold":50,"value":21.626}
                 */
    
                var blurness: BlurnessBean? = null
                var motionblur: MotionblurBean? = null
                var gaussianblur: GaussianblurBean? = null
    
                class BlurnessBean {
                    /**
                     * threshold : 50.0
                     * value : 21.626
                     */
    
                    var threshold: Double = 0.toDouble()
                    var value: Double = 0.toDouble()
                }
    
                class MotionblurBean {
                    /**
                     * threshold : 50.0
                     * value : 21.626
                     */
    
                    var threshold: Double = 0.toDouble()
                    var value: Double = 0.toDouble()
                }
    
                class GaussianblurBean {
                    /**
                     * threshold : 50.0
                     * value : 21.626
                     */
    
                    var threshold: Double = 0.toDouble()
                    var value: Double = 0.toDouble()
                }
            }
        }
    
        class FaceRectangleBean {
            /**
             * width : 338
             * top : 87
             * left : 182
             * height : 338
             */
    
            var width: Int = 0
            var top: Int = 0
            var left: Int = 0
            var height: Int = 0
        }
    }
    }
    

    (4)调用

       fun faceDetect() {
      //创建Okhttp
        val builder = OkHttpClient.Builder()
      //添加日志拦截器(自定义日志拦截器)也可以不添加
      //builder.addInterceptor(LoggingInterceptor())
        val client = builder.build() 
        val retrofit = Retrofit.Builder()
        .client(client)
        .baseUrl(FACE_BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
               
        val service = retrofit.create(KtvApiService::class.java)
        val file = File(LOCAL_SAVE_FACE_IMAGE)
        val photoRequestBody = RequestBody.create(MediaType.parse("image/jpg"), file)
        val photoPart = MultipartBody.Part.createFormData("image_file", file.name, photoRequestBody)
        val api_key = RequestBody.create(MediaType.parse("text/plain"), API_KEY)
        val api_secret = RequestBody.create(MediaType.parse("text/plain"), API_SECRET)
        val return_attributes = RequestBody.create(MediaType.parse("text/plain"), FACE_FEATURE)
        if (file.exists()) {
            val repos = service.detectFace(api_key, api_secret, return_attributes, photoPart)
            repos.enqueue(object : Callback<DetectFaceResult> {
                override fun onResponse(call: Call<DetectFaceResult>?, response: Response<DetectFaceResult>?) {
                    if (response != null) {
                        Log.e("ScanActivity 成功", response.body().toString())
                    }
    
                }
    
                override fun onFailure(call: Call<DetectFaceResult>?, t: Throwable?) {
                    Log.e("ScanActivity  失败", t.toString())
    
                }
            })
    
        }
    }
    

    重点内容
    上传图片要携带参数时必须要以这样的格式

         @Multipart
    @POST(FACE_DETECT)
    fun detectFace(
            @Part("api_key") api_key: RequestBody,
            @Part("api_secret") api_secret: RequestBody ,
            @Part("return_attributes") return_attributes: RequestBody ,
            @Part part: MultipartBody.Part ): Call<DetectFaceResult>
    

    而不是

    @Multipart
    @POST(FACE_DETECT)
    fun detectFace(
            @Part("api_key") api_key: String,
            @Part("api_secret") api_secret: String,
            @Part("return_attributes") return_attributes: String,
            @Part part: MultipartBody.Part ): Call<DetectFaceResult>
    

    这样上传是错误的
    调用的时候
    携带的参数应该这样写
    上传照片的参数应该这样

        val photoRequestBody = RequestBody.create(MediaType.parse("image/jpg"), file)
        val photoPart = MultipartBody.Part.createFormData("image_file", file.name, photoRequestBody)
    

    其他参数

    val api_key = RequestBody.create(MediaType.parse("text/plain"), API_KEY)
    val api_secret = RequestBody.create(MediaType.parse("text/plain"), API_SECRET)
    val return_attributes = RequestBody.create(MediaType.parse("text/plain"), FACE_FEATURE)
    

    到此完工
    本人第一次在简书写文章,请多多关照,如需帮助,求留言,也请大家多多指教

    相关文章

      网友评论

          本文标题:Android Retrofit2和Kotlin结合上传文件

          本文链接:https://www.haomeiwen.com/subject/vpfvwxtx.html