Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Aplicação não funciona direito

Eu terminei o primeiro módulo do curso de Android agora e o ultimo método não está funcionando. Segue o código para vcs entenderem melhor:

 AlunoDAO dao = new AlunoDAO(this);
 //Instancia o objeto dao, com todos os seus métodos e afins.

 if(aluno.getId() == null){
 //Caso o id do Aluno que temos no formulário seja DIFERENTE de nulo, ou seja se esse já tiver Ido ao formulário e recebido um ID.

dao.insere(aluno);
   Toast.makeText(FormularioActivity.this, aluno.getNome() +" cadastrado(a)!",
   Toast.LENGTH_SHORT).show();

   }else{
   dao.altera(aluno);

   //Caso o ID seja nulo, ou seja caso o aluno não tenha ido ao banco de dados ainda, chamamos o método insere, e não o altera.
   Toast.makeText(FormularioActivity.this, aluno.getNome() +" Alterado com sucesso(a)!",

   Toast.LENGTH_SHORT).show();
       }

      dao.close();
      //Fechamos a conexão com o banco de dados.
                finish();

                //Terminamos o método
                break;

            //Paramos o switch

Esse if não funciona como deveria, porque quando ele é definido com a lógica (aluno.getId() == null) o Inserir não funciona, e quando a lógica é (aluno.getId() != null) o alterar não funciona.

O meu modelo, o DAO tudo está funcionando corretamente, mas é nesse if q algo acontece, não consegui identificar o que está errado. Alguém poderia me ajudar?

ATT, Obrigado.

5 respostas

Oi Pedro, tudo bem?

Eu vi o seu código e está correto era pra funcionar normalmente! Se preferir passar o projeto todo eu posso dar uma olhada, pois baseando-se nesse trecho que você enviou eu não vejo problema algum na lógica.

Abraços.

Olá Pedro, tudo bem?

Acredito que essa parte do código esteja faltando:

Aluno aluno = helper.pegaAluno();

Com o método pegaAluno(), podemos verificar se trata de um aluno que veio da ListaAlunosActivity (id !=null) ou se é de fato o cadastro de um novo aluno (id==null).

Espero que funcione!

Abs

A classe DAO:

@NonNull
    private ContentValues getContentValues(Aluno aluno) {
        //Método que recebe um aluno como argumento e que recupera deste objeto os seus dados
        //E então coloca os mesmos em cada linha da tabela.
        ContentValues dados = new ContentValues();

        dados.put("nome", aluno.getNome());
        dados.put("telefone", aluno.getTelefone());
        dados.put("endereco", aluno.getEndereco());
        dados.put("twitter", aluno.getTwitter());
        dados.put("snapchat", aluno.getSnapchat());
        dados.put("facebook", aluno.getFacebook());
        dados.put("instagram", aluno.getInstagram());
        dados.put("nota", aluno.getNota());
        return dados;
    }

    public void insere(Aluno aluno) {
        SQLiteDatabase db = getWritableDatabase();

        ContentValues dados = getContentValues(aluno);


        db.insert("alunos",null,dados);
    }




    public List<Aluno> buscaAluno(){
        String sql = "SELECT * FROM alunos;";
        SQLiteDatabase db = getReadableDatabase();
        Cursor c = db.rawQuery(sql, null);

        List<Aluno> alunos = new ArrayList<>();
        while (c.moveToNext()){
            Aluno aluno = new Aluno();
            aluno.setId(c.getLong(c.getColumnIndex("id")));
            aluno.setNome(c.getString(c.getColumnIndex("nome")));
            aluno.setTelefone(c.getString(c.getColumnIndex("telefone")));
            aluno.setEndereco(c.getString(c.getColumnIndex("endereco")));
            aluno.setTwitter(c.getString(c.getColumnIndex("twitter")));
            aluno.setSnapchat(c.getString(c.getColumnIndex("snapchat")));
            aluno.setFacebook(c.getString(c.getColumnIndex("facebook")));
            aluno.setInstagram(c.getString(c.getColumnIndex("instagram")));
            aluno.setNota(c.getDouble(c.getColumnIndex("nota")));

            alunos.add(aluno);
        }
        c.close();
        return alunos;
    }


    public void deleta(Aluno aluno) {
        SQLiteDatabase db = getWritableDatabase();

        String [] params = {aluno.getId().toString()};
        db.delete("alunos","id=?",params);
    }

    public void altera(Aluno aluno) {
        SQLiteDatabase db = getWritableDatabase();
        //Recuperamos uma instancia do banco de dados, que usaremos para alterar o mesmo.

        ContentValues dados = getContentValues(aluno);
        //Declaramos uma váriavel do tipo ContentValues, que recebe o retorno do método getContentValues();

        String[] params = {aluno.getId().toString()};
        //Preparamos nossa String de argumentos, que passaremos como parâmetro para a nossa "query".

        db.update("alunos",dados,"id=?",params);
        //Chamamos o método update. Passamos: a tabela que será modificada na query, passamos os dados que
        //Serão alterados, passamos o ID do registro que será alterado. Passamos a String com os parametros
        //Que serão modificados.

A classe Modelo:

public class Aluno implements Serializable {
    private long id;
    private String nome;
    private String telefone;
    private String endereco;
    private String twitter;
    private String snapchat;
    private String facebook;
    private String instagram;
    private Double nota;

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public String getTwitter() {
        return twitter;
    }

    public void setTwitter(String twitter) {
        this.twitter = twitter;
    }

    public String getSnapchat() {
        return snapchat;
    }

    public void setSnapchat(String snapchat) {
        this.snapchat = snapchat;
    }

    public String getFacebook() {
        return facebook;
    }

    public void setFacebook(String facebook) {
        this.facebook = facebook;
    }

    public String getInstagram() {
        return instagram;
    }

    public void setInstagram(String instagram) {
        this.instagram = instagram;
    }

    public Double getNota() {
        return nota;
    }

    public void setNota(Double nota) {
        this.nota = nota;
    }

    public Long getId() {
        return id;

    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return getId() + " - " + getNome();
    }
}

A FormularioHelper:

public class FormHelper {
    private EditText nome;
    private EditText telefone;
    private EditText endereco;
    private EditText twitter;
    private EditText snapchat;
    private EditText facebook;
    private EditText instagram;
    private RatingBar nota;
    private Aluno aluno;
    //Aqui usamos agregação, temos um atributo do tipo aluno na classe.

    public FormHelper(AppCompatActivity form){
        nome = (EditText) form.findViewById(R.id.formulario_nome);
        telefone = (EditText) form.findViewById(R.id.formulario_telefone);
        endereco = (EditText) form.findViewById(R.id.formulario_endereco);
        twitter = (EditText) form.findViewById(R.id.formulario_twitter);
        snapchat = (EditText) form.findViewById(R.id.formulario_snapchat);
        facebook = (EditText) form.findViewById(R.id.formulario_facebook);
        instagram = (EditText) form.findViewById(R.id.formulario_instagram);
        nota = (RatingBar) form.findViewById(R.id.formulario_barra_avaliacao);
        aluno = new Aluno();
        //Instanciamos o nosso objeto aluno no constutor da classe aluno.
    }

    public Aluno pegaAluno(){
        //Note que não precisamos instaciar o nosso objeto aluno para pegar os seus métodos e nem
        //Para colocar dados dentro do mesmo, isso porque o nosso objeto Aluno já foi instanciado na
        //Criação da classe, no construtor.
        aluno.setNome(nome.getText().toString());
        aluno.setTelefone(telefone.getText().toString());
        aluno.setEndereco(endereco.getText().toString());
        aluno.setTwitter(twitter.getText().toString());
        aluno.setSnapchat(snapchat.getText().toString());
        aluno.setFacebook(facebook.getText().toString());
        aluno.setInstagram(instagram.getText().toString());
        aluno.setNota(Double.valueOf(nota.getProgress()));

        return aluno;
    }

    public void preencheFormulario(Aluno aluno) {
        //Criamos o método que coloca as informações do aluno em ordem. No método pegaAluno, recuperamos as infor
        //mações do aluno do formulário, nesse método, colocamos as informações recuperadas no formulário.
        nome.setText(aluno.getNome());
        telefone.setText(aluno.getTelefone());
        endereco.setText(aluno.getEndereco());
        twitter.setText(aluno.getTwitter());
        snapchat.setText(aluno.getSnapchat());
        facebook.setText(aluno.getFacebook());
        instagram.setText(aluno.getInstagram());
        nota.setProgress(aluno.getNota().intValue());
        this.aluno = aluno;
        //Nessa ultima linha, recuperamos o Objeto aluno, com todos os dados (Inclusive o ID, que iremos
        // precisar para alterar o BD).
    }
}

A ListaAlunosActivity:

private ListView listaAlunos;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); //Usa o estado salvo na classe AppComaptActivity
        setContentView(R.layout.activity_lista_alunos);//Usa o layout salvo na pasta res,
        // na pasta layout e o arquivo nome_activity.xml

        listaAlunos = (ListView) findViewById(R.id.lista_alunos);
        //Aqui recuperamos a lista e guardamos a mesma em uma váriavel global. Isso porque definimos a lista como
        //Atributo da classe. E na criação da classe recuperamos o valor desse atributo.


        listaAlunos.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            //Coloca um listener na lista, esse pega em qual subElemento ocorreu o click
            @Override
            public void onItemClick(AdapterView<?> lista, View item, int posicao, long id) {
                //Os parametros são, lista (Pai do sub componente), o item que foi clicado (view),
                //A posição do elemento na lista, e o seu ID.

                Aluno aluno = (Aluno) listaAlunos.getItemAtPosition(posicao);
                //Esse método pega o aluno dada a sua posição na lista, o retorno desse método é do tipo
                //Object. Por isso o cast para Aluno (Downcast).
                //Agora dado um click na lista recuperamos, pela sua posição qual aluno foi clicado.

                Intent vaiProFormulario = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
                //Criamos uma intenção de irmos para a activity formulario.java. Então dizemos isso ao android
                //Criamos um objeto do tipo intent e passamos no construtor onde estamos e para onde queremos ir
                vaiProFormulario.putExtra("aluno",aluno);
                //Chamamos o método putExtra e passamos o que queremos levar para a formulário activity
                //Nesse caso levamos o nosso objeto aluno (Serializado, por isso implementamos a interface
                // Serializable). Passamos também uma etiqueta no objeto isso porque é o que vamos chamar na
                //FormularioActivity.class.
                startActivity(vaiProFormulario);
                //Começamos a intenção no clique em um item da lista.
            }
        });

        carregaLista();

        Button botao = (Button) findViewById(R.id.lista_alunos_adicionar);

        botao.setOnClickListener(new View.OnClickListener() {//Criação da Classe anônima, que implementa interface
            @Override
            public void onClick(View v) {

                Intent ir_Formulario = new Intent(ListaAlunosActivity.this, FormularioActivity.class);

                startActivity(ir_Formulario);
            }
        });

        registerForContextMenu(listaAlunos);
    }

    private void carregaLista() {
        AlunoDAO dao = new AlunoDAO(this);

        List<Aluno> alunos = dao.buscaAluno();

        dao.close();

        ArrayAdapter<Aluno> adaptador = new ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item, alunos);

        listaAlunos.setAdapter(adaptador);
    }


    @Override
    protected void onResume() {
        super.onRestart();
        carregaLista();
    }


    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, final ContextMenu.ContextMenuInfo menuInfo) {

        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        //Recuperamos o Item que foi clicado na lista.
        final Aluno aluno = (Aluno) listaAlunos.getItemAtPosition(info.position);
        //Guardamos o objeto que foi clicado na lista, dentro de um objeto do tipo Aluno. Como essa váriavel foi declarada fora de uma
        //classe anônima e está sendo usada dentro de uma, o Android nos obriga a declarar a mesma como final.

        //--------------------------------------------------------------------------------------------------------------//
        MenuItem itemSite = menu.add("Visitar Instagram");
        //Adicionamos mais uma opção no menu de contexto. Logo após um clique longo, aparecerá 2 opções no menu de contexto.
        //Visitar instagram e Deletar.

        Intent vaiProSite = new Intent(Intent.ACTION_VIEW);
        //Aqui passamos uma Intent Ímplicita, isso é, dizemos ao Android: "Quero abrir um site, me dê a Intent mais recomendada
        //Pra esse trabalho.

        String site = "https://www.instagram.com/" + aluno.getInstagram() + "/";
        //Recuperamos o instagram do objeto aluno, Concatenamos com o endereço do instagram e com as duas barras necessárias da URL.

        vaiProSite.setData(Uri.parse(site));
        //Aqui passamos um dado obrigatório para a Intent. Esse dado é obrigatório por um motivo, caso ele não seja
        //passado, não existe Intent. Logo ele precisa ser passado, esse dado é o endereço do Instagram.

        itemSite.setIntent(vaiProSite);
        //Aqui Associamos o nosso menu de contexto a uma Intent, isso é, dizemos que quando clicarmos em um menu de contexto, essa Intent
        //Será automáticamente executada.

        //----------------------------------------------------------------------------------------------------------------------//
        MenuItem itemMensagem = menu.add("Enviar Mensagem");
        //Adiciona uma nova opção no menu de contexto
        Intent enviarMensagem = new Intent(Intent.ACTION_VIEW);
        //Cria uma nova intent onde dizemos que queremos vizualizar algo, e deixamos o usuário decidir como vai visualizar
        enviarMensagem.setData(Uri.parse("sms:" + aluno.getTelefone()));
        //Colocamos o protocolo da URI, junto com o telefone do aluno.
        itemMensagem.setIntent(enviarMensagem);
        //Aqui associamos a nossa opção de menu com a nossa Intent.
        //----------------------------------------------------------------------------------------------------------------------//

        //"Mesma coisa" dos outros menus, muda apenas o protocolo do URI, e o que aparece no menu de contexto.
        MenuItem itemMapa = menu.add("Visualizar a casa do Aluno no Mapa");
        Intent verMapa = new Intent(Intent.ACTION_VIEW);
        verMapa.setData(Uri.parse("geo:0,0?q=" + aluno.getEndereco()));
        itemMapa.setIntent(verMapa);
        //---------------------------------------------------------------------------------------------------------------------//

        //---------------------------------------------------------------------------------------------------------------------//

        MenuItem deletar = menu.add("Deletar");
        deletar.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                AlunoDAO alunoDAO = new AlunoDAO(ListaAlunosActivity.this);
                alunoDAO.deleta(aluno);
                alunoDAO.close();

                carregaLista();
                return false;
            }
        });
    }
}

E por último a Formulário Activity:

private FormHelper form;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_formulario);

        form = new FormHelper(this);
        //Intanciamos a nossa classe que abstrai a lógica que usamos no formulário.

        Intent intencao = getIntent();
        //Recuperamos a intenção que nos trouxe aqui. E guardamos o seu retorno em uma
        //Váriavel

        Aluno aluno = (Aluno) intencao.getSerializableExtra("aluno");
        //Aqui "inflamos" novamente o nosso objeto que veio "pendurado" na nossa intent, pois foi isso que fizemos
        //Penduramos um objeto serializado, do tipo Aluno, em nossa intent. Aqui recuperamos o nosso aluno
        if(aluno != null){
            //Temos dois modos de vir para o formulário, quando queremos cadastrar um novo aluno e quando queremos
            //editar um que já existe, logo só vamos colocar dados no nosso formulário quando o objeto aluno não
            // estiver vazio. Caso ele esteja, ignoramos o mesmo.
            form.preencheFormulario(aluno);
            //Chamamos o método que coloca as informações do objeto em ordem.
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) { //Cria um menu na Activity, isso é recebe um objeto menu e
        //retorna um objeto do tipo menu.
        getMenuInflater().inflate(R.menu.formulario_activity, menu);//O método getMenuInflate,chama o método
        //Inflater e recebe como argumento o nome do menu que ele vai inflar, ou seje, transformar de XML
        // para Java, e recebe o que ele vai inflar, nesse caso um menu.
        return super.onCreateOptionsMenu(menu);//Retorna o objeto menu criado e inflado.
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()){

            case R.id.menu_formulario_salvar:

                AlunoDAO dao = new AlunoDAO(this);
                Aluno aluno = form.pegaAluno();

                //Instancia o objeto dao, com todos os seus métodos e afins.
                if(aluno.getId() == null){
                    //Caso o id do Aluno que temos no formulário seja DIFERENTE de nulo, ou seja se esse já tiver
                    //Ido ao formulário e recebido um ID.
                    dao.insere(aluno);
                    Toast.makeText(FormularioActivity.this, aluno.getNome() +" cadastrado(a)!",
                            Toast.LENGTH_SHORT).show();
                    }else{
                    dao.altera(aluno);
                    //Caso o ID seja nulo, ou seja caso o aluno não tenha ido ao banco de dados ainda, chamamos
                    //O método insere, e não o altera.
                    Toast.makeText(FormularioActivity.this, aluno.getNome() +" Alterado com sucesso(a)!",
                            Toast.LENGTH_SHORT).show();
                }
                dao.close();
                //Fechamos a conexão com o banco de dados.


                finish();
                //Terminamos o método
                break;
            //Paramos o switch

        }
        return super.onOptionsItemSelected(item);
    }
}

Cara, tá tudo funcionando, só naquela parte que dá aquele bug. Se você conseguir encontrar eu ficarei grato, pois já tentei tudo e já revirei esse código de cabo a rabo.

Att, Obrigado.

solução!

Olá Pedro,

Acredito que o problema esteja na sua classe modelo Aluno, o id está do tipo long primitivo, com isso ele vai colocar como valor default para o id=0 e com isso, um novo aluno terá o id sempre diferente de nulo.

Pra mudar isso, tente alterar para classe Wraper:

private Long id;

Com isso, o valor default do id será null ao invés de 0.

Espero que funcione!

Abs

Caramba, obrigado!