Android Moshi Adapter For Gps Location (Kotlin)

May 14, 2018

We shall parse {"geo":"1.0, 2.0"} into a LocationType class to store the latitude and longitude.

LocationType.

class LocationType(        @Transient var lat: Double? = null,        @Transient var lng: Double? = null) {    // accept android.location.Location    constructor(location: Location?): this(location?.latitude, location?.longitude)    companion object {        fun fromJson(data: String): LocationType? {            if (data.isEmpty()) {                return null            }            val item = LocationType()            item.fromJson(data)            return item        }    }    fun setValue(lat: Double, lng: Double) {        this.lat = lat        this.lng = lng    }    fun isNull(): Boolean {        return lat == null || lng == null    }    private fun fromJson(data: String) {        val tokens = data.split(",\\s?".toRegex())        if (tokens.size == 2) {            lat = tokens[0].toDouble()            lng = tokens[1].toDouble()        }        else {            lat = null            lng = null        }    }    fun toJson(): String? {        if (isNull()) {            return null        }        return "$lat, $lng"    }}

LocationAdapter.

class LocationAdapter {    @ToJson    @Nullable fun toJson(@Nullable value: LocationType?):  String? {        return value?.toJson()    }    @FromJson    fun fromJson(@Nullable data: String?): LocationType? {        if (data == null) {            return null        }        return LocationType.fromJson(data)    }}

Setup Moshi

val moshi = Moshi.Builder()      .add(LocationAdapter())      .add(KotlinJsonAdapterFactory())      .build()

Test Code.

data class PhotoPin (        @Json(name = "geo") var location: LocationType? = null        )
@RunWith(AndroidJUnit4::class)class MoshiTest {    lateinit var moshi: Moshi    lateinit var adapter: JsonAdapter<PhotoPin>    @Before    fun init() {        moshi = Moshi.Builder()            .add(LocationAdapter())            .add(KotlinJsonAdapterFactory())            .build()        adapter = moshi.adapter<PhotoPin>(PhotoPin::class.java)    }    @Test    fun testLocationEmpty() {        var item = adapter.fromJson("""{"geo": ""}""")!!        assertThat(item.location, Is(nullValue()))    }    @Test    fun testLocationNull() {        var item = adapter.fromJson("""{"geo": null}""")!!        assertThat(item.location, Is(nullValue()))    }    @Test    fun testLocationValue() {        var item = adapter.fromJson("""{"geo":"1.0, 2"}""")!!        assertThat(item.location, Is(notNullValue()))        assertThat(item.location?.lat, Is(1.0))        assertThat(item.location?.lng, Is(2.0))    }    @Test    fun testLocationValueToJson() {        var item = PhotoPin()        item.location = LocationType(1.0, 2.0)        val data = adapter.toJson(item)        assertThat(data.contains(""""geo":"1.0, 2.0""""), Is(true))        item = adapter.fromJson(data)!!        assertThat(item.location?.lat, Is(1.0))        assertThat(item.location?.lng, Is(2.0))    }    @Test    fun testLocationEmptyToJson() {        var item = PhotoPin()        val data = adapter.serializeNulls().toJson(item)        assertThat(item.location, Is(nullValue()))        assertThat(data.contains(""""geo":null"""), Is(true))        item = adapter.fromJson(data)!!        assertThat(item.location, Is(nullValue()))    }    }

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.