Como Leer un archivo JSON en Android (Android Studio 3.6.1 + Java) – Parte 2 (Final)
Demo Github
En la Parte anterior llamada Como Leer un archivo JSON en Android (Android Studio 3.6.1 + Java) – Parte 1 creamos el proyecto, configuramos el archivo AndroidManifest.xml y creamos el código de la actividad principal en el archivo MainActivity.java, en esta Parte 2 y última, crearemos el modelo, el adaptador y otros elementos necesarios para que la aplicación funciones sin problemas.
Partes
- Parte 1
- Parte 2 (Final – Demo, Código Fuente en GitHub)
Antes de continuar te invito a leer los siguientes artículos:
- Que es Android y tu Primera aplicación Hola Mundo
- Las Novedades más Destacadas que trae Android Studio 3.6
- 5 Comandos en Android Studio que te harán más Productivo
- Entendiendo los Ciclos de Vida de una Actividad (Activity) en Android
Y también te invito a escuchar el Podcast: “Si No Tienes Experiencia Para Un Puesto De Trabajo, Créala !”:
Bien ahora continuemos con el Post: Como Leer un archivo JSON en Android (Android Studio 3.6.1 + Java) – Parte 2 (Final)
Adaptador (Adapter)
Voy a crear un Adaptador para mi aplicación, le pondré de nombre MyAppAdapter. java, este adaptador lo creo en app > java > com.example.miapp > adaptadores > MyAppAdapter.java (Puedes ver que he creado el directorio adaptadores).
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/app ├── /manifests ├── /java ├── /com.example.miapp ├── /adaptadores ├── MyAppAdapter // Abro este Archivo ├── MainActivity ├── /com.example.miapp (androidTest) ├── /com.example.miapp (test) ├── /res /Gradle Scripts |
Abro el archivo MyAppAdapter. java y voy a comenzar importando los siguientes elementos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; import com.example.miapp.R; import com.example.miapp.modelos.MyAppModel; import com.squareup.picasso.Picasso; import java.util.ArrayList; public class MyAppAdapter extends RecyclerView.Adapter<MyAppAdapter.MyViewHolder> { // Acá va el código del Adaptador } |
Luego defino un Inflater y el array de datos de mi modelo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com.example.miapp.adaptadores; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; import com.example.miapp.R; import com.example.miapp.modelos.MyAppModel; import com.squareup.picasso.Picasso; import java.util.ArrayList; public class MyAppAdapter extends RecyclerView.Adapter<MyAppAdapter.MyViewHolder> { private LayoutInflater inflater; private ArrayList<MyAppModel> myappModelArrayList; } |
Ahora voy a colocar 5 métodos indispensables para que mi Adaptador (Adapter) funcione sin problemas, estos métodos son MyAppAdapter(), onCreateViewHolder(), onBindViewHolder(), getItemCount() y dentro de este último agrego otro método llamado MyViewHolder().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
package com.example.miapp.adaptadores; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; import com.example.miapp.R; import com.example.miapp.modelos.MyAppModel; import com.squareup.picasso.Picasso; import java.util.ArrayList; public class MyAppAdapter extends RecyclerView.Adapter<MyAppAdapter.MyViewHolder> { private LayoutInflater inflater; private ArrayList<MyAppModel> myappModelArrayList; public MyAppAdapter(Context ctx, ArrayList<MyAppModel> myappModelArrayList){ inflater = LayoutInflater.from(ctx); this.myappModelArrayList = myappModelArrayList; } @Override public MyAppAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.item, parent, false); MyViewHolder holder = new MyViewHolder(view); return holder; } @Override public void onBindViewHolder(MyAppAdapter.MyViewHolder holder, int position) { holder.nombre.setText(myappModelArrayList.get(position).getNombre()); holder.precio.setText(myappModelArrayList.get(position).getPrecio()); holder.stock.setText(myappModelArrayList.get(position).getStock()); Picasso.get().load(myappModelArrayList.get(position).getImagen()).into(holder.img); } @Override public int getItemCount() { return myappModelArrayList.size(); } class MyViewHolder extends RecyclerView.ViewHolder{ TextView nombre, precio, stock; ImageView img; public MyViewHolder(View itemView) { super(itemView); nombre = (TextView) itemView.findViewById(R.id.nombre); precio = (TextView) itemView.findViewById(R.id.precio); stock = (TextView) itemView.findViewById(R.id.stock); img = (ImageView) itemView.findViewById(R.id.img); } } } |
El Adapter (Adaptador) se complementa con el RecyclerView el cual es un widget de Android que nos sirve de contenedor de los datos JSON.
Modelo
Ahora necesito un modelo para definir los datos que tiene mi archivo JSON, creo un modelo y le pongo de nombre MyAppModel.java, para mantener un orden lo voy a crear en app > java > com.example.miapp > modelos > MyAppModel.java (Puedes ver que he creado el directorio modelos).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/app ├── /manifests ├── /java ├── /com.example.miapp ├── /adaptadores ├── MyAppAdapter ├── /modelos ├── MyAppModel // Abro este Archivo ├── MainActivity ├── /com.example.miapp (androidTest) ├── /com.example.miapp (test) ├── /res /Gradle Scripts |
Abro el archivo MyAppModel.java y defino los campos del archivo JSON que utilizaré (He colocado comentarios en el código para explicar que hace cada porción de código).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package com.example.miapp.modelos; public class MyAppModel { // Declaro los campos private String nombre, precio, stock, img; // Campo nombre public String getNombre() { return nombre; } // Seteo el nombre public void setNombre(String nombre) { this.nombre = nombre; } // Campo precio public String getPrecio() { return precio; } // Seteo el precio public void setPrecio(String precio) { this.precio = precio; } // Campo stock public String getStock() { return stock; } // Seteo el Stock public void setStock(String stock) { this.stock = stock; } // Campo imagen public String getImagen(){ return img; } // Seteo la imagen public void setImagen(String img){ this.img = img; } } |
Solicitudes HTTP
Por último creo el archivo HttpRequest.java en app > java > com.example.miapp > HttpRequest.java, en este archivo crearé el código que me permitirá hacer peticiones HTTP al servidor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/app ├── /manifests ├── /java ├── /com.example.miapp ├── /adaptadores ├── MyAppAdapter ├── /modelos ├── MyAppModel ├── HttpRequest // Abro este Archivo ├── MainActivity ├── /com.example.miapp (androidTest) ├── /com.example.miapp (test) ├── /res /Gradle Scripts |
Abro el archivo HttpRequest.java y comienzo importando lo siguientes elementos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.example.miapp; import android.util.Log; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; public class HttpRequest { // Acá va el código } |
Dentro de la clase HttpRequest defino 4 métodos de petición al servidor (POST, PUT, DELETE, GET), asimismo creo 3 variables privadas, URL, httpURLConnection y OutputStream.
1 2 3 4 5 6 7 8 9 |
// Métodos de solicitud Http admitidos public static enum Method{ POST,PUT,DELETE,GET; } private URL url; private HttpURLConnection con; private OutputStream os; |
Paso seguido agrego 7 métodos necesarios para que las peticiones al servidor se lleven acabo sin problemas (He colocado comentarios en el código para explicar que hace cada porción de código).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
package com.example.miapp; import android.util.Log; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; public class HttpRequest { // Métodos de solicitud Http admitidos public static enum Method{ POST,PUT,DELETE,GET; } private URL url; private HttpURLConnection con; private OutputStream os; // Después de la creación de instancias, al abrir la conexión: puede ocurrir una excepción public HttpRequest(URL url)throws IOException { this.url = url; con = (HttpURLConnection)this.url.openConnection(); } // Se puede crear una instancia con la representación de String de la url // Obliga a verificar la IOException si es que es lanzada public HttpRequest(String url)throws IOException{ this(new URL(url)); Log.d("parametros", url); } // Método que prepara toda la solicitud al servidor private void prepararTodo(Method method)throws IOException{ con.setDoInput(true); con.setRequestMethod(method.name()); if(method== Method.POST||method== Method.PUT){ con.setDoOutput(true); os = con.getOutputStream(); } } // Preparo la solicitud con los diferentes métodos (GET, POST, PUT, DELETE) public HttpRequest preparar(Method method)throws IOException{ prepararTodo(method); return this; } // Le doy soporte de caracteres UTF-8 al archivo JSON public HttpRequest reciboDatos(String query) throws IOException{ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); writer.write(query); writer.close(); return this; } // Organizo los datos, a cada uno le defino un key = value public HttpRequest reciboDatos(HashMap<String,String> params) throws IOException{ StringBuilder resultado = new StringBuilder(); for(Map.Entry<String,String>entry : params.entrySet()){ resultado.append((resultado.length()>0?"&":"")+entry.getKey()+"="+entry.getValue()); Log.d("parametros",entry.getKey()+" ===> "+ entry.getValue()); } reciboDatos(resultado.toString()); return this; } // Solicito y recibo los datos en String public String enviaryRecibirString() throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); StringBuilder response = new StringBuilder(); for(String line;(line = br.readLine())!=null;)response.append(line+"\n"); Log.d("resultado",response.toString()); return response.toString(); } } |
Layouts
Luego de crear una nueva aplicación en Android Studio, este me crea el layout activity_main.xml, abro este archivo que se encuentra en app > res > layout > activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/app ├── /manifests ├── /java ├── /com.example.miapp ├── /adaptadores ├── MyAppAdapter ├── /modelos ├── MyAppModel ├── HttpRequest ├── MainActivity ├── /com.example.miapp (androidTest) ├── /com.example.miapp (test) ├── /res ├── /layout ├── activity_main.xml // Abro este Archivo /Gradle Scripts |
Abro el archivo activity_main.xml y agrego lo siguiente, uso un LinearLayout y en su interior creo un RecyclerView que será el contenedor de los datos que recibo del archivo JSON.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical" android:background="#ffffff" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Hello World" android:textColor="#fff" android:textStyle="bold" /> <!-- Contenedor de los datos que recibo del archivo JSON --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/contenedor" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:scrollbars="vertical"/> </LinearLayout> |
Ahora creo un layout con el nombre item.xml, este lo creo en app > res > layout > item.xml, este layout me servirá para mostrar cada dato o ítem que recibo del archivo JSON.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/app ├── /manifests ├── /java ├── /com.example.miapp ├── /adaptadores ├── MyAppAdapter ├── /modelos ├── MyAppModel ├── HttpRequest ├── MainActivity ├── /com.example.miapp (androidTest) ├── /com.example.miapp (test) ├── /res ├── /layout ├── activity_main.xml ├── item.xml // Abro este Archivo /Gradle Scripts |
Abro el archivo item.xml y agrego lo siguiente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content"> <androidx.cardview.widget.CardView android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" app:cardCornerRadius="5dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <!-- Contenedor de la Imagen --> <ImageView android:id="@+id/img" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:layout_marginBottom="10dp" android:scaleType="fitXY" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="100dp" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:orientation="vertical"> <!-- Contenedor del nombre --> <TextView android:id="@+id/nombre" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_marginTop="5dp" android:layout_weight="1" android:text="ddd" android:textColor="#000" android:textStyle="bold" /> <!-- Contenedor del precio --> <TextView android:id="@+id/precio" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" android:text="ddd" android:textColor="#000" android:textStyle="bold" /> <!-- Contenedor del stock --> <TextView android:id="@+id/stock" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" android:text="ddd" android:textColor="#000" android:textStyle="bold" /> </LinearLayout> </LinearLayout> </androidx.cardview.widget.CardView> </LinearLayout> |
Bien si lanzo la aplicación en el emulador o un dispositivo físico, debería poder leer los datos del archivo JSON sin problemas.
Eso es todo, al inicio he colocado una Demo un repositorio GitHub con el código de este proyecto.
Conclusión
Bien en este tutorial hemos aprendido a leer un archivo JSON puramente con Java en una aplicación Android, hay otras maneras de hacerlo, esta es una opción y espero que te sirva de mucho.
Nota
- Los pasos mencionadas y el código utilizado en este Post pueden ser modificadas o continuar en el futuro, esto no depende de mi, si no de los Desarrolladores que dan soporte a Android y Java.
- No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.
- Android Tutoriales
- 24-05-2020
- 08-06-2020
- Crear un Post - Eventos Devs - Foro