Ratio: 0 / 5

Inicio desactivadoInicio desactivadoInicio desactivadoInicio desactivadoInicio desactivado
 

En este artículo vamos a ver lo básico de como completar un listview con datos obtenidos desde una tabla en nuestro server PHP con MySQL. Nuestro listview contrendrá íconos que se bajarán desde la web y se almacenarán en nuestra SD Card a modo de caché. Esto es para disminuir el trafico de datos desde/hacia nuestro server y acelerar la ejecución de nuestra app en el dispositivo del usuario.

 

Este ejemplo esta orientado a obtener una cantidad relativamente baja de filas desde MySQL. Es decir, no está pensado para resultados MySQL de cientos o miles de filas, ya que no limita la cantidad de filas a mostrar. Si esto pasara, cargaríamos demasiado innecesariamente nuestro server y el dispositivo del usuario. Para qué traer de una sola vez un resultado de 2000 filas, si el usuario verá pocas filas en su pantalla al mismo tiempo? En próximo articulo trabajaremos sobre este punto.

Simularemos un menú online de un restaurant. Como siempre, no se busca la eficiencia del código, sino mostrar cómo hacerlo. Al final del artículo en la sección de adjuntos, está el proyecto completo para exportar.

En la primer parte de estos artículos, prepararemos lo básico para la ejecución de nuestra app.

Para este desarrollo mi entorno es:

  • Android Development Toolkit Version: 22.6.2.v201403212031-1085508
  • Un equipo Windows con XAMPP

Este último nos implica un pequeño problema con las codificaciones. Para trabajar correctamente con JSON (para devolver los datos a nuestra app) lo debemos hacer en UTF8. Por defecto la instalación de XAMPP en Windows no utiliza UTF8. En mi caso, tengo aplicaciones funcionando en ese equipo con MySQL, por lo cual no puedo, fácilmente, modificar las variables globales de MySQL. Esto nos implicará luego dar un poco de vueltas con los ENCODE y COLLATIONS. Si donde almacenamos los datos es un equipo con Linux, estos problemas son mucho menores. :D

La IP de mi server es 192.168.5.141

Comenzamos trabajando sobre el lado de nuestro server.

MySQL

Creamos una base de datos que llamaremos phplistview.

Tendremos dos tablas. La primera con los datos de cada cosa que vendemos, y la segunda, para las categorias (bebidas, minutas, carnes, etc). Este es el dump desde phpmyadmin para la creación de las tablas y para llenarlas con algunos datos.

-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `tbl_categorias`
--
CREATE TABLE IF NOT EXISTS `tbl_categorias` ( `id_categoria` int(11) NOT NULL AUTO_INCREMENT, `categoria` varchar(45) DEFAULT NULL, PRIMARY KEY (`id_categoria`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
--
-- Volcado de datos para la tabla `tbl_categorias`
--
INSERT INTO `tbl_categorias` (`id_categoria`, `categoria`) VALUES (1, 'Pastas'), (2, 'Postres'), (3, 'Carnes'), (4, 'Bebidas'), (5, 'Minutas');
--
--------------------------------------------------------
--
-- Estructura de tabla para la tabla `tbl_comidas`
--
CREATE TABLE IF NOT EXISTS `tbl_comidas` ( `id_comida` int(11) NOT NULL AUTO_INCREMENT, `categoria` int(11) NOT NULL, `comida` varchar(25) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `descripcion` varchar(250) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `calificacion` tinyint(4) NOT NULL, `imagen` varchar(250) NOT NULL, `precio` decimal(10,2) NOT NULL, PRIMARY KEY (`id_comida`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=13 ; --
-- Volcado de datos para la tabla `tbl_comidas`
--
INSERT INTO `tbl_comidas` (`id_comida`, `categoria`, `comida`, `descripcion`, `calificacion`, `imagen`, `precio`) VALUES (1, 1, 'Tallarines', NULL, 3, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/tallarines.jpg', 25.00), (2, 5, 'Sandwich mediterráneo', 'Aceitunas, jamón crudo, queso, aceite de oliva', 5, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/sandwichmediterraneo.png', 40.45), (3, 3, 'Vacío a la leña', NULL, 4, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/vacio.png', 100.02), (4, 2, 'Don Pedro', 'Helado granizado con whisky', 2, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/donpedro.jpg', 33.00), (5, 4, 'Fernet con coca', NULL, 5, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/fernet.png', 23.00), (6, 3, 'Milanesas rellenas', 'Milas rellenas con jamón,queso y morron', 3, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/milarellena.jpg', 50.60), (7, 1, 'Ñoquis de ricota', NULL, 4, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/noquis.jpg', 4.00), (8, 2, 'Helado de vainilla', 'Dos bochas de helado', 1, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/bochashelado.jpg', 23.00), (9, 4, 'Vino de la casa', '3/4 tinto', 1, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/vino.jpg', 2.00), (12, 5, 'Picada de quesos', 'Varios quesos', 4, 'http://probando-cosas.com.ar/deposito/android/img/listviewphpmysql/quesos.png', 15.00);

Detalle a tener en cuenta. Vemos en la estructura de la tabla tbl_comidas, que los campos comida y descripcion especificamos CHARACTER SET utf8 COLLATE utf8_bin. Si utilizamos utf8_general_ci (ci, de case insentive), MySQL no diferenciará entre n, N, ñ o Ñ. Es decir, que si ejecutamos la siguiente consulta


select * from tbl_comidas where comida like '%ñ%';

Obtendremos resultados tales como Ñoquis, carne, vainilla. En mi caso, los quería diferenciar específicamente este tipo de búsquedas. Se puede jugar con el set de caracteres y collations para que se ajuste al comportamiento que deseamos. Sólo hay que tener el cuidado de mantenernos en UTF8.

PHP

En nuestro equipo, dentro del document_root de apache, creamos la carpeta comidas que es donde alojaremos nuestro archivo que se encargará de recibir las consultas de nuestra app y le devolverá los resultados. En mi instalación, el paso completo sería:


C:\xampp\htdocs\comidas\consultas.php

Para facilitar el diagnóstico en caso de error, usaremos GET para enviar los datos para consulta.


<?php
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding("UTF-8");
$host = "localhost";
$db = "phplistview";
$user = "usuarioMYSQL";
$pwd = "passwdMYSQL";
//
Crear conexion $con = mysqli_connect($host, $user, $pwd, $db);
/* cambiar el conjunto de caracteres a utf8
*/
if (!$con->set_charset("utf8")) {
   printf("Error cargando el conjunto de caracteres utf8: %s\n", $con->error);
} else {
   // Para diagnosticar si algo anda mal con la codificación
   //printf("Conjunto de caracteres actual: %s\n", $con->character_set_name());
   //echo "<br>";
}
$con->query('SET NAMES utf8');
// verifica conexion
if(mysqli_connect_errno($con)) {
   die("Error al conectarse con MySQL: " . mysqli_connect_error());
}
$COMIDA=$_GET['comida'];
$query = "SELECT tbl_comidas.id_comida as id_comida, tbl_comidas.comida as comida, tbl_comidas.descripcion as descripcion, tbl_comidas.calificacion as calificacion, tbl_comidas.imagen as imagen, tbl_comidas.precio as precio, tbl_categorias.categoria FROM `tbl_comidas`, tbl_categorias WHERE tbl_comidas.categoria=tbl_categorias.id_categoria and (UPPER (comida) LIKE UPPER ('%".$COMIDA."%') OR UPPER (`descripcion`) LIKE UPPER ('%".$COMIDA."%')) ";
#Verificamos si hay filtrado por categoria ... si lo hay, agregamos la condición
if (!empty($_GET['categoria'])){
   $query=$query." and tbl_categorias.id_categoria = ".$_GET['categoria'];
}
$result = mysqli_query($con, $query) or die (mysqli_error($con)."<br>".$query);
// Salvamos los datos en un array
$final_data = array();
if ($query_run = mysqli_query($con,$query)){
   $i=0;
   while($query_row = mysqli_fetch_assoc($query_run)){
      $id_comida = utf8_encode($query_row ['id_comida']);
      $comida = utf8_encode($query_row ['comida']);
      $descripcion = utf8_encode($query_row ['descripcion']);
      $calificacion = utf8_encode($query_row ['calificacion']);
      $imagen = utf8_encode($query_row ['imagen']);
      $precio = utf8_encode($query_row ['precio']);
      $categoria = utf8_encode($query_row ['categoria']);
      $data = array('id_comida'=>$id_comida, 'comida'=>$comida, 'descripcion'=>$descripcion, 'calificacion'=>$calificacion, 'imagen'=>$imagen, 'precio'=>$precio, 'categoria'=>$categoria );
      $final_data[$i]=$data; $i++;
   }
   print(json_encode($final_data));
}else{
   echo mysql_error();
}
// Cerrar la conexion mysqli_close($con);
?>

Detalle. Notemos en la consulta:


... and (UPPER (comida) LIKE UPPER ('%".$COMIDA."%') OR UPPER (`descripcion`) LIKE UPPER ('%".$COMIDA."%')) ...

Habíamos especificado en la definición de la tabla que usaríamos utf8_bin. Esto significa que se diferenciará entre mayúsculas y minúsculas. Por lo que si estamos buscando "ñ" nos devolverá añejo, pero no encontrará Ñoquis.

Para resolver esto agregamos los UPPER en la consulta. Lo que hacemos es convertir el parámetro a buscar y los campos a mayúsculas. Es decir buscaremos Ñ en AÑEJO y en ÑOQUIS

Ahora vamos a probar si está funcionando todo correctamente en este punto.

En cualquier browser:


http://192.168.5.141/comidas/consultas.php?


[{"id_comida":"1","comida":"Tallarines","descripcion":"","calificacion":"3","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/tallarines.jpg","precio":"25.00","categoria":"Pastas"},{"id_comida":"7","comida":"\u00c3\u0091oquis de ricota","descripcion":"","calificacion":"4","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/noquis.jpg","precio":"4.00","categoria":"Pastas"},{"id_comida":"4","comida":"Don Pedro","descripcion":"Helado granizado con whisky","calificacion":"2","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/donpedro.jpg","precio":"33.00","categoria":"Postres"},{"id_comida":"8","comida":"Helado de vainilla","descripcion":"Dos bochas de helado","calificacion":"1","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/bochashelado.jpg","precio":"23.00","categoria":"Postres"},{"id_comida":"3","comida":"Vac\u00c3\u00ado a la le\u00c3\u00b1a","descripcion":"","calificacion":"4","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/vacio.png","precio":"100.02","categoria":"Carnes"},{"id_comida":"6","comida":"Milanesas rellenas","descripcion":"Milas rellenas con jam\u00c3\u00b3n,queso y morron","calificacion":"3","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/milarellena.jpg","precio":"50.60","categoria":"Carnes"},{"id_comida":"5","comida":"Fernet con coca","descripcion":"","calificacion":"5","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/fernet.png","precio":"23.00","categoria":"Bebidas"},{"id_comida":"9","comida":"Vino de la casa","descripcion":"3\/4 tinto","calificacion":"1","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/vino.jpg","precio":"2.00","categoria":"Bebidas"},{"id_comida":"2","comida":"Sandwich mediterr\u00c3\u00a1neo","descripcion":"Aceitunas, jam\u00c3\u00b3n crudo, queso, aceite de oliva","calificacion":"5","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/sandwichmediterraneo.png","precio":"40.45","categoria":"Minutas"},{"id_comida":"12","comida":"Picada de quesos","descripcion":"Varios quesos","calificacion":"4","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/quesos.png","precio":"15.00","categoria":"Minutas"}]


http://192.168.5.141/comidas/consultas.php?comida=oqui


[{"id_comida":"7","comida":"\u00c3\u0091oquis de ricota","descripcion":"","calificacion":"4","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/noquis.jpg","precio":"4.00","categoria":"Pastas"}]


http://192.168.5.141/comidas/consultas.php?categoria=5

[{"id_comida":"2","comida":"Sandwich mediterr\u00c3\u00a1neo","descripcion":"Aceitunas, jam\u00c3\u00b3n crudo, queso, aceite de oliva","calificacion":"5","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/sandwichmediterraneo.png","precio":"40.45","categoria":"Minutas"},{"id_comida":"12","comida":"Picada de quesos","descripcion":"Varios quesos","calificacion":"4","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/quesos.png","precio":"15.00","categoria":"Minutas"}]


http://192.168.5.141/comidas/consultas.php?categoria=5&comida=medi

[{"id_comida":"2","comida":"Sandwich mediterr\u00c3\u00a1neo","descripcion":"Aceitunas, jam\u00c3\u00b3n crudo, queso, aceite de oliva","calificacion":"5","imagen":"http:\/\/joomla.probando-cosas.com.ar\/images\/deposito\/android\/listiviewphpmysql\/sandwichmediterraneo.png","precio":"40.45","categoria":"Minutas"}]

La segunda parte : Android: Listview con búsqueda con SearchView + PHP + MySQL + Imágenes + Cache (parte 2)


FacebookMySpaceTwitterDiggDeliciousStumbleuponGoogle BookmarksRedditNewsvineTechnoratiLinkedinRSS FeedPinterest
Pin It