JSON en Kotlin

qué es JSON

Aprende JSON en 10 minutos

Tutorial de JSON

Ejemplo:

xml json
<listado>
    <persona>
        <nombre>Juan</nombre>
        <apellidos>Palomo</apellidos>
        <fecha>20/10/1980</fecha>
    </persona>
    <persona>
        <nombre>Pepe</nombre>
        <apellidos>Gotera</apellidos>
        <fecha>7/8/1990</fecha>
    </persona>
</listado>
{"listado": [
              {
                "nombre":"Juan", 
                "apellidos":"Palomo", 
                "fecha": "20/10/1980"
              },
              {
                "nombre": "Pepe",
                "apellidos": "Gotera", 
                "fecha": "7/8/1990"
              }
           ]
}

 

Ejemplo: repositorios de un usuario en GitHub

https://api.github.com/users/paco-portada/repos

 

Json Viewer Tools

Online JSON Viewer

JSONLint – The JSON Validator

Extensión JSONView: Permite abrir documentos JSON en el navegador Firefox.

 

Json y Android

Clase JSONObject

  JSONObject(String json) Creates a new JSONObject with name/value mappings from the JSON string.
  getInt(String name) Returns the value mapped by name if it exists and is an int or can becoerced to an int, or throws otherwise.
  getString(String name) Returns the value mapped by name if it exists, coercing it if necessary, or throws if no such mapping exists.
  getJSONObject(String name) Returns the value mapped by name if it exists and is a JSONObject, or throws otherwise.
  put(String name, int value) Maps name to value, clobbering any existing name/value mapping with the same name.
  toString()  Encodes this object as a compact JSON string.

Clase JSONArray

  JSONArray(String json) Creates a new JSONArray with values from the JSON string.
  toString(int indentSpaces) Encodes this array as a human readable JSON string for debugging
  getJSONArray(String name) Returns the value mapped by name if it exists and is a JSONArray or throws otherwise

 

Parsing JSON in Android

 

Ejemplo: Lista de contactos

Crear una aplicación que lea una lista de contactos almacenada en un fichero en formato json (situado en la carpeta res/raw o en la tarjeta de memoria).
Cada contacto contendrá los campos: nombre, dirección, email y teléfono. En el teléfono se podrán guardar tres valores (casa, móvil y trabajo).

Crear el proyecto Lista Contactos Kotlin

Estructura del proyecto

¿contactos.json?

 

añadir contactos.json a la carpeta assets

view Binding en build.gradle

buildFeatures {
    viewBinding = true
}

acitvity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Lista de contactos"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.022" />

    <Switch
        android:id="@+id/switch1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"
        android:text="Gson"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.95"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginBottom="16dp"
        android:text="Mostrar"
        app:layout_constraintBottom_toTopOf="@+id/recyclerView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.462"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="362dp"
        android:layout_height="561dp"
        android:layout_marginBottom="28dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.326"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

</androidx.constraintlayout.widget.ConstraintLayout>

item_contact.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="10dp"
    android:paddingBottom="10dp">

    <TextView
        android:id="@+id/contact_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="name"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:textColor="#2196F3" />

    <TextView
        android:id="@+id/mobile_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="TextView" />

</LinearLayout>

Telefono.kt

data class Telefono (
    var casa: String,
    var movil: String,
    var trabajo: String
)

Contacto.kt

data class Contacto (
    var nombre: String,
    var direccion: String,
    var email: String,
    var telefono: Telefono
)

ContactosAdapter.kt

class ContactosAdapter(private var mContactos: List<Contacto>) : RecyclerView.Adapter<ContactosAdapter.ViewHolder>() {

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val binding = ItemContactBinding.bind(itemView)
    }
    
    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): ViewHolder {
        val context = parent.context
        val inflater = LayoutInflater.from(context)
        val contactView = inflater.inflate(R.layout.item_contact, parent, false)
        
        return ViewHolder(contactView)
    }
    
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // Get the data model based on position
        val contact = mContactos[position]

        // Set item views based on your views and data model
        holder.binding.contactName.text = contact.nombre
        holder.binding.mobilePhone.text = contact.telefono.movil
    }

    // Returns the total count of items in the list
    override fun getItemCount(): Int {
        return mContactos.size
    }

    fun actualizar(data: List<Contacto>) {
        mContactos = data
        notifyDataSetChanged()
    }
}

MainActivity.kt

class MainActivity : Activity(), View.OnClickListener {
    private lateinit var binding: ActivityMainBinding
    lateinit var adapter: ContactosAdapter

    companion object {
        const val CONTACTOS = "contactos.json"
        const val CONTACTS = "contacts.json"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main)
        binding = ActivityMainBinding.inflate(layoutInflater)

        val view: View = binding.root
        setContentView(view)
        binding.button.setOnClickListener(this)

        crearAdapter()
        // onClick(binding.button);
    }

    private fun crearAdapter() {
        // Create adapter passing in the sample user data
        adapter = ContactosAdapter(obtenerContactos())
        // Attach the adapter to the recyclerview to populate items
        binding.recyclerView.adapter = adapter
        // Set layout manager to position the items
        binding.recyclerView.layoutManager = LinearLayoutManager(this)
    }

    override fun onClick(v: View) {
        var contactos: ArrayList<Contacto> = obtenerContactos()

        if (v === binding.button) {
            if (contactos.size > 0)
                // adapter.notifyDataSetChanged();
                // adapter.notifyItemRangeChanged(0, contactos.size());
                adapter.actualizar(contactos)
            else
                mostrarMensaje("Error al obtener los contactos")
        }
    }

    fun obtenerContactos(): ArrayList<Contacto> {
        var contactos: ArrayList<Contacto> = ArrayList()
        lateinit var contenido: String
        lateinit var gson: Gson
        lateinit var persona: Persona
        lateinit var telefono: Telefono

        try {
            if (!binding.switch1.isChecked) {
                // Analizar contactos
                contenido = leerAsset(applicationContext, CONTACTOS)
                contactos = analizarContactos(contenido)
            } else {
                // usar Gson






            }
        } catch (e: IOException) {
            Log.e("Error: ", e.message.toString())
            mostrarMensaje("Error: " + e.message.toString())
        //} catch (e: JsonSyntaxException) {
        //    Log.e("Error: ", e.message.toString())
        //    mostrarMensaje("Error: " + e.message.toString())
        } catch (e: JSONException) {
            //e.printStackTrace();
            Log.e("Error: ", e.message.toString())
            mostrarMensaje("Error: " + e.message.toString())
        }

        return contactos
    }

    @Throws(IOException::class)
    fun leerAsset(context: Context, fileName: String): String {
        val jsonString: String

        jsonString = context.assets.open(fileName).bufferedReader().use { it.readText() }

        return jsonString
    }

    private fun mostrarMensaje(texto: String) {
        Toast.makeText(this, texto, Toast.LENGTH_SHORT).show()
    }
}

Análisis del fichero json

Utils/Analisis.kt

object Analisis {

    @Throws(JSONException::class)
    fun analizarContactos(cadena: String?): ArrayList<Contacto> {
        val jAcontactos: JSONArray
        val objeto: JSONObject
        var jOcontacto: JSONObject
        var jOtelefono: JSONObject
        var contacto: Contacto
        var telefono: Telefono
        val personas = ArrayList<Contacto>()

        // añadir contactos (en formato JSON) a personas















    }
}

 

Deja una respuesta