Я работаю над приложением для Android, и я боролся с вызовами/ответами API и т. д., и проблема заключается в том, что ответ API, который я получил и сериализовал/парцеллировал, был изменен, и я не мог найти способ сериализовать и разделить .
Это старый ответ API:
[
{
"msg": "No data available for this time period: 2022-11-14 11:00:00 and 2022-11-14 11:15:00"
},
{
"datetime": "2022-11-14 11:15:00",
"avg_temp": 27.59265899658203,
"min_temp": 27.59265899658203,
"max_temp": 27.59265899658203,
"open_temp": 27.59265899658203,
"close_temp": 27.59265899658203
},
{
"datetime": "2022-11-14 11:30:00",
"avg_temp": 27.59265899658203,
"min_temp": 27.59265899658203,
"max_temp": 27.59265899658203,
"open_temp": 27.59265899658203,
"close_temp": 27.59265899658203
}
]
Ответ API меняется на это:
[
[
1668413700,
-99,
29,
27.59,
27.59,
27.59,
27.59,
27.59
],
[
1668414600,
-99,
29,
27.59,
27.59,
27.59,
27.59,
27.59
]
]
и поэтому я уже создал такой класс данных:
@Parcelize
data class TRA(
@SerializedName("datetime")
val datetime: Long?,
@SerializedName("pred")
val pred: Float?,
@SerializedName("sensor")
val sensor: Int?,
@SerializedName("average")
val average: Float?,
@SerializedName("min")
val min: Float?,
@SerializedName("max")
val max: Float?,
@SerializedName("open")
val open: Float?,
@SerializedName("close")
val close: Float?,
@SerializedName("msg")
val msg: String?
):Parcelable
и у меня есть такой класс репозитория, и я изменил его для работы с новым ответом API:
suspend fun uploadId(request: TextRecognitionRequest): List<TRA>? {
return try {
val response = api.uploadSensorId(request = request)
val jsonArray = JSONArray(response)
val resultList = mutableListOf<TRA>()
for (i in 0 until jsonArray.length()) {
val json = jsonArray.getJSONArray(i)
val item = TemperatureResponseAggregation(
datetime = json.optInt(0),
pred = json.optDouble(1).toFloat(),
sensor = json.optInt(2),
average = json.optDouble(3).toFloat(),
min = json.optDouble(4).toFloat(),
max = json.optDouble(5).toFloat(),
open = json.optDouble(6).toFloat(),
close = json.optDouble(7).toFloat(),
)
resultList.add(item)
}
resultList
} catch (e: Exception) {
e.printStackTrace()
null
}
}
это мой класс MainActivityViewModel:
@HiltViewModel
class MainActivityViewModel @Inject constructor(
private val repository: CameraRepository
) : ViewModel() {
private val _sensorResponse = MutableLiveData<List<TRA>>()
val sensorResponse: LiveData<List<TRA>> = _sensorResponse
fun uploadSensorId(request: TextRecognitionRequest) {
viewModelScope.launch {
_sensorResponse.postValue(repository.uploadSensorId(request))
}
}
}
Я использую модификацию таким образом:
@Provides
@Singleton
fun provideCameraApi(okHttpClient: OkHttpClient): CameraApi {
return Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(CameraApi::class.java)
}
Наконец, в моей основной деятельности у меня есть функция, которая записывает эти данные ответа в диаграмму, она выглядит следующим образом:
private fun lineChartForDataObservation() {
viewModel.sensorResponse.observe(this) { response ->
response?.let { safeResponse ->
val values = arrayListOf<Float>()
val valuesPred = arrayListOf<Float>()
val valuesClose = arrayListOf<Float>()
val valuesOpen = arrayListOf<Float>()
val valuesMax = arrayListOf<Float>()
val valuesMin = arrayListOf<Float>()
dates = arrayListOf()
val sensors = arrayListOf<Int>()
for (item in safeResponse) {
item.datetime?.let { dates.add(it.toString()) }
item.pred?.let { valuesPred.add(it) }
item.average?.let { values.add(it) }
item.open?.let { valuesOpen.add(it) }
item.close?.let { valuesClose.add(it) }
item.min?.let { valuesMin.add(it) }
item.max?.let { valuesMax.add(it) }
}
chartModels.add(
AASeriesElement()
.name(sensors.component1().toString())
.data(values.toTypedArray())
.allowPointSelect(true)
.dashStyle(AAChartLineDashStyleType.Solid)
)
drawChart()
} ?: run {
Toast.makeText(this, "Something went wrong!", Toast.LENGTH_LONG).show()
startActivity(Intent(this, OpenCameraActivity::class.java))
}
}
}
Я пробовал и искал решение для этого, но не смог найти ничего полезного или полезного, поэтому, пожалуйста, я хочу узнать, как я могу выполнить эту задачу, и если я плохо объяснил свою проблему, извините за это, я все еще новичок в такого рода вещи.
РЕШЕНИЕ
Я заставил это работать, ребята, проблема была в моем интерфейсе API, который я изменил на Object to Array<Array>, теперь он работает так, спасибо за предложения и помощь. я очень ценю
@POST("....")
suspend fun test(
@Header("Accept") header1: String = "....",
@Header("User-Agent") header2: String = "....",
@Header("Connection") header5: String= ".....",
@Body request: .....,
) : Array<Array<Double>>
и у меня есть такой класс репозитория, и я изменил его для работы с новым ответом API:
for (i in 0 until jsonArray.length()) {
val jsonObject = jsonArray.getJSONObject(i)
Это не будет работать с «новым ответом API», поскольку ваш новый ответ API представляет собой массив массивов с плавающей запятой.
Вам понадобится что-то вроде:
for (i in 0 until jsonArray.length()) {
val jsonArrayOfFloats = jsonArray.getJSONArray(i)
// Parse jsonArrayOfFloats and do something with values
Предполагая, что значения с плавающей запятой в массивах соответствуют ранее названным значениям, тогда да, вам нужно всего лишь изменить функцию uploadId
, чтобы правильно проанализировать данные и создать объекты TRA
. Все остальное должно быть в состоянии остаться прежним.
Я внес некоторые коррективы, теперь я собираюсь отредактировать часть вопроса uploadId, можете ли вы проверить это также, потому что я думаю, что сделал что-то не так, и это не сработало
Хорошо, но вам придется уточнить, что означает «это не сработало».
извините, да, поэтому, когда я применяю эти изменения к классу репозитория, функция lineChartForDataObservation в основном действии должна отображать эти данные на линейной диаграмме, но это не так, и из-за этого приложения происходит сбой
«приложение вылетает» не поясняет, что означает «оно не сработало». Пожалуйста, отладьте свое приложение, чтобы определить, что вызывает его сбой. Тогда сделай так, чтобы этого не было.
Я помещаю некоторый Log.e для отладки в «uploadId», и код запускает блок catch, и сообщение об исключении выглядит так: «Произошло исключение: java.lang.IllegalStateException: Ожидается BEGIN_OBJECT, но был BEGIN_ARRAY в строке 2, столбце 6, путь $[0] "
Это указывает на то, что ваш код написан для анализа объекта JSON («Ожидаемый BEGIN_OBJECT»), но данные на самом деле являются массивом («но был BEGIN_ARRAY»). Убедитесь, что код, который вы пишете для синтаксического анализа, соответствует входной структуре json.
Как мне это сделать, что мне нужно изменить, чтобы разобрать его, класс данных? класс репозитория?
Вам не нужны данные или классы репозитория — исключение сообщает вам строку, которая была проанализирована неправильно. Вы пытались getJSONObject
когда это должно было быть getJSONArray
Я обновил его до getJsonArray, вы можете увидеть обновленный код выше, но он по-прежнему дает мне то же исключение, он запускает только блок catch
Выложите полную трассировку стека.
Я заставил это работать, проблема была в моем интерфейсе API. Я изменил Object на Array<Array<Double>>, теперь он работает так, спасибо за помощь
насколько я понимаю, мне нужно изменить класс репозитория и не трогать другие, которые я упомянул, верно? Кстати, я извиняюсь, если мой вопрос звучит немного глупо, я все еще учусь таким вещам.