JSON en Kotlin
qué es 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
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?
{ "contactos":[
                {
                  "name": "John Doe",
                  "address": "123 Main St",
                  "city": "Anytown",
                  "phones": {
                    "landline": "555-123-4567",
                    "mobile": "555-987-6543",
                    "work": "555-111-2222"
                  }
                },
                {
                  "name": "Jane Smith",
                  "address": "456 Oak Ave",
                  "city": "Springfield",
                  "phones": {
                    "landline": "555-246-8010",
                    "mobile": "555-369-1212",
                    "work": "555-456-7890"
                  }
                },
                {
                  "name": "Peter Jones",
                  "address": "789 Pine Ln",
                  "city": "Riverdale",
                  "phones": {
                    "landline": "555-789-0123",
                    "mobile": "555-654-3210",
                    "work": "555-101-1122"
                  }
                }
              ]
}
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
Lo siento, debes estar conectado para publicar un comentario.