說到呼叫 API 的方法,那就一定會提到 Retrofit 這個無人不知,無人不曉的第三方的套件, 適用於 Android 和 Java 的類型安全HTTP 客戶端,功能強大且完整,好寫和好維護呀,廢話不多就用下去吧。
終於談到了Retrofit , 那我們就看一下從第15天到第17天的MVVM 架構,綜合實作一下吧
build.gradle(app)
dependencies {
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation "com.squareup.okhttp3:logging-interceptor:4.0.1"
implementation "com.squareup.okhttp3:okhttp:4.9.0"
}
AndroidManifet.xml 宣告 INTERNET 權限
<uses-permission android:name="android.permission.INTERNET" />
建立Interface
interface FindWcApi {
@GET("{mLocal}?format=json&limit=5&api_key="+ API_KEY)
suspend fun getToilet( @Path(value = "mLocal") Local:String,@Query(value = "filters") Latitude:String, @Query(value = "filters") Longitude:String): Response<ToiletData>
companion object {
const val OPENDATA_URL = "https://data.epa.gov.tw/api/v1/"
const val API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
建立Repository
class FindWcRepository(Local:String = "fac_p_07", Latitude:Double=24.9XXXX, Longitude:Double=121.5XXXX9) {
private val findWcApi: FindWcApi
var mLocal = Local
var mLatitude = Latitude
var mLongitude = Longitude
public val mApiInfo = ApiInfo(mLocal,mLatitude,mLongitude)
init {
val loggingInterceptor = HttpLoggingInterceptor()
println(loggingInterceptor.toString())
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
val okHttpClientBuilder = OkHttpClient.Builder().addInterceptor {
// This open API does not require any headers. This would be the
// place to add headers for APIs that, for example require an API key.
it.proceed(it.request().newBuilder().build())
}
val retrofit = Retrofit.Builder()
.baseUrl(FindWcApi.OPENDATA_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClientBuilder.build())
.build()
findWcApi = retrofit.create(FindWcApi::class.java)
}
fun getToiletData(block: suspend (ToiletData) -> Unit) {
runBlocking {
val response = findWcApi.getToilet(mLocal,"Latitude,LE,"+mLatitude,"Longitude,LE,"+mLongitude)
val result = response.body()
result?.let {
block(it)
}
}
}
}
**viewModel **
class Day21ViewModel:ViewModel() {
var toiletInfo = MutableLiveData<String>()
var toiletInfoResult: String = "查詢中"
fun getToiletInfo() {
FindWcRepository().getToiletData {
//var toiletInfo:String = ""
if(!it.records.isEmpty()) {
for(item in it.records.indices) {
toiletInfoResult= toiletInfoResult+"公廁名稱: "+it.records.get(item).Name + " 公廁地址: " + it.records.get(item).Address+"\n"
}
}else{
toiletInfoResult = "找不到資料或是資料有誤,如果還要找其他地方,請再問一次請問廁所在哪裏"
}
toiletInfo.postValue(toiletInfoResult)
}
}
}
Activity
viewModel = ViewModelProvider(this).get(Day21ViewModel::class.java)
viewModel.toiletInfo.observe(this){
binding.TextviewResult.text = it
}
//onClick
fun findwc(view: View) {
viewModel.getToiletInfo()
}
執行結果:
https://square.github.io/retrofit/
https://developer.android.com/jetpack
https://developer.android.com/topic/libraries/architecture/viewmodel
https://developer.android.com/topic/libraries/architecture/livedata