Como funciona a conexão com Mysql no Android?

Olá. Eu estou iniciando no Android. Gostaria de fazer uma aplicação para trabalhar com Mysql. Estou tentando conectar da mesma maneira do Java desktop. Adicionei a lib do Mysql no projeto. Criei uma classe DAO, e lá inicializei a conexão. O problema é que a conexão não está sendo feita corretamente mesmo com as credenciais corretas. Segue aí a classe:

import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Created by thall on 24/03/2017.
 */

public class GlobalDAO {

    static java.sql.Connection conn;

    public static boolean connect(){
        try {
            conn = DriverManager.getConnection("jdbc:mysql://192.168.1.102/app_formatura?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC", "app_formatura", "KAVeCOjE");
            return true;
        } catch (SQLException e) {
            return false;
        }
    }

    public static String getBox() throws SQLException {
        PreparedStatement stm = conn.prepareStatement("SELECT pega_caixa();");
        ResultSet rs = stm.executeQuery();
        String toReturn = null;
        while(rs.next()){
            toReturn = rs.getString(0);
        }
        return toReturn;
    }
    public static String getGoals() throws SQLException {
        PreparedStatement stm = conn.prepareStatement("SELECT pega_metas();");
        ResultSet rs = stm.executeQuery();
        String toReturn = null;
        while(rs.next()){
            toReturn = rs.getString(0);
        }
        return toReturn;
    }

Alguém sabe me dizer se a conexão deve ser feita de outra maneira ou meu código que está errado mesmo?

Alguma exceção sendo lançada?

Sim. E o método connect está retornando false.

E/AndroidRuntime: FATAL EXCEPTION: main
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{tkfentretenimento.com.formatura92app/tkfentretenimento.com.formatura92app.MainActivity}: java.lang.NullPointerException
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316)
                      at android.app.ActivityThread.access$700(ActivityThread.java:158)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
                      at android.os.Handler.dispatchMessage(Handler.java:99)
                      at android.os.Looper.loop(Looper.java:176)
                      at android.app.ActivityThread.main(ActivityThread.java:5365)
                      at java.lang.reflect.Method.invokeNative(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:511)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
                      at dalvik.system.NativeStart.main(Native Method)
                   Caused by: java.lang.NullPointerException
                      at tkfentretenimento.com.formatura92app.GlobalDAO.getBox(GlobalDAO.java:26)
                      at tkfentretenimento.com.formatura92app.MainActivity.onCreate(MainActivity.java:41)
                      at android.app.Activity.performCreate(Activity.java:5326)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2225)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316) 
                      at android.app.ActivityThread.access$700(ActivityThread.java:158) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296) 
                      at android.os.Handler.dispatchMessage(Handler.java:99) 
                      at android.os.Looper.loop(Looper.java:176) 
                      at android.app.ActivityThread.main(ActivityThread.java:5365) 
                      at java.lang.reflect.Method.invokeNative(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:511) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
                      at dalvik.system.NativeStart.main(Native Method) 
Application terminated.

O que tem na linha 22 de GlobalDAO?

PreparedStatement stm = conn.prepareStatement("SELECT pega_caixa();");

Tudo indica que é conn que não está recebendo o valor.

Você tem o código no GitHub ou em algum repositório? tendo o código fonte ficaria muito mais fácil ajudar.

1 curtida

Sim, sim. Aqui. Só não tenho certeza se está atualizado com o local. Quem está fazendo os commits é o Android Studio. Eu cliquei para atualizar.

Tem duas coisas que eu acho que vale a pena falar. Primeiro, eu já tentei com localhost ao invés do ip. Segundo, eu estou executando no Android Studio porém em um tablet pela USB.

Eu segui esse tutorial. Mas sempre quando eu tento me conectar, mesmo dando a porta 3306, em qualquer dispositivo, eu recebo um:

'DESKTOP-O8I5I23' is not allowed to connect to this MySQL server

Então eu acho que o problema é justamente esse, não, eu tenho certeza.

Sim, com certeza é a permissão de acesso do teu computador.

Pesquise essa mensagem de erro no google, voce vai achar fácil a solução, só retire o IP.

Se sua aplicação Android for rodar em rede local esta solução pode até ser aceitável acessando o banco em uma thread separada, mas fora isso o ideal seria usar web services, seguindo REST por exemplo.

Você quer rodar MySQL no Android?

Essa é uma ideia um tanto bizarra.

Bizarra ou não, deveria funcionar.
Lógico que eu preferiria subir uma aplicação simples, como webservive REST e disponibilizar o crud por esta, mas, nem todo mundo faria da mesma forma.

Funciona no Java™.

No Android, vai depender de como a plataforma implementa java.sql.PreparedStatement, se é que implementa.

Imagino que nem implementa já que Android já vem com SQLite (android.database.sqlite) e não faz sentido rodar um SGBD completo num smartphone.

Essa implementação é do driver e não da plataforma. Caso contrário, não seria preciso incluir drivers nos projetos para interação com bancos de dados.
E, sim, existe um SGDB no android: SQLite (ok, não é um Oracle da vida, mas é um SGBD)

Driver? Estamos falando de Android? rs

SQLite é um banco de dados embarcado e até onde sei não suporta a API java.sql.PreparedStatement.

Não, estou falando da implementação do java para a estrutura da API java.sql.

Como eu coloquei…

Mas é um SGBD…
E sobre prepared statements

Então porque o google resolveu criar outra API ao invés de usar java.sql?

Que confusão google, vergonha!!!

A primeira coisa que eu fiz. Como eu disse, eu segui o tutorial. Era pra dar certo.

Poxa. Realmente é necessário? Eu quero fazer uma coisa tão simples.

Minha aplicação não vai rodar em rede local. Só estou testando.