Ошибка Kotlin Json при анализе данных openweather

#json #kotlin

Вопрос:

Я пытаюсь разобрать Json из openweathermap.org . Я следую этому руководству о том, как это сделать. Однако при запуске моего кода я получаю следующий журнал ошибок:

     Process: com.example.fuelcalculation3, PID: 18592
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fuelcalculation3/com.example.fuelcalculation3.OpenWeatherScratchPad}: org.json.JSONException: Value {"temp":294.45,"feels_like":294.46,"temp_min":293.77,"temp_max":295.41,"pressure":1013,"humidity":70} at main of type org.json.JSONObject cannot be converted to JSONArray
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: org.json.JSONException: Value {"temp":294.45,"feels_like":294.46,"temp_min":293.77,"temp_max":295.41,"pressure":1013,"humidity":70} at main of type org.json.JSONObject cannot be converted to JSONArray
        at org.json.JSON.typeMismatch(JSON.java:101)
        at org.json.JSONObject.getJSONArray(JSONObject.java:599)
        at com.example.fuelcalculation3.OpenWeatherScratchPad.onCreate(OpenWeatherScratchPad.kt:30)
        at android.app.Activity.performCreate(Activity.java:8000)
        at android.app.Activity.performCreate(Activity.java:7984)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)


 

Вот мой код:

 
import android.os.Build
import android.os.Bundle
import android.os.StrictMode
import android.util.Log
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import org.json.JSONObject
import org.json.JSONTokener
import java.net.URL


class OpenWeatherScratchPad : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_open_weather_scratch_pad)

        if (Build.VERSION.SDK_INT > 9) {
            val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
            StrictMode.setThreadPolicy(policy)
        }

        title = "Openweather Scratchpad";

        val type: String = "data"
        val updateTextViewJsonData = findViewById<TextView>(R.id.textViewJsonData)
        var openWeatherURL = URL("https://api.openweathermap.org/data/2.5/weather?{MYAPI-KEY]").readText();
        val jsonObject = JSONTokener(openWeatherURL).nextValue() as JSONObject;
        val jsonArray = jsonObject.getJSONArray("main");

        for ( i in 0 until jsonArray.length()) {
            val type = jsonArray.getJSONObject(i).getString("coord");
            Log.i("coord", type);
            updateTextViewJsonData.text="$i"
        }
    }
}
 

И возвращаемый JSon выглядит следующим образом:

 {"coord":{"lon":145.7667,"lat":-16.9167},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03n"}],"base":"stations","main":{"temp":294.72,"feels_like":294.76,"temp_min":294.32,"temp_max":295.41,"pressure":1013,"humidity":70},"visibility":10000,"wind":{"speed":3.6,"deg":160},"clouds":{"all":40},"dt":1626598739,"sys":{"type":1,"id":9490,"country":"AU","sunrise":1626554765,"sunset":1626595186},"timezone":36000,"id":2172797,"name":"Cairns","cod":200}
 

Я знаю о доступных парсерах JSon, но я хотел бы узнать, как выполнять простой синтаксический анализ JSon. Есть гораздо более эффективные способы сделать это, но я решил, что должен, по крайней мере, попытаться сделать это вручную, чтобы получить некоторое представление о том, как все это работает.

Ответ №1:

проверьте свой ответ

{«коорд»:{«долгота»:145.7667,»широта»:-16.9167},»погода»:[{«идентификатор»:802,»главный»:»облака»,»описание»:»рассеянные облака»,»значок»:»03n»}],»основание»:»вокзалы»,«main»:{«temp»:294.72,»feels_like»:294.76,»temp_min»:294.32,»temp_max»:295.41,»pressure»:1013,»humidity»:70},»visibility»:10000,»wind»:{«speed»:3.6,»deg»:160},»clouds»:{«all»:40},»dt»:1626598739,»sys»:{«type»:1,»id»:9490,»country»:»AU»,»sunrise»:1626554765,»sunset»:1626595186},»timezone»:36000,»id»:2172797,»name»:»Cairns»,»cod»:200}

синтаксический анализ не будет работать, потому что main-это не JSONArray, это JSONObject, поэтому измените эту строку

         val jsonArray = jsonObject.getJSONArray("main");
 

к этому,
если вы хотите получить элементы из «main»

         val mainOb = jsonObject.get("main") as JSONObject