Home > front end >  Cant use @TypeConverter to convert between LatLng and String to store in Room Database
Cant use @TypeConverter to convert between LatLng and String to store in Room Database

Time:03-18

I'm building an android app that needs to store latitude and longitude in a room database.

Internally in my, am using the enter image description here


HOWEVER, when initially applying your code to an existing project I had the issue with the invalid return type.

What I did was to then look at using an alternative MyLatLng (2 doubles) and TypeConverters using:-

import com.google.android.gms.maps.model.LatLng

class MyLatLng(lat: Double, lng: Double) {

    var latitude: Double = lat
    var longitude: Double = lng

    /* <<<<<<<<<< Added AFTER successful compile >>>>>>>>>>*/
    fun getAsLatLng(): LatLng {
        return LatLng(latitude,longitude)
    }

}

and TypeConverters :-

@TypeConverter
fun myLatLngToString(latLng: MyLatLng) : String{
    return "(${latLng.latitude},${latLng.longitude}"
}

@TypeConverter
fun stringToMyLatLng(string: String) : MyLatLng{
    val s = string.replace("(", "").replace(")", "")
    val list = s.split(",")
    return MyLatLng(list.first().toDouble(), list.last().toDouble())
}

Changing location to be a MyLatLng rather than LatLng compiled fine, so I then added the function to convert a MyLatLng to a LatLng, this then compiled fine.

I then reverted to the original LatLng and commented out the MyLatLng converters and then NO invalid return type failure.

I then created a brand new project just with your code and extras to enable it to be run. It compiled OK and ran (as the results above show).

The full code used in the new project (with the imports):-

MyEntity

import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.android.gms.maps.model.LatLng

@Entity
data class MyEntity(
    @PrimaryKey
    val iD: String,
    var location: LatLng,
    val timeStamp: Long
)

Converters

import androidx.room.TypeConverter
import com.google.android.gms.maps.model.LatLng

class Converters{

    @TypeConverter
    fun latLngToString(latLng: LatLng) : String{
        return "(${latLng.latitude},${latLng.longitude}"
    }

    @TypeConverter
    fun stringToLatLng(string: String) : LatLng{
        val s = string.replace("(", "").replace(")", "")
        val list = s.split(",")
        return LatLng(list.first().toDouble(), list.last().toDouble())
    }
}

AllDao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query

@Dao
interface AllDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(myEntity: MyEntity)
    @Query("SELECT * FROM myentity")
    fun getAllMyEntities(): List<MyEntity>
}

TheDatabase

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters

@Database(entities = [MyEntity::class], version = 1, exportSchema = false)
@TypeConverters(value = [Converters::class])
abstract class TheDatabase: RoomDatabase() {
    abstract fun getAllDao(): AllDao

    companion object {
        private var instance: TheDatabase? = null
        fun getInstance(context: Context): TheDatabase {
            if (instance == null) {
                instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
                    .allowMainThreadQueries()
                    .build()
            }
            return instance as TheDatabase
        }
    }
}

MainActivity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.google.android.gms.maps.model.LatLng

class MainActivity : AppCompatActivity() {
    lateinit var db: TheDatabase
    lateinit var dao: AllDao
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        db = TheDatabase.getInstance(this)
        db.openHelper.writableDatabase
        dao = db.getAllDao()
        dao.insert(MyEntity("ME001", LatLng(101.12345678,202.87654321),System.currentTimeMillis()))
        dao.insert(MyEntity("ME002", LatLng(678.12345678,321.87654321),System.currentTimeMillis()))
        for(me: MyEntity in dao.getAllMyEntities()) {
            Log.d("DBINFO","MyEntity is ${me.iD} \n\tLATITUDE is ${me.location.latitude} \n\tLONGITUDE is ${me.location.longitude} \n\tTIMESTAMP is ${me.timeStamp}")
        }
    }
}
  • Related