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.