我们用到的 API endpoint 只有一个,就是用来取得港铁机场快綫、东涌綫、屯马綫及将军澳綫最多四班即将到站列车的抵达时间。车站清单我们会直接写死在 app 里面。API 的使用方法可以在资料一线通网站(香港政府 open data 的网站)内找到。这个 API 是不需要额外申请 API key,只是一个普通的 HTTP GET request,然後 response body 是一个 JSON object。
打开「数据字典」PDF 档,可以找到各车站及行车綫的代码和 response body JSON object 的说明。当中我们主要用到的 property 大致上是:
plat
月台编号time
时间(留意它的格式并非按照 ISO 8601)dest
目的地车站代码seq
次序(我们要按照这个顺序显示班次)再看「港铁实时列车服务资讯 API 规范文件」PDF 档,它提供了几个 HTTP response status code 的意义和一些 response body 例子。例如当事故发生时那个 API 会提供一段文字让我们显示。
一般而言,我们都不会直接用 Android SDK 入面的 org.json 套件(即是 JSONObject
那些 class)来将 API response 的 JSON 转成 Java/Kotlin object。因为要为每个 property 逐个写 code,费时失事,所以我们都会用其他 deserialization library 去做 JSON 和 Java/Kotlin object 转换。
在使用那些 library 之前,我们要准备 API response JSON 对应的 Kotlin data class。那个 data class 基本上就是要跟 JSON object 的结构相同,即是 response 的那个 property 是 string 就要在 data class 开对应的 string property。另外,我们只对整个 response 入面的某几个 property 感兴趣,所以在准备 data class 只针对那几个 property 而造,其余的东西我们就略过。
下面就是完成後的 data class,最尾的 companion object 放了几个 constant 方便之後处理。
data class EtaResponse(
/**
* system status code.
*/
val status: Int = STATUS_ERROR_OR_ALERT,
/**
* Alert message.
*/
val message: String = "",
/**
* URL for Special Train Services Arrangement case.
*/
val url: String = "",
/**
* Indicate if the train is delayed.
*/
val isDelay: String = IS_DELAY_FALSE,
val data: Map<String, Data> = emptyMap()
) {
data class Data(
/**
* Indicate the destinations of the train in the specific line (up trip).
*/
val up: List<Eta> = emptyList(),
/**
* Indicate the destinations of the train in the specific line (down trip).
*/
val down: List<Eta> = emptyList()
)
data class Eta(
/**
* Platform numbers for the departure / arrival train.
*/
val plat: String = "1",
/**
* Estimated arrival time (or departure time) of the train.
*/
val time: String = EMPTY_TIMESTAMP,
/**
* MTR Station Code in capital letters.
*/
val dest: String = "",
/**
* The sequence of the 4 upcoming trains.
*/
val seq: String = "0"
)
companion object {
const val EMPTY_TIMESTAMP = "-"
const val STATUS_NORMAL = 1
const val STATUS_ERROR_OR_ALERT = 0
const val IS_DELAY_TRUE = "Y"
const val IS_DELAY_FALSE = "N"
}
}
我们已经准备好 response 的 data class。下一篇我们会介绍不同的 JSON deserialization library 并且将 EtaResponse
加上 deserialization library 的 annotation。
<<: Day 3: 人工智慧在音乐领域的应用 (各层面的应用二)
>>: 03. Unit Test x PHPUnit x FizzBuzz
今天讲的内容属於简单的元件使用,而我在前面几天已经先有拿来用几次来观察结果,但我一直没有好好提到,今...
这边你需要自己制作一个流程控制 不了解的话建可以画个图来确认现在在哪个流程 基本上都会回到主要操控介...
到目前为止的范例都是只有单一类别,但在真实的世界里其实是更复杂的,像是如果想要再加入一个小狗类别: ...
Check-in Check-in让成员有不同面向了解彼此的机会 文化的塑造与累积是每一天都在进行的...
虽然今天已经是最後一天,但如果明天系统仍然可以发文的话,会先继续发文,方便之後回顾整理系列文时,能够...