Hola developers, vamos a ver como se parsea un documento JSON en Android.
JSON EN ANDROID
JSON (JavaScript Object Notation) es un formato para intercambiar datos, JSON los describe con una sintaxis dedicada que se usa para identificarlos y gestionarlos.
JSON es una alternativa a XML,y el fácil uso en javascript ha generado un gran numero de seguidores. Una de las mayores ventajas que tiene el uso de JSON es que puede ser leído por cualquier lenguaje de programación. Así que en resumen, puede ser usado para el intercambio de información entre tecnologías distintas.
Según esté realizado el formulario, nos encontraremos con arrays u objetos, y así lo representaremos en el código.
Por ejemplo tenemos este código en JSON, hay herramientas online para la visualización de nuestro archivo JSON y para que se nos ayude con la sintaxis, como por ejemplo JSON Viewer
{
"Personajes": [
{
"Equipo": "Elfos",
"name": "Arwen",
"Especialidad":"guerrero",
"image": "http://oi60.tinypic.com/2emoi7n.jpg",
"Habilidades": {
"Fuerza": "7",
"Espiritu": "2",
"Fortaleza": "8"
}
},
{
"Equipo": "Orcos",
"name": "Arwen",
"Especialidad":"Brujo",
"image": "http://oi59.tinypic.com/2jetzl0.jpg",
"Habilidades": {
"Fuerza": "1",
"Espiritu": "10",
"Fortaleza": "5"
}
},
{
"Equipo": "Humanos",
"name": "Arwen",
"Especialidad":"Mago",
"image": "http://oi61.tinypic.com/msoyfa.jpg",
"Habilidades": {
"Fuerza": "1",
"Espiritu": "9",
"Fortaleza": "3"
}
}
]
}
Este archivo le podeis descargar desde aquí.
Comenzamos por subir el archivo con extension JSON, en este caso lo llamaremos "Archivo.json". Para hacer la prueba, lo subí a dropbox, pero no os olvideis de cambiar las 3 www del enlace que conseguireis, por dl para tener el acceso público, de todas formas podreis ver el ejemplo en una de las clases.
Como profesionales que somos, he usado dropbox para el ejemplo, pero los programadores debemos huir literalmente de lo "gratis", lo que no se paga, tiene una seguridad endeble, entre otras desventajas.
También he subido estas imágenes a un servidor gratuito TinyPic, quiere decir que podeis usar el mismo archivo JSON que yo.
IMAGENES
Orco
Elfo
humano
Importamos estas librerías al proyecto para poder usar JSON :
- gson-1.7.1.jar
- gson-1.7.1-javadoc.jar
- gson-1.7.1-sources.jar
- ksoap2-android-assembly-22.5.8-jar-with-depencies.jar
Tendremos que guardar los datos en una clase JavaBeans, así que creamos la correspondiente a nuestro archivo JSON para trabajar y gestionar los objetos :
public class Personajes { private String nombre; private String profesion; private String equipo; private String Fuerza; private String Fortaleza; private String Espiritu; private String URLimagen; public Bitmap imagen; public Personajes() { super(); } public String getEquipo() { return equipo; } public void setEquipo(String equipo) { this.equipo = equipo; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getProfesion() { return profesion; } public void setProfesion(String profesion) { this.profesion = profesion; } public String getFuerza() { return Fuerza; } public void setFuerza(String fuerza) { Fuerza = fuerza; } public String getFortaleza() { return Fortaleza; } public void setFortaleza(String fortaleza) { Fortaleza = fortaleza; } public String getEspiritu() { return Espiritu; } public void setEspiritu(String espiritu) { Espiritu = espiritu; } public String getURLimagen() { return URLimagen; } public void setURLimagen(String uRLimagen) { URLimagen = uRLimagen; } public Bitmap getImagen() { // TODO Auto-generated method stub return imagen; } }
Ahora vamos con el código, pongo a continuación las dos partes del main :
Y este es el código Java de momento :
public class MainActivity extends Activity { private Button buscar; private ListView listaa; String searchTerm ; //SI OS FIJAIS LA URL EMPIEZA POR dl EN VEZ DE www String URL = "https://dl.dropbox.com/s/sjhj5zuxfu87vz5/Archivo.json?dl=0"; Activity a; Context context; static ArrayListlista; JSONArray pers; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lista = new ArrayList (); a=this; context=getApplicationContext(); listaa = (ListView) findViewById(R.id.listViewLista); buscar = (Button) findViewById(R.id.busqueda); //VEMOS QUE HAY EN EL EDITTEXT buscar.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub //AQUI ES LA EJECUCIÓN DEL PARSEO DEL XML } }); } }
A continuación tenemos el método público que utilizaremos para leer nuestro archivo JSON. Este método crea la llamada al servicio web. No os olvideis de darle permisos de internet a la aplicación.
//CLASE PARA RECOJER EL CODIGO EN BRUTO DEL JSON public class JSONParser { static String response = null; public final static int GET = 1; public final static int POST = 2; //CONSTRUCTOR public JSONParser() { } public String makeServiceCall(String url, int method) { return this.makeServiceCall(url, method, null); } //METODO PARA ESTABLECER CONEXIÓN public String makeServiceCall(String url, int method,Listparams) { try { //HTTP CLIENT DefaultHttpClient httpClient = new DefaultHttpClient(); HttpEntity httpEntity = null; HttpResponse httpResponse = null; // AÑADIMOS PARAMETROS AL METODO POST if (method == POST) { HttpPost httpPost = new HttpPost(url); // adding post params if (params != null) { httpPost.setEntity(new UrlEncodedFormEntity(params)); } httpResponse = httpClient.execute(httpPost); } else if (method == GET) { // AÑADIMOS PARAMETROS AL METODO GET if (params != null) { String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; } //METODO GET HttpGet httpGet = new HttpGet(url); httpResponse = httpClient.execute(httpGet); } httpEntity = httpResponse.getEntity(); response = EntityUtils.toString(httpEntity); //EXCEPCIONES } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //DEVOLVEMOS RESPUESTA return response; } }
Vamos a completar nuestro main con 2 clases que harán la función de hilos, uno es para cargar los datos del objeto JSON en un ArrayList y otro es para cargar los datos correspondientes en el ListView, están enlazados y el código está bastante explicado e intuitivo.
//HILO PARA CARGAR LOS DATOS DEL JSON EN UN ARRAYLIST class GetContacts extends AsyncTask{ ListView list; private ProgressDialog pDialog; //CONSTRUCTOR public GetContacts(ListView listaa) { this.list=listaa; } @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage("Getting Data ..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } @Override protected Void doInBackground(Void... arg0) { // CREAMOS LA INSTANCIA DE LA CLASE JSONParser sh = new JSONParser(); String jsonStr = sh.makeServiceCall(URL, JSONParser.GET); if (jsonStr != null) { try { JSONObject jsonObj = new JSONObject(jsonStr); // Getting JSON Array node pers = jsonObj.getJSONArray("Personajes"); // looping through All Equipos for (int i = 0; i < pers.length(); i++) { JSONObject c = pers.getJSONObject(i); //RECOJEMOS DATOS EN VARIABLES String equipo = c.getString("Equipo"); String name = c.getString("name"); String especialidad = c.getString("Especialidad"); String imagen = c.getString("image"); //SUBITEM CON LAS HABILIDADES JSONObject habilidades = c.getJSONObject("Habilidades"); String fuerza = habilidades.getString("Fuerza"); String espiritu = habilidades.getString("Espiritu"); String fortaleza = habilidades.getString("Fortaleza"); //CREAMOS OBJETO Y LO LLENAMOS Personajes e=new Personajes(); e.setURLimagen(imagen); e.setNombre(name); e.setEquipo(equipo); e.setProfesion(especialidad); e.setEspiritu(espiritu); e.setFortaleza(fortaleza); e.setFuerza(fuerza); // adding contact to contact list lista.add(e); } } catch (JSONException e) { e.printStackTrace(); } } else { Log.e("ServiceHandler", "Esta habiendo problemas para cargar el JSON"); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); // Dismiss the progress dialog if (pDialog.isShowing()){ pDialog.dismiss(); } new CargarListTask().execute(); } //HILO PARA CARGAR LOS DATOS EN EL LISTVIEW class CargarListTask extends AsyncTask { @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); } protected Adapter doInBackground(Void... arg0) { // TODO Auto-generated method stub try{ }catch(Exception ex){ ex.printStackTrace(); } Adapter adaptador = new Adapter(a,lista); return adaptador; } @Override protected void onPostExecute(Adapter result) { // TODO Auto-generated method stub super.onPostExecute(result); listaa.setAdapter(result); } } }
Si colocamos cuando clickamos el botón...
new GetContacts(listaa).execute();
Ya está!! sólo necesitamos un adapter con un hilo, este hilo se encargará de llenar la imágen a partir de la URL de la imagen, de esas 3 que he puesto al principio :
public class Adapter extends BaseAdapter{ protected Activity activity; //ARRAYLIST CON TODOS LOS ITEMS protected ArrayListitems; //CONSTRUCTOR public Adapter(Activity activity, ArrayList items) { this.activity = activity; this.items = items; } //CUENTA LOS ELEMENTOS @Override public int getCount() { return items.size(); } //DEVUELVE UN OBJETO DE UNA DETERMINADA POSICION @Override public Object getItem(int arg0) { return items.get(arg0); } //METODO PRINCIPAL, AQUI SE LLENAN LOS DATOS @Override public View getView(int position, View convertView, ViewGroup parent) { // SE GENERA UN CONVERTVIEW POR MOTIVOS DE EFICIENCIA DE MEMORIA //ES UN NIVEL MAS BAJO DE VISTA, PARA QUE OCUPEN MENOS MEMORIA LAS View v = convertView; //ASOCIAMOS LA VISTA AL LAYOUT DEL RECURSO XML DONDE ESTA LA BASE DE if(convertView == null){ LayoutInflater inf = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = inf.inflate(R.layout.list_item, null); } Personajes dir = items.get(position); //RELLENAMOS LA IMAGEN Y EL TEXTO //IMAGEN ImageView img = (ImageView) v.findViewById(R.id.imageView1); if(img != null) { new LoadImage(img).execute(dir.getURLimagen()); } //CAMPOS TextView nombre = (TextView) v.findViewById(R.id.username); nombre.setText("NOMBRE : "+dir.getNombre()); TextView clase = (TextView) v.findViewById(R.id.clase); clase.setText("PROFESION : "+dir.getProfesion()); TextView equipo = (TextView) v.findViewById(R.id.equipo); equipo.setText("EQUIPO : "+dir.getEquipo()); TextView fuerza = (TextView) v.findViewById(R.id.fuerza); //SUBCAMPOS fuerza.setText("FUERZA : "+dir.getFuerza()); TextView fortaleza = (TextView) v.findViewById(R.id.fortaleza); fortaleza.setText("FORTALEZA : "+dir.getFortaleza()); TextView espiritu = (TextView) v.findViewById(R.id.espiritu); espiritu.setText("ESPIRITU : "+dir.getEspiritu()); // DEVOLVEMOS VISTA return v; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } class LoadImage extends AsyncTask { ImageView bmImage; public LoadImage(ImageView bmImage) { this.bmImage = bmImage; } @Override protected Bitmap doInBackground(String... urls) { String urldisplay = urls[0]; Bitmap mIcon11 = null; try { mIcon11 = BitmapFactory.decodeStream((InputStream)new URL(urldisplay).getContent()); } catch (Exception e) { //Log.e("Error", e.getMessage()); e.printStackTrace(); } return mIcon11; } @Override protected void onPostExecute(Bitmap result) { bmImage.setImageBitmap(result); } } }
Y por último el item_list....
Podeis descargar el código fuente de thebestandroide con sólo compartir en facebook,twitter,linkedin o suscribirte a nuestro canal RSS más abajo.
Buenas, tengo una duda, tu codigo me funciona correctamente, pero cuando utilizo mi JSON que esta en un host gratuito al ejecutarlo no me sale nada en mi avd, si me pudieras ayudar, no entra en doInBackground directamente sale "Esta habiendo...."
ResponderEliminarMuchas gracias
Buenas! Mira puede ser por dos cosas :
Eliminar-Por ejemplo en dropbox que es un servidor gratuito, para hacer el archivo público hay que cambiar las www por dl en la ruta que le metes a la clase java para leer el JSON.
-Otra causa y las más probable, es que hayas cambiado la extuctura del JSON adaptandolo a tus necesidades y ahí este el jaleo. No obstante, si me pudieras poner el link de tu JSON y echarlo un ojo, te podría ayudar mejor.
Saludos
Gracias por responder tan rápido, parece que puede ser un problema de convertir JsonArray a JsonObject, es uno de los warning que me da, ya que no me muestra los datos, sin embargo en el LogCat si que veo que aparecen.
EliminarTe envio el enlace:
http://www.bdmacotera.besaba.com/bdMacoteraConecta/db.php
Si necesitas el codigo es este:
$id, 'nombre'=> $nombre, 'telefono'=> $telefono, 'direccion'=> $direccion,
'horario'=> $horario);
}
//desconectamos la base de datos
$close = mysqli_close($conexion)
or die("Ha sucedido un error inexperado en la desconexion de la base de datos");
//Creamos el JSON
$json_string = json_encode($organismos, JSON_FORCE_OBJECT);
echo $json_string;
//Si queremos crear un archivo json, sería de esta forma:
/*
$file = 'organismos.json';
file_put_contents($file, $json_string);
*/
?>
$id, 'nombre'=> $nombre, 'telefono'=> $telefono, 'direccion'=> $direccion,
Eliminar'horario'=> $horario);
}
//desconectamos la base de datos
$close = mysqli_close($conexion)
or die("Ha sucedido un error inexperado en la desconexion de la base de datos");
//Creamos el JSON
$json_string = json_encode($organismos, JSON_FORCE_OBJECT);
echo $json_string;
//Si queremos crear un archivo json, sería de esta forma:
/*
$file = 'organismos.json';
file_put_contents($file, $json_string);
*/
?>
No se porque no me deja poner el codigo entero....
EliminarTe pongo uno de los errores que me aparecen: org.json.JSONException: No value for Servicios
https:/dl.dropbox.com/s/zeejgy8493z8vzs/db.php?dl=0
Esto viene de la parte de codigo:
// Getting JSON Array node
pers = jsonObj.getJSONArray("Servicios");
Buenas!!! Hace mucho que no toco .php pero más o menos entiendo que pone =)
EliminarOk, no te dejará postear el código porque tendrán los de blogger un minimo de seguridad para la inyección por código javascript.
Respecto a este enlace :
http://www.bdmacotera.besaba.com/bdMacoteraConecta/db.php
Es lo que te comentaba, adaptandolo a tus necesidades has cambiado la jerarquia de Objects y Arrays, te paso un JSON con la jerarquía correcta para que lo amoldes, o por el contrario, modifiques tu clase Java con el tuyo.
https://www.dropbox.com/s/14tbosysfstsb3d/productos.json?dl=0
Pienso que el problema está en que donde en mi json si te das cuenta pone Productos, englosa toda la categoría, mientras que en el tuyo pones numeros como 0,1,2.... englosa una categoria a un objeto, y algo se debe rallar en el bucle for siguiente. Vamos, en una explicación normal, el mio coge un array y después recoge objetos, en el tuyo por el contrario, tienes un array lleno de arrays... Dios, como cuesta explicarse a estas horas!
Espero haberte sido de ayuda,
Saludos!
Y por cierto, para ayudarte a resolver el problema, te recomiendo que uses https://www.jsoneditoronline.org/ que es un editor online de JSON, seguro que te ahorra más de un rato en la construcción del JSON!
EliminarMuchas gracias, probare y ya te contare...:D
EliminarBuenas de nuevo Makone, al utilizar como base tu código y modificar el JSON que me pasaste, lo he modificado para que me muestre mis datos, al ejecutar en el emulador me sale el siguiente mensaje:
Eliminar05-27 18:10:58.976 4913-4913/? E/dalvikvm﹕ could not disable core file generation for pid 4913: Operation not permitted
Sin embargo con el tuyo sigo sin tener problemas...aunque tambien me aparece un mensaje similar.
No veo diferencias entre código, el tuyo sigue mostrándome tus datos pero el mio se queda en blanco.
buen tutorial :D
ResponderEliminarEn primer lugar darte las gracias y la enhorabuena por el tutorial.
ResponderEliminarGracias a el he aprendido a usar Android y JSON juntos.
Estoy desarrollando una aplicación y tengo el siguiente problema:
Cuando obtengo las imágenes del archivo JSON colgadas en mi dropbox, se ve en la interfaz del teléfono o del emulador como las imágenes recorren todas la primera posición del array, y una vez que han pasado por todas imagens, entonces empiezan a colocarse cada una en el lugar que le corresponde. En vez de colocarlas directamente, como el resto de los datos (nombre, edad, etc.)
Me gustaría que me ayudes a resolver mi problema.
Muchas gracias de antemano, Salu2.
Buenos días, muy buena página. Tengo una duda. Quiero hacer un proyecto que en lugar de llamar al archivo json desde un servidor remoto lo tenga incluido dentro de una de las carpetas del proyecto. Necesito saber como se hace.
ResponderEliminarSaludos a todos
Excelente información!, lo compilé en Android Studio y funcionó de inmediato.
ResponderEliminarHola, saludos
ResponderEliminaren primer lugar quisiera felicitar y agradecer por el material entregado, es claro y fácil de entender.
Solo tengo una duda, no puedo descargar el ejemplo, no se si me puedes ayudar con esto. gracias.
Hola, saludos
ResponderEliminaren primer lugar quisiera felicitar y agradecer por el material entregado, es claro y fácil de entender.
Solo tengo una duda, no puedo descargar el ejemplo, no se si me puedes ayudar con esto. gracias.
Buenos dias me podrias ayudar con el ejmeplo.
ResponderEliminarBuen dia, mucas gracias por el codigo
ResponderEliminary los enlaces de descarga el proyecto?
ResponderEliminarbuen dia, por favor quisiera saber porque ocurre este error
ResponderEliminarUnterminated string at character 50000 of {"ObjListaTalleres":[{"CODHOR������������������������������������������������������
Afyon
ResponderEliminarAntalya
Erzurum
Mersin
izmir
DMYJ
Malatya
ResponderEliminarKırıkkale
Aksaray
Bitlis
Manisa
ZRK
ankara
ResponderEliminarsakarya
tekirdağ
kastamonu
amasya
0KG2CR
whatsapp görüntülü show
ResponderEliminarücretli.show
3HOXHR
görüntülü.show
ResponderEliminarwhatsapp ücretli show
CM3ZC
https://istanbulolala.biz/
ResponderEliminarSH81S
şırnak evden eve nakliyat
ResponderEliminarçankırı evden eve nakliyat
nevşehir evden eve nakliyat
antalya evden eve nakliyat
artvin evden eve nakliyat
0XMY
karabük evden eve nakliyat
ResponderEliminarbartın evden eve nakliyat
maraş evden eve nakliyat
mersin evden eve nakliyat
aksaray evden eve nakliyat
XQUAM
muş evden eve nakliyat
ResponderEliminarçanakkale evden eve nakliyat
uşak evden eve nakliyat
ardahan evden eve nakliyat
eskişehir evden eve nakliyat
XN3ZXT
B7FCD
ResponderEliminarVindax Güvenilir mi
Binance Referans Kodu
Kars Evden Eve Nakliyat
Ünye Oto Elektrik
Malatya Şehirler Arası Nakliyat
Kırşehir Şehirler Arası Nakliyat
Hakkari Şehir İçi Nakliyat
Samsun Şehir İçi Nakliyat
Tekirdağ Fayans Ustası
15895
ResponderEliminarcanlı görüntülü sohbet odaları
kocaeli ücretsiz sohbet
nevşehir rastgele sohbet
Karabük Sesli Sohbet
tunceli canlı sohbet odaları
canlı sohbet sitesi
Afyon Telefonda Rastgele Sohbet
muş en iyi sesli sohbet uygulamaları
nevşehir sesli mobil sohbet
4536B
ResponderEliminarığdır Rastgele Görüntülü Sohbet Uygulaması
istanbul rastgele canlı sohbet
kars en iyi ücretsiz sohbet siteleri
Samsun Mobil Sesli Sohbet
Antep Ücretsiz Sohbet Odaları
antep canlı sohbet odası
Ağrı Canlı Sohbet Siteleri
Burdur Görüntülü Sohbet Siteleri
sesli sohbet odası
hgfjhngfyutjytuj
ResponderEliminarشركة عزل اسطح بالقطيف