domingo, 14 de junio de 2015

Tutorial: Cómo conectarse a MySQL desde Android con XAMPP


El presente tutorial tiene como objetivo explicar cómo llevar a cabo la conexión a una base de datos MySQL desde una aplicación Android. La aplicación de ejemplo va a realizar algo bastante sencillo. Al introducir el nombre de una videoconsola y el nombre del juego, va a devolver su género, valoración, PEGI y su precio.

Para ello se ha de tener acceso y privilegios de administrador de una base de datos MYSQL, para lo que en este caso se va a utilizar XAMPP. Las siglas provienen de: X para cualquier sistema operativo, A de Apache, M de MySQL, P de PHP y P de Perl. 

No se va a detallar en este tutorial la instalación de XAMPP, pero puede seguirse fácilmente aquí o aquí. XAMPP permite el uso del pc como servidor y además proporciona una base de datos MySQL que es justo lo que necesitamos.



Configuración de la base de datos


Lo primero que hemos de hacer si queremos acceder a la base de datos es crearla. Para ello hay que lanzar el servidor Apache y MySQL desde XAMPP. Puede comprobarse su funcionamiento desde el panel de control de XAMPP:


Figura 1. XAMPP Control Panel

Para poder entrar en el servidor sólo hay que poner en la barra de direcciones del buscador la dirección:

 >> http://localhost:8080/xampp

Donde como sabéis localhost puede sustituirse por la dirección 127.0.0.1 y 8080 es el puerto correspondiente al servidor Apache .Podría ser otro en función de la configuración, por lo que es importante comprobar desde el panel de control qué puerto tiene asignado.

La página de inicio de XAMPP es la siguiente:


 Figura 2. Página inicio XAMPP

En la figura 2 aparece marcado en un recuadro negro, justo debajo de tools, “phpMyAdmin”. Esta es la herramienta que permite configurar las diferentes bases de datos MySQL desde el entorno web. Por supuesto podría hacerse desde la consola, pero por simplicidad en este tutorial se va a usar phpMyAdmin.

Al pinchar en phpMyAdmin se accede a la página de configuración de bases de datos MySQL:

Figura 3. phpMyAdmin

A la izquierda de la figura 3 se tienen todas las bases de datos existentes en el servidor. En mi caso ya se tienen configuradas algunas pero se va a crear otra a modo de ejemplo. Para ello, a la derecha de phpMyAdmin aparecen una serie de pestañas. Pinchamos en “Bases de datos” y llegaremos  al siguiente menú de configuración:


 Figura 4. Bases de datos phpMyAdmin

En donde aparece claramente una caja de texto para crear una nueva base de datos. Únicamente debemos especificar el nombre y darle a “Crear”. Dejamos por defecto el otro recuadro en “Cotejamiento”. El nombre de la base de datos de este ejemplo va a ser “videoconsolas”. 
Al pinchar en “Crear” dirá que se ha creado correctamente. Ahora hay que configurarla. Pinchamos en la base de datos creada, en donde tendremos que crear una tabla por cada videoconsola que queramos tener en nuestra base de datos. En este caso se van a crear 2: New Nintendo3DS y Xbox360:

Figura 5. Creación de una tabla en la BD

El número de columnas indica el número de campos que va a tener cada videojuego. En nuestro caso serán 5 (nombre, género, valoración, PEGI y precio). Al darle a “continuar” aparece la configuración de las columnas de la tabla:


Figura 6. Configuración de la tabla

La figura 6 muestra las 5 columnas y sus tipos y longitudes asociadas. Los campo “nombre” y “genero” serán de tipo VARCHAR (cadenas de longitud variable) mientras que “valoración” y “precio” son de tipo decimal (FLOAT) y por último PEGI de tipo INT. Es importante saber qué tipo de variable tiene asociada cada columna ya que  más tarde llamaremos a un método u otro en función del tipo para acceder a la información. El resto de parámetros los dejamos por defecto y pinchamos en “Guardar”.

Lo siguiente es añadir un par de juegos con los que probar la aplicación. Desde la pestaña estructura podremos acceder ahora a la tabla. Al pinchar aparecerá un mensaje diciendo que MySQL ha devuelto un conjunto de valores vacío (lógico, aún no hemos agregado ningún juego). Para insertar una nueva entrada le damos a la pestaña “Insertar”, y llegaremos a la siguiente página:

Figura 7. Añadiendo una entrada a la tabla

En este caso se han añadido los juegos FIFA 15 y Monster Hunter 4. La figura 7 muestra cómo se puede añadir un juego, concretamente el FIFA 15. Sólo hay que indicar los valores y darle a “Continuar”. Ya se tiene el juego añadido a la tabla “new nintendo3ds” dentro de “videoconsolas”. Si ahora pinchamos en la pestaña “Examinar” aparecen las 2 entradas. 
Después de esto ya se tendría la base de datos lista.


Acceso a la base de datos desde la aplicación


Ahora sí, ya estamos en condiciones de obtener información de la base de datos desde nuestra aplicación. Creamos el proyecto en Android Studio al que vamos a llamar “ejemploConexionBaseDatos”. Sólo nos va a hacer falta una clase, “MainActivity”. En cuanto al layout, está disponible junto con todo el proyecto en mi repositorio de GitHub que encontraréis al final del tutorial.

Lo que se va a utilizar para realizar a cabo la conexión con la base de datos es JDBC (Java DataBase Connectivity). Es una API que permite la ejecución de operaciones sobre bases de datos desde JAVA. Para más información acerca de la misma puedes hacer click aquí. Primero hay que descargarse el .jar correspondiente a la API desde su página

Para cargar la librería en Android Studio vamos a Project > [aplicación] > libs y pegamos el .jar en ese directorio. Después tenemos que añadir la siguiente línea en Gradle Scripts > build.gradle (Module:app), en el apartado de dependencies:

 >> compile files('mysql-connector-java-3.0.17-ga-bin.jar')

NOTA: Hay que poner el nombre de .jar descargado. En el momento de hacer este tutorial yo tenía la versión 3.0.17, pero esto puede cambiar (y de hecho ha cambiado) así es importante poner el nombre correctamente.

Una vez hecho esto ya podemos acceder a los métodos que nos hacen falta para realizar la conexión, pero eso será más tarde.

Lo primero que hacemos en el método OnCreate() es buscar las referencias de los elementos del layout previamente instanciados:

etNombre = (EditText)findViewById(R.id.etNombre);
etVideoconsola = (EditText)findViewById(R.id.etVideoconsola);
tvGenero = (TextView)findViewById(R.id.tvGenero);
tvValoracion = (TextView)findViewById(R.id.tvValoracion);
tvPEGI = (TextView)findViewById(R.id.tvPEGI);
tvPrecio = (TextView)findViewById(R.id.tvPrecio);
btnConectar = (Button)findViewById(R.id.btnConectar);


Además hay que añadir el listener al botón que realiza la petición sql:

btnConectar.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {

        String videoconsola = etVideoconsola.getText().toString();
        String juego = etNombre.getText().toString();

        if (videoconsola.equals("New Nintendo3DS")){
            videoconsola = "`" + videoconsola + "`";
        }
        new ConexionDB().execute(IP,baseDatos,videoconsola,juego);
    }
});

Vamos por partes. Primero obtenemos el datos de la videoconsola y el juego elegido por el usuario. El condicional se utiliza porque, cuando se quiere hacer una petición SQL del tipo:

SELECT * FROM tabla

Si “tabla” contiene espacios debe ponerse entre comillas francesas `. Por lo tanto, cuando el usuario ponga “New Nintendo3DS” se le deben añadir las comillas, en otro caso saltará una excepción SQL. Quedaría tal que así:

SELECT * FROM `New Nintendo3DS`

Además, desde el main de la interfaz de usuario no se permiten conexiones a la red, hay que hacerlo desde fuera del MainThread. Es por esto que se ha creado la clase ConexionDB que extiende a Asyntask, de modo que la acción se lleve a cabo fuera. La clase es la siguiente:

public class ConexionDB extends AsyncTask<String,Void,ResultSet>{

    @Override
    protected ResultSet doInBackground(String... strings) {

        try {
            Connection conn;
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://"+strings[0]+strings[1], "root", "");

            Statement estado = conn.createStatement();
            System.out.println("Conexion establecida");
            String peticion ="select * from " +strings[2]+" where nombre='"+strings[3]+"'";
            ResultSet result = estado.executeQuery(peticion);
            return result;
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(ResultSet result) {

        try {
            if (!result.next() ) {
                System.out.println("No data");
            }else{
                tvGenero.setText(result.getString("genero"));
                tvValoracion.setText(Float.toString(result.getFloat("valoracion")));
                tvPEGI.setText(Integer.toString(result.getInt("PEGI")));
                tvPrecio.setText(Float.toString(result.getFloat("precio")));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

}

Para el que no sepa qué es la clase Asyntask y cómo funciona, puede verlo aquí. La clase ConexiónDB recibe como parámetros un vector de Strings, que le pasa como argumento a doInBackGround. Este método a su vez devuelve ResultSet a OnPostExecute que es de tipo void. Pero vamos al funcionamiento:

- En doInBackground realizamos la conexión con la base de datos. El método Class.forName() carga la clase que recibe como argumento si no ha sido cargada previamente. Después creamos la conexión mediante el método getConnection de DriverManager. Este método recibe como argumento un primer String con el siguiente formato:

jdbc:mysql://[IP]:[puerto]/[nombre base de datos]

En este caso sería: 

jdbc:mysql://192.168.1.131:3306/videoconsolas

El segundo y tercer String hacen referencia al usuario y la contraseña para acceder a la base de datos. En este caso es el usuario y contraseña por defecto, “root” de usuario y nada (“ ”) de contraseña.

Lo siguiente es crear un “estado” que será el encargado de realizar la petición SQL. Esto se hace llamando al método createStatement() de la clase Connection.

Por último sólo queda formular la petición SQL en función de los datos introducidos por el usuario y recibir los resultados. Para ello se crea una instancia de la clase ResultSet que contiene dichos resultados.

- En el método OnPostExecute recogemos los datos devueltos y seleccionamos los que nos interesen. ResultSet contiene un listado de filas que cumplen la condición nombre=’strings[3]’, es decir, que si el nombre de un juego sólo aparece una vez el número de filas de ResultSet va a ser 1. Sin embargo, si lo que queremos es hacer un recorrido por la base de datos y no seleccionamos ningún elemento (juego) en concreto, debemos ir recorriendo el listado de filas con el método next() de ResultSet. Este método cambia el puntero de una fila a otra, de manera que si lo ejecutamos tal que asi:

While(result.next()){
//codigo a ejecutar
}

Podemos ir recorriendo cada una de las filas para obtener los datos que se deseen.

Volviendo a la aplicación, en nuestro caso sólo se tiene 1 fila en ResultSet, por lo que lo único que debemos hacer es obtener los campos género, valoración, PEGI y precio llamando a:

result.getString() // result.getInt() //….etc

y añadirlos a los diferentes TextView. El resultado final es este:


                                                                  Figura 8. Resultado

Consideraciones adicionales


1. Es necesario añadir permisos de conexión a internet en AndroidManifest para poder acceder a la base de datos. Para ello hay que añadir en ese documento la siguiente línea:

<uses-permission android:name="android.permission.INTERNET" />


2. Si se está utilizando XAMPP en una red de área local, primero hay que identificar cuál es la conexión IP del servidor. La mayoría de los routers utilizan el protocolo DHCP para proporcionar direcciones IP y NORMALMENTE asignan la misma dirección IP, dentro del rango del que disponen, cada vez que un equipo se conecta a dicha red. Sin embargo es muy posible que dicha dirección IP sea diferente si estas en una red diferente a la que habitualmente usas, por lo que es importante comprobarlo primero. 

3. Relacionado con el punto 2, si se utiliza un servidor XAMPP tienes que estar conectado a la misma red Wi-Fi que el servidor. Si, por ejemplo, se intenta utilizar la aplicación de ejemplo con la conexión de datos del móvil (no Wi-Fi) no encontrará nunca el servidor XAMPP. Esto se debe a que al utilizar la conexión de datos se asigna un rango de direcciones IP, por parte del operador de turno, diferente del rango de direcciones IP de la red local WiFi, y la red del operador no sabe qué dirección es la 192.168.x.x ya que es un rango de direcciones privadas.

4. Es posible que al intentar realizar la conexión no permita acceder a la base de datos porque faltan privilegios. En ese caso hay que ir a XAMPP > phpMyAdmin > [basededatos] > privilegios y añadir permisos para acceder desde otro host diferente al servidor que está ejecutando XAMPP.

El código y la aplicación de ejemplo pueden descargarse desde el siguiente repositorio de GitHub: repositorio GitHub

53 comentarios:

  1. Hola tengo una mega duda, soy nueva en esto y me arriesgue hacer una app con lo sig:

    Estoy desarollando una app que lee codigos qr (ya lo hace) y que tambien agregre, consulte y elimine datos desde la app a la base de datos que esta hecha en MySQLworkbench, no entiendo muy bien como desarrollar esa parte, lei y tengo que hacerlo con un webservices, espero me puedan orientar se los agradeceria. Saludos

    ResponderEliminar
    Respuestas
    1. La verdad es que no he utilizado MySQLworkbench, así que no puedo ayudarte. Lo siento =(

      Eliminar
    2. En MySQL Workbench se crea la BD de forma mas dinamica sin necesidad de codificar, simplemente se agregan las tablas y los campos, la exportas en .sql y la puedes agregar desde PHPMyAdmi para procesarla de forma mas comoda igual ya teniendo el .sql la puedes importar desde cualquier procesador de SQL de forma mas sencilla y asi escojes cualquiera de tu preferencia.

      Eliminar
    3. En MySQL Workbench se crea la BD de forma mas dinamica sin necesidad de codificar, simplemente se agregan las tablas y los campos, la exportas en .sql y la puedes agregar desde PHPMyAdmi para procesarla de forma mas comoda igual ya teniendo el .sql la puedes importar desde cualquier procesador de SQL de forma mas sencilla y asi escojes cualquiera de tu preferencia.

      Eliminar
  2. Hola! al añadir al descargar el JDBC vienen varios archivos. Solo añado el .jar?? Gracias!

    ResponderEliminar
    Respuestas
    1. Sí, solo el .jar. Después tienes que añadir el nombre del archivo en apartado de dependencias como pone en el tutorial. Cuando yo hice el ejemplo era otra version, la 3.0.17, en tu caso tendrás que poner el nombre de la version del jdbc que te hayas descargado.

      Eliminar
  3. Hola, como puedo guardar los resultados en un arraylist, para luego pasarlos a un adaptador?

    ResponderEliminar
    Respuestas
    1. Buenas:

      No se exactamente a qué resultados te refieres, pero si son los obtenidos a través de la base de datos, guardados en el ResultSet, tendrías que utilizar el método add de arrayList junto con el getString del ResultSet:

      arrayList.add(result.getString("nombre de la columna"));

      Si quieres añadir un entero tendrías primero que convertirlo a un String a través del método, por ejemplo, Integer.toString(valor), aunque hay varias formas de hacerlo.

      Entonces si lo que quieres es por ejemplo tener un arrayList con la lista de valoraciones (en el caso del ejemplo), podrías hacerlo con un bucle que recorra el ResultSet y obtenga los valores:

      while(result.next()){

      arrayList.add(result.getString("valoracion"));

      }

      Espero que te sea de ayuda =)

      Eliminar
    2. Hola de nuevo,

      no hay manera de conectarme, me da este error todo el tiempo.

      java.sql.SQLException: Unable to connect to any hosts due to exception: java.net.SocketException: java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 3306): connect failed: ECONNREFUSED (Connection refused)

      Eliminar
    3. Hola Dani:

      La dirección de localhost se utiliza para acceder al propio host (al ordenador donde se está ejecutando el XAMPP) y se corresponde con la dirección IP 127.0.0.1. Cuando lo que quieres es conectarte desde el móvil, no puedes utilizar la misma dirección porque entonces el movil intentaría acceder a sí mismo al puerto 3306, pero la base de datos está en el ordenador.

      Lo que tienes que hacer es buscar la dirección IP privada del host, que probablemente será de la forma 192.168.1.xxx (en el caso del ejemplo la mía era 192.168.1.131) y acceder a la base de datos a través de la dirección y el puerto que aparezca en el panel de XAMPP, en mi caso el 3306. Por lo tanto, en mi caso tendrías que acceder a la IP 192.168.1.131:3306.

      Para saber la dirección IP privada del ordenador que ejecuta el XAMPP puedes hacerlo desde la consola (cmd) ejecutando el comando "ipconfig" y buscando la dirección IPv4 privada del "Adaptador de LAN inalámbrica Wi-Fi".

      Espero que te sea de ayuda. Por si no te has dado cuenta, al final del post hay un link al repositorio de GitHub con el código de la aplicación de ejemplo.

      Un saludo

      Eliminar
  4. hola, me arroja un error al intentar conectarme
    java.sql.SQLException: Data source rejected establishment of connection, message from server: "Host '192.168.1.77' is not allowed to connect to this MySQL server"
    ya trate de configurar el XAMPP pero namas no se deja

    ResponderEliminar
    Respuestas
    1. Hola Angel:

      Posiblemente tengas que darle permisos. Mira el punto 4 del apartado de "Consideraciones adicionales", al final del post.

      Saludos

      Eliminar
  5. Hola Vicente me quede en el proceso de agregar *.jar al querer correr la app me arroja el siguiente error:

    Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
    > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0_45\bin\java.exe'' finished with non-zero exit value 1

    ResponderEliminar
    Respuestas
    1. Hola Luis:

      En base al error que te da, no creo que sea un problema de agregar el .jar. Más bien parece un problema de configuración del proyecto. Intenta hacer un "clean" del proyecto y después intenta ejecutar la app. Te dejo aquí un enlace que quizá te sirva.

      http://stackoverflow.com/questions/32807587/com-android-build-transform-api-transformexception

      Un saludo, y espero que lo resuelvas ;)

      Eliminar
  6. necesito conexion a internet o todo es local??

    ResponderEliminar
    Respuestas
    1. En este ejemplo todo es en local. Es más, si miras al final del post, en "consideraciones adicionales", explico brevemente por qué tiene que ser en local (como la wifi de casa, por ejemplo).

      O bien el pc y el movil que ejecuta la aplicación tienen que estar conectado a la red local (por ejemplo, ambos conectado a la red wifi de casa), o bien que el host que tiene la base de datos tenga una direccion IP publica a la que poder acceder desde el movil.

      Para acceder desde el movil a un servidor remoto en internet tienes que saber su dirección IP pública y que el servidor esté correctamente configurado para recibir peticiones.

      Eliminar
  7. Hola Vicente solo quiero felicitarte, pocas veces se encuentra un tutorial(o ejemplo) tan bien explicado y detallado como este realmente todo esta muy muy claro muchísimas gracias me has sido de mucha ayuda :D... haaa si una pequeña consulta, ¿habrá alguna diferencia si en lugar de XAMP utilizo WAMP? tengo entendido que funcionan igual, Saludos y gracias de nuevo

    ResponderEliminar
    Respuestas
    1. por cierto que version de sdk usaste?

      Eliminar
    2. Muchas gracias =)

      La verdad, no he utilizado nunca WAMP así que no se si habrá alguna diferencia o no. Respecto a la versión:

      android {
      compileSdkVersion 22
      buildToolsVersion "23.0.0 rc2"

      defaultConfig {
      applicationId "programados.ejemploconexionbasedatos"
      minSdkVersion 16
      targetSdkVersion 22
      versionCode 1
      versionName "1.0"
      }

      Un saludo, y gracias de nuevo :)

      Eliminar
  8. Hola....gracias por el tutorial. Me gustaria saber que pasaria cuando se necesitan varias consultas a la base de datos. Se tendria que hacer un switch case en el metodo doInBackground para que se seleccione insertar, eliminar, etc ?

    ResponderEliminar
    Respuestas
    1. Hola Ramiro. Pues hay varias opciones de hacerlo, pero sí, esa es una opción. Un switch case que se encargue de hacer la inserción o de eliminar algo en función de lo que le hayas pasado como parametro (variable strings en el caso del ejemplo) al metodo doInBackground.

      También puedes ponerle a la clase ConexionDB una lista como atributo y pasarle la lista de peticiones cuando crees la clase. Después en el doInBackground se puede poner un for o iterator que recorra la lista y haga las peticiones.

      Eliminar
    2. Gracias Vicente....buena idea lo de la lista para la clase ConexionBD. Si tengo tiempo empezare a trabajar mas en mi aplicacion movil

      Eliminar
  9. Buen día, gracias por el tutorial, me ayudo demasiado, voy empesando a programar para android, y bases de datos, de casualidad tendras un tutorial en donde edites y insertes informacion en una base de datos?...

    ResponderEliminar
    Respuestas
    1. Buenos días, me alegro que te haya sido de ayuda.

      La verdad es que no tengo ningún tutorial así, hace casi un año que no escribo nada porque no tengo mucho tiempo. Sin embargo, no creo que difiera mucho de lo que se ha hecho en este tutorial. Sin probarlo, creo que funcionaria simplemente de la siguiente manera:

      - En la clase ConexionDB, concretamente en el doInBackground, cuando se crea el string "peticion" se hace con la operacion "select from", que lo hace es obtener de la base de datos en cuestión los datos de (en este caso) "fifa15" de la tabla "videojuegos". Si lo que quieres hacer es insertar información, puedes cambiar "select from" por "insert into" con los parámetros necesarios.

      Te dejo un link con información acerca de como se hace la petición de insertar: http://www.w3schools.com/sql/sql_insert.asp

      Un saludo

      Eliminar
  10. Buenas, estoy intentando conectarme a traves de Hostname en vez de por Ip, es posible?

    Yo lo he cambiado y no me funciona asi, no se si tendre que cambiar alguna sentencia

    ResponderEliminar
    Respuestas
    1. No se a qué te refieres con Hostname, supongo que a localhost. No te funciona porque localhost es la dirección de tu dispositivo móvil, así que tienes que poner la IP del servidor. Copio y pego la respuesta que dí a una pregunta (creo) similar a la tuya.

      La dirección de localhost se utiliza para acceder al propio host (al ordenador donde se está ejecutando el XAMPP) y se corresponde con la dirección IP 127.0.0.1. Cuando lo que quieres es conectarte desde el móvil, no puedes utilizar la misma dirección porque entonces el movil intentaría acceder a sí mismo al puerto 3306, pero la base de datos está en el ordenador.

      Lo que tienes que hacer es buscar la dirección IP privada del host, que probablemente será de la forma 192.168.1.xxx (en el caso del ejemplo la mía era 192.168.1.131) y acceder a la base de datos a través de la dirección y el puerto que aparezca en el panel de XAMPP, en mi caso el 3306. Por lo tanto, en mi caso tendrías que acceder a la IP 192.168.1.131:3306.

      Para saber la dirección IP privada del ordenador que ejecuta el XAMPP puedes hacerlo desde la consola (cmd) ejecutando el comando "ipconfig" y buscando la dirección IPv4 privada del "Adaptador de LAN inalámbrica Wi-Fi".

      Espero que te sea de ayuda. Por si no te has dado cuenta, al final del post hay un link al repositorio de GitHub con el código de la aplicación de ejemplo.

      Saludos

      Eliminar
    2. Cuando me refiero a Hostname, es al nombre que tengo asignado al servidor.

      El servidor tiene la IP(10.201.1.230) y el nombre del servidor es "MiServer". Puedo poner en el string de conexion dek driver JDBC: DriverManager.getConnection("jdbc:mysql://MiServer:3306/baseDeDatos,...

      Esa seria mi duda, creo que lo explique algo mejor.

      Gracias

      Eliminar
    3. Ahhh perdona, no te entendí.

      No, en ese caso creo que no va a funcionar. Tendrías que configurar el servidor DNS para que acepte el nombre de tu host y le asigne la IP correspondiente, de manera que cuando se ejecuta el método getConnection con el nombre de tu host se haga una llamada al servicio DNS y devuelva la IP con la que hacer la petición.

      Sin embargo, no lo he hecho y no sabría decirte exactamente qué debes de hacer, lo siento.

      Un saludo

      Eliminar
  11. hola disculpa tengo un proyecto de la escuela donde nos piden que creemos un programa en java "netbeans" y ahora nos piden que corra para un celular o tablet mi pregunta es tendrás algún vídeo tutorial donde expliques lo de este blog o podría mandarte un corre donde te explique mas detalla mente que es lo que necesito hacer, si se puede o no y un saludo

    ResponderEliminar
    Respuestas
    1. No, no tengo ningún vídeo tutorial. De hecho actualmente tampoco sigo haciendo ningún tipo de tutorial porque no tengo tiempo, espero poder volver a hacer algo cuanto antes.

      Un saludo

      Eliminar
  12. Hola, hago todo como dices y me da el siguiente rror:
    Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
    > java.io.FileNotFoundException: C:\Users\DAC2.0-PC\AndroidStudioProjects\EjemploConexionBaseDatos\app\mysql-connector-java-3.0.17-ga-bin.jar (El sistema no puede encontrar el archivo especificado)

    ResponderEliminar
    Respuestas
    1. Esa versión (la 3.0.17) era la que utilicé en el momento de hacer el tutorial. Ya puse una nota diciendo que esa versión podría cambiar con el tiempo, y que es necesario modificar la línea:

      >> compile files('mysql-connector-java-3.0.17-ga-bin.jar')

      Cambiando 'mysql-connector-java-3.0.17-ga-bin.jar' por el .jar que te hayas descargado de la pagina oficial:

      http://dev.mysql.com/downloads/connector/j/

      Un saludo

      Eliminar
  13. Hola Vicente. Muchas gracias por el aporte.

    No tengo problemas al entender tu código, sólo que me sale este error al tratar de correr la app:
    Error:com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)

    Estoy suponiendo que se debe a problemas de compatibilidad, pero aún no estoy seguro de nada.

    Si me podrías ayudar, te lo agradecería aún más.

    Saludos.

    ResponderEliminar
    Respuestas
    1. Hola Moisés, de nada ;)

      Parece que es un problema de compatibilidad como tú dices. Cuando añades el módulo de my-sql connector en el build.gradle tienes que indicarle el project version correctamente. Te dejo un par de páginas que acabo de encontrar que te pueden servir:

      http://stackoverflow.com/questions/24662801/bad-class-file-magic-or-version

      http://stackoverflow.com/questions/24741948/wrong-java-compiler-when-including-a-java-module-as-dependency-in-android-studio

      http://www.alonsoruibal.com/my-gradle-tips-and-tricks/

      Un saludo!

      Eliminar
    2. Hola de nuevo, muchas gracias por responder. Solucioné mi problema, y sólo fue que en la carpeta libs de mi proyecto, coloqué sólo el archivo .jar de la API jdbc, en vez de colocar su carpeta completa. Lo comento para que no le pase lo mismo a otra persona.

      Ahora bien, ya puedo accesar a mi app, pero cuando trato de hacer conexión con mi base de datos (escribiendo el nombre de mi tabla, el nombre de alguna dupla y luego apretando el botón), la app se cierra.

      Mediante la función Log.d, comencé a rastrear la línea de código que hace que se me cierre la app, y específicamente se cierra cuando se ejecuta el comando: "Class.forName("com.mysql.jdbc.Driver");".

      Nota: Ya me fijé de tener ese archivo entre las carpeta de la API, pero igual, me sale este error en letras azules: "java.lang.ClassNotFoundException: com.mysql.jdbc.Driver".

      Disculpa las molestias, espero que puedas responderme pronto.

      Saludos de nuevo. (:

      Eliminar
    3. No estoy seguro de lo que puede ser, pero parece que no es capaz de encontrar bien la clase Driver. Eso puede deberse a que no hayas compilado el .jar, aunque lo hayas puesto en la carpeta libs. ¿Has puesto la siguiente línea en el archivo build.gradle?

      compile files('[nombre de la lib].jar')

      Donde [nombre de la lib] corresponde al nombre del .jar que hayas añadido a la carpeta libs, el que te descargaste de la página de jdbc.

      Ya me contarás si es eso =)

      Eliminar
    4. Este comentario ha sido eliminado por el autor.

      Eliminar
    5. Sí, sí tengo esa línea. De hecho, la tengo de esta manera:

      dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
      testCompile 'junit:junit:4.12'
      compile 'com.android.support:appcompat-v7:23.1.1'
      compile 'com.android.support:design:23.1.1'
      compile files('mysql-connector-java-5.1.39-ga-bin.jar')
      }

      Ahora que lo pienso, dentro de la carpeta libs, tengo la carpeta de la API, y dentro de esa carpeta, tengo todos los archivos de la API. Me refiero que, la dirección del archivo "mysql-connector-java-5.1.39-ga-bin.jar", vendría siendo algo como "/libs/mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-ga-bin.jar." Está bien así?, o debería ser "/libs/mysql-connector-java-5.1.39-ga-bin.jar."?

      Te adelanto que ya probé copiando todos los archivos de la carpeta de la API, directamente a la carpeta libs, y me aparece un error de código en esta línea "Statement estado = conn.createStatement();". Éste es el error que se produce "Error:(73, 56) error: incompatible types: java.sql.Statement cannot be converted to com.mysql.jdbc.Statement".

      Eliminar
    6. Bueno, ya lei que sólo tengo que copiar y pegar el archivo .jar de la API, en la carpeta libs. Pero igual no me funciona, sigo con el problema de la compatibilidad.

      Eliminar
    7. Pues la verdad no sé que puede ser =/ intenta googlear por ahí, al final seguro que lo sacas =)

      Suerte, y siento no haber podido ayudarte más.
      Saludos!

      Eliminar
    8. Ya pude solucionarlo, pero gracias a otro método (utilicé un JSON parser).

      Igualmente, gracias por tus rápidas respuestas. Te agradezco el blog.

      Saludos, compañero.

      Eliminar
  14. Hola Vicente te agradecería mucho si me ayudaras con unos errores que me salieron...
    Error:PARSE ERROR:
    Error:unsupported class file version 52.0
    Error:...while parsing com/mysql/jdbc/JDBC42CallableStatement.class

    ResponderEliminar
  15. Hola muy buen aporte. He echo todo como lo indica, solo que me marca un pequeño error en los puntos de la IP & la verdad no se porque, yo apenas ando entrando a esto. De antemano gracias. :)

    ResponderEliminar
    Respuestas
    1. Perdona por la tardanza, he estado bastante ocupado últimamente.

      Si aún sigues teniendo el problema, te puedo ayudar si concretas un poco más qué error te marca.

      Eliminar
  16. Si hago un proyecto con la API 19 por ejemplo, no necesito Asyntask verdad? Es decir, puedo directamente hacerlo como en java normal.

    ResponderEliminar
  17. Amigo tengo exactamente todo como tu. Incluida la base de datos y me dice que la videoconsola no está en la base de datos.
    ¿Qué puede ser? No me ha dado ningún problema de conexión ni nada, ¿supongo que quiere decir que se ha podido conectar bien no?

    ResponderEliminar
    Respuestas
    1. Ten cuidado al introducir el nombre de la consola, tiene que estar exactamente igual que en la base de datos. Si me enseñas el error que te da el programa (si es que te da alguno) quizá pueda ayudarte más.

      Eliminar
  18. Hola, en ConexionDB una vez muestras el resultado no me detecta el "userTV y passTV".No sabe lo son. Pq?
    userTV.setText(result.getString(0));
    passTV.setText(result.getString(1));

    ResponderEliminar
    Respuestas
    1. Es posible que no los hayas instanciado los textView o que no los encuentre con el nombre que le has indicado cuando llamas a FindViewByID.

      Eliminar
  19. disculpa hice algo parecido y al querer buscar por ciudad me muestra solo las que no tinen espacio en su nombre, por ejemplo si busco Coquimbo, me muestra todo bien, pero si busco la serena no me muestra nada, pienso que eso de las comillas pero no entendi donde van u.u

    ResponderEliminar
  20. Disculpa me sale este error
    Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
    > Failed to create MD5 hash for file 'C:\Users\Jair\Desktop\TDM\TDM_U3_EjempXAMPP\app\mysql-connector-java-5.1.42-bin.jar'.

    espero puedas ayudarme. Gracias!

    ResponderEliminar
    Respuestas
    1. Para corregir ese problemas, prueba ha hacer lo siguiente:
      1. Deja esta linea así: compile files('libs/mysql-connector-java-5.1.42-bin.jar') Pones la versión de tu JDBC.

      2. En el mismo fichero de arriba, añadir las siguientes lineas dentro de android {

      ...
      ...
      ...
      defaultConfig {
      ...
      ...
      ...
      jackOptions {
      enabled true
      }

      }

      compileOptions {
      sourceCompatibility JavaVersion.VERSION_1_7
      targetCompatibility JavaVersion.VERSION_1_7
      }
      }

      Prueba, y me avisas ;)

      Eliminar
  21. Pues vaya mierda de Tutorial colega, te lo hubieras currado más...

    ResponderEliminar