How to access a field array nested in an array of JSON? I need to get the value of the field "value" from the array "rows" -> "elements" -> "distance" -> "value"

JSON https://api.myjson.com/bins/1dzkgl

{ "destination_addresses" : [ "ул. 2-й Луч, 5а, Санкт-Петербург, Россия, 192019" ], "origin_addresses" : [ "ул. Книпович, 11, Санкт-Петербург, Россия, 192019" ], "rows" : [ { "elements" : [ { "distance" : { "text" : "0,4 км", "value" : 443 }, "duration" : { "text" : "1 мин.", "value" : 70 }, "status" : "OK" } ] } ], "status" : "OK" } 

There is such a working example, but I can’t get there in any way by analogy with my own.

 { "data": "dbfriends", "friends": [ { "id": "1", "name": "Andrew", "city": "Moscow", "contacts": { "mobile": "+7 0000000", "email": "andrew@androiddocs.ru", "skype": "andrew" } }, { "id": "2", "name": "Ivan", "city": "Kiev", "contacts": { "mobile": "+38 0000000", "email": "ivan@androiddocs.ru", "skype": "ivan" } } ] } 

 package com.example.sfp.javaparsejson import android.os.AsyncTask import android.support.v7.app.ActionBarActivity import android.os.Bundle import android.util.Log import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import java.io.BufferedReader import java.io.InputStream import java.io.InputStreamReader import java.net.HttpURLConnection import java.net.URL class MainActivity : ActionBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ParseTask().execute() } private inner class ParseTask : AsyncTask<Void, Void, String>() { internal var urlConnection: HttpURLConnection? = null internal var reader: BufferedReader? = null internal var resultJson = "" override fun doInBackground(vararg params: Void): String { // получаем данные с внешнего ресурса try { val url = URL("http://androiddocs.ru/api/friends.json") urlConnection = url.openConnection() as HttpURLConnection urlConnection!!.requestMethod = "GET" urlConnection!!.connect() val inputStream = urlConnection!!.inputStream val buffer = StringBuffer() reader = BufferedReader(InputStreamReader(inputStream)) var line: String? /* while ((line = reader!!.readLine()) != null) { buffer.append(line) }*/ do { line = reader!!.readLine() if (line == null) break buffer.append(line) } while (true) resultJson = buffer.toString() } catch (e: Exception) { e.printStackTrace() } return resultJson } override fun onPostExecute(strJson: String) { super.onPostExecute(strJson) // выводим целиком полученную json-строку Log.d(LOG_TAG, strJson) var dataJsonObj: JSONObject? = null var secondName = "" try { dataJsonObj = JSONObject(strJson) val friends = dataJsonObj.getJSONArray("friends") // 1. достаем инфо о втором друге - индекс 1 val secondFriend = friends.getJSONObject(1) secondName = secondFriend.getString("name") Log.d(LOG_TAG, "Второе имя: " + secondName) // 2. перебираем и выводим контакты каждого друга for (i in 0..friends.length() - 1) { val friend = friends.getJSONObject(i) val contacts = friend.getJSONObject("contacts") val phone = contacts.getString("mobile") val email = contacts.getString("email") val skype = contacts.getString("skype") Log.d(LOG_TAG, "phone: " + phone) Log.d(LOG_TAG, "email: " + email) Log.d(LOG_TAG, "skype: " + skype) } } catch (e: JSONException) { e.printStackTrace() } } } companion object { var LOG_TAG = "my_log" } } 

Reply from comments (Message: No value for value)

 dataJSON = JSONObject(strJson) val rows = dataJSON.getJSONArray("rows") val obj = rows.getJSONObject(0) val elements = obj.getJSONArray("elements") val distance = elements.getJSONObject(0) val value = distance.getJSONObject("value") Log.d(LOG_TAG, "Text: " + value) 

    1 answer 1

    Code on kotlin:

     val resultJson = JSONObject(responseString) val rows = resultJson.getJSONArray("rows") val obj = rows.getJSONObject(0) val elements = obj.getJSONArray("elements") val element = elements.getJSONObject(0) val distance = element.getJSONObject("distance") val value = distance.getInt("value") 

    And in general, even though you (as I understood it) have just started learning, it will be much easier to solve some routine issues with the help of third-party libraries. Asyncracy is, of course, good and important, but it would be much easier to solve your problem like this:

     val client = OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .retryOnConnectionFailure(false) .build() val request = Request.Builder() .url(url) .build() client.newCall(request).enqueue(object : Callback { override fun onResponse(call: Call?, response: Response?) { val responseString = response!!.body()!!.string() val resultJson = JSONObject(responseString) val rows = resultJson.getJSONArray("rows") val obj = rows.getJSONObject(0) val elements = obj.getJSONArray("elements") val element = elements.getJSONObject(0) val distance = element.getJSONObject("distance") val value = distance.getInt("value") Log.d(TAG, "'value': " + value); } override fun onFailure(call: Call?, e: IOException?) { Log.d(TAG, "some error"); } }) 

    The OkHttp library is used .

    • Message: No value for value. The code on kotlin in question. - nuqss
    • @userBuzzer fixed. - Peter Samokhin
    • responseString is an unknown argument. Before, I didn’t have a case with JSON at all. Libraries are good, but in the absence of experience using them on the cotlin, the code falls off in various places, thus having to look for other solutions. - nuqss
    • @userBuzzer do you have experience with java? If so, what's the difference, use libraries on cotlin or on it? I brought a piece of code completely working, if you use only the part with JSON parsing, replace the responseString in your code with your strJson and all problems will be solved. - Peter Samokhin
    • Thanks for the answer. The OkHttp library helped me. And it didn't even fall off, although I recently tried using it ... - nuqss