Complete Android port of duooomi-ios-sdk with 1:1 API parity. Includes SDK library module and Jetpack Compose demo app. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
60 lines
2.0 KiB
Kotlin
60 lines
2.0 KiB
Kotlin
package com.duooomi.ble.services
|
|
|
|
import com.duooomi.ble.DuooomiBleConfig
|
|
import com.duooomi.ble.core.DuooomiBleError
|
|
import com.duooomi.ble.models.FirmwareInfo
|
|
import com.duooomi.ble.utils.BleLog
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.withContext
|
|
import org.json.JSONObject
|
|
import java.net.HttpURLConnection
|
|
import java.net.URL
|
|
import java.net.URLEncoder
|
|
|
|
internal class FirmwareService(private val config: DuooomiBleConfig) {
|
|
|
|
private val latestPath = "api/auth/loomart/firmware/latest-published"
|
|
|
|
suspend fun fetchLatest(
|
|
identifier: String? = null,
|
|
status: String? = null
|
|
): FirmwareInfo? = withContext(Dispatchers.IO) {
|
|
val id = (identifier ?: config.firmwareIdentifier).trim()
|
|
val st = status ?: config.firmwareStatus
|
|
|
|
if (id.isEmpty()) {
|
|
throw DuooomiBleError.TransferFailed("Invalid firmware identifier")
|
|
}
|
|
|
|
val encodedId = URLEncoder.encode(id, "UTF-8")
|
|
val encodedStatus = URLEncoder.encode(st, "UTF-8")
|
|
val urlStr = "${config.apiHost}/$latestPath?identifier=$encodedId&status=$encodedStatus"
|
|
|
|
val connection = URL(urlStr).openConnection() as HttpURLConnection
|
|
try {
|
|
connection.requestMethod = "GET"
|
|
connection.setRequestProperty("x-api-key", config.apiKey)
|
|
connection.setRequestProperty("accept", "application/json")
|
|
connection.connectTimeout = 30_000
|
|
connection.readTimeout = 30_000
|
|
|
|
val code = connection.responseCode
|
|
if (code !in 200..299) {
|
|
throw DuooomiBleError.TransferFailed("HTTP $code")
|
|
}
|
|
|
|
val responseText = connection.inputStream.bufferedReader().readText()
|
|
val json = JSONObject(responseText)
|
|
|
|
if (json.optBoolean("success") != true) {
|
|
return@withContext null
|
|
}
|
|
|
|
val dataObj = json.optJSONObject("data") ?: return@withContext null
|
|
FirmwareInfo.fromJson(dataObj)
|
|
} finally {
|
|
connection.disconnect()
|
|
}
|
|
}
|
|
}
|