如何从房间数据库中的位置对象保存和检索纬度和经度

时间:2019-07-11 15:39:56

标签: android android-room android-location

我正在将AndroidX Room组件用于我的应用程序中的小型离线数据库。我希望能够将用户的位置(纬度和经度)保存到数据库中,并在以后使用。 怎么做以及最佳做法是什么?

我以前从未做过,也无法在网络上找到任何帮助。

这就是我的实际操作方式(显然是错误的方式):

@ColumnInfo(name = "session_location")
var sessionLocation: Location

我收到一个错误 Cannot figure out how to save this field into database

2 个答案:

答案 0 :(得分:1)

您的Location类是什么?是android.location.Location还是您定义的某个数据类?

无论如何,我都会使用@Embedded POJO类而不是其他人推荐的TypeConverters

如果Location是您已经定义的类,则只需在sessionLocation顶部添加@Embedded注释

@Embedded
@ColumnInfo(name = "session_location")
var sessionLocation: Location

否则,如果Locationandroid.location.Location,则您无需将所有信息存储在该类中。您必须使用lat & long的基本密码。

我将刚刚创建一个类Location并存储这些基本信息,并将其添加为@Embedded。像下面这样

class Location {
    var latitude: Double = 0
    var longitude: Double = 0
}

class User {
    @Embedded
    @ColumnInfo(name = "session_location")
    var sessionLocation: Location
}

正如其他人所建议的,TypeConverter是一种解决方案,但是当您可以直接保存它时,无需序列化/反序列化POJO

答案 1 :(得分:0)

您应为Room不支持的类型定义自己的转换器。基本上,SQLite仅支持原始类型作为列字段。 对于每种复杂数据类型,您必须定义一个自定义转换器,因为Room不知道如何在数据库列中序列化您的复杂类型。 为此,您需要创建一个转换器,该转换器负责在原始字段中转换复杂的结构化类型:

例如(来自android文档)

class Converters {
    @TypeConverter
    fun fromTimestamp(value: Long?): Date? {
        return value?.let { Date(it) }
    }

    @TypeConverter
    fun dateToTimestamp(date: Date?): Long? {
        return date?.time?.toLong()
    }
}

在您的情况下,最简单的方法是使用 GSON 将对象序列化为JSON字符串(当您写入数据库时​​-Room支持字符串),然后将数据库中的字符串解析为从数据库中读取您的Location对象

在您的情况下,我会做类似的事情:

class LocationConverter {
   @TypeConverter
    fun toLocation(locationString: String?): Location? {
        return try {
            Gson().fromJson(locationString, Location::class.java)
        } catch (e: Exception) {
            null
        }
    }

    @TypeConverter
    fun toLocationString(location: Location?): String? {
        return Gson().toJson(location)
    }
}

完成转换器后,请使用刚刚定义的LocationConverter为数据库添加注释!

@TypeConverters(LocationConverter::class)
abstract class YourDatabase : RoomDatabase() {
  // your code
}