Search code examples
androidkotlinretrofitunicode-string

Retrofit auto parse html unicode


I have a problem. I have a json. I'm trying to parse symbols like ' and \u00e7. Symbol \u00e7 successfully parses, but symbol ' remains unchanged. Here's my retrofit builder.

Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .baseUrl(RatersApi.BASE_URL)
        .client(get())
        .build()
        .create(RatersApi::class.java)

and ok http builder which called from get() function

OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor()
            .apply { level = HttpLoggingInterceptor.Level.BODY }
        )
        .addInterceptor(HeaderInterceptor())
        .build()

ANSWER

Ok. I didn't find correct solution, so i wrote my own interceptor which transform strings from html. Just inject this into your okhttp builder Here it is:

class HtmlStringInterceptor: Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val response = chain.proceed(chain.request())

        val contentType = response.body?.contentType()
        val bodyString = if (android.os.Build.VERSION.SDK_INT >= 24) {
            Html.fromHtml(response.body?.string(), Html.FROM_HTML_MODE_COMPACT).toString()
        } else {
            Html.fromHtml(response.body?.string()).toString()
        }

        val body = bodyString.toResponseBody(contentType)
        return response.newBuilder().body(body).build()
    }
}

Solution

  • The cause of this issue is already in your title: ' is a HTML code and not Unicode.

    So the JSON parsing is correct and you need additional processing to handle HTML content. For example if you want to show it in a TextView you can use the following:

    // extension function to handle different api levels 
    fun TextView.setHtml(htmlContent: String) {
        if (android.os.Build.VERSION.SDK_INT >= 24) {
            this.text = Html.fromHtml(htmlContent, Html.FROM_HTML_MODE_COMPACT)
        } else {
            @Suppress("DEPRECATION")
            this.text = Html.fromHtml(htmlContent)
        }
    }
    
    // set view content from JSON 
    text_view.setHtml("test: '")