RetrofitでRestAPIからデータを取得します
build.gradle
dependencies {
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
}
retrofit(非同期通信するためのライブラリ)をimplementします
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<uses-permission android:name="android.permission.INTERNET" />
インターネットに接続するのでパーミッションを追加します
com.exmple.myapp/network/ApiService.kt
package com.example.myapp.network
import retrofit2.Call
import retrofit2.http.GET
import com.example.myapp.model.Destination
interface ApiService {
@GET("wp-json/custom/v1/get-destination")
fun getDestination(): Call<List<Destination>>
}
API インターフェースの概要を定義します
今回は @GET(“REST APIのパス”) つまりREST APIからデータをGETします。
サーバーからはCustomData.ktで定義したDestinationオブジェクトのListがCall(呼び出し)されます。
そして関数getDestinationを使うことで、このListが得られるようにしておきます。
com.example.myapp/model/Destination.kt
package com.example.application0210.model
data class DestinationResponse(
val success: Boolean,
val data: List<Destination>
)
data class Destination(
val id: String,
val latitude: String, // APIのデータが文字列なので String にする
val longitude: String,
val created_at: String,
val closest_driver: String,
val min_distance: String,
val customer_name: String,
val customer_sex: String,
val customer_phone: String,
val customer_birth: String
)
データクラスを作成します。中身はカラム名に合わせます
HomeActivity.kt
package com.example.application0210
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.application0210.model.Destination
import com.example.application0210.model.DestinationResponse
import com.google.gson.Gson
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.IOException
class HomeActivity : AppCompatActivity() {
private lateinit var tvLabelInfo: TextView
private val handler = Handler(Looper.getMainLooper())
private val updateInterval: Long = 60000 // 1分ごとに更新
private lateinit var prefsManager: PrefsManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_home)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.home)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
prefsManager = PrefsManager(this)
tvLabelInfo = findViewById(R.id.tvLabelInfo)
startPolling()
}
private fun startPolling() {
handler.post(object: Runnable {
override fun run() {
fetchDestinationData()
handler.postDelayed(this, updateInterval)
}
})
}
private fun fetchDestinationData() {
val url = "https://azurlane.work/wp-json/custom/v1/get-destination"
val client = OkHttpClient()
val request = Request.Builder().url(url).build()
client.newCall(request).enqueue(object : okhttp3.Callback {
override fun onFailure(call: okhttp3.Call, e: IOException) {
Log.e("API", "Error: ${e.message}")
}
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
response.use { res ->
val responseBody = res.body?.string()
Log.d("API Response", "Response: $responseBody") // ログで確認
if (responseBody != null) {
try {
// DestinationResponse に変換
val responseObj: DestinationResponse = Gson().fromJson(responseBody, DestinationResponse::class.java)
// APIの `data` を取り出してリストにする
val destinations = responseObj.data
// UIを更新
runOnUiThread {
updateUI(destinations)
}
} catch (e: Exception) {
Log.e("API", "JSON parsing error: ${e.message}")
}
}
}
}
})
}
private fun updateUI(destinations: List<Destination>) {
val sb = StringBuilder()
for (dest in destinations) {
sb.append(
"Lat: ${dest.latitude.toDouble()}, " +
"Lon: ${dest.longitude.toDouble()}, " +
"Driver: ${dest.closest_driver}, " +
"Distance: ${dest.min_distance.toDouble()}, " +
"CustomerName: ${dest.customer_name}, " +
"CustomerSex: ${dest.customer_sex}, " +
"CustomerPhone: ${dest.customer_phone}, " +
"CustomerBirth: ${dest.customer_birth}\n"
)
}
tvLabelInfo.text = sb.toString()
}
override fun onDestroy() {
super.onDestroy()
handler.removeCallbacksAndMessages(null)
}
}
※1 … Retrofit.instance.getData()でhttps://xxx.com/wp-json/xxx にアクセスしてデータを取得します。
enqueueは非同期のHTTP通信を行うという意味です。executeとすると同期通信になります。
得られるデータはList<CustomData>という形になります。
※2 … 成功したらonResponse 、失敗したらonFailure 関数を実行します
※3 … レスポンスが成功(200等)かどうかを判別します
※4 … response.body() はAPIから返ってきたJSONデータをList<CustomData>というKotlinオブジェクトに変換したものです。これがnull出ない場合?.let {}内の処理を行います。
BACK