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

Erro: java.lang.NullPointerException

Olá.

Na hora de execução do OnMenuItenClick para Deletar apresenta o erro java.lang.NullPointerException no ClienteDAO Já pesquisei que não pode voltar um valor NULL, mas não sei aonde esta puxando esse valor NULL e como corrigir. Podem me ajudar por favor?

CLASSE LISTA DE CLIENTE ACTIVITY

public class ListaClientesActivity extends Activity{

    private ListView lista;
    private Cliente cliente;

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

        lista = (ListView) findViewById(R.id.lista);
        registerForContextMenu(lista);    

        //Clique normal
        lista.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter, View view,
                    int posicao, long id) {

                Intent irParaFormulario = new Intent(ListaClientesActivity.this, FormularioActivity.class);
                startActivity(irParaFormulario);

                Toast.makeText(ListaClientesActivity.this, "A posição é: " + posicao, Toast.LENGTH_SHORT).show();                
            }
        });

    }

    @Override
    protected void onResume() {

        //carregaLista();
        super.onResume();
        ClienteDAO dao = new ClienteDAO(this);
        List<Cliente> clientes = dao.getLista();

        ArrayAdapter<Cliente> adapter = 
            new ArrayAdapter<Cliente>(this, android.R.layout.simple_list_item_1, clientes); 
        lista.setAdapter(adapter);

    }

        private void carregaLista() {
            ClienteDAO dao = new ClienteDAO(this);
            List<Cliente> clientes = dao.getLista();

            ArrayAdapter<Cliente> adapter = 
                new ArrayAdapter<Cliente>(this, android.R.layout.simple_list_item_1, clientes); 
            lista.setAdapter(adapter);


        }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_listaclientes, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
        case R.id.novo:
            Intent irParaFormulario = new Intent(ListaClientesActivity.this, FormularioActivity.class); 
            startActivity(irParaFormulario);
            break;

        default:
            break;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        menu.add("Ligar");
        menu.add("Enviar SMS");
        menu.add("Achar no Mapa");
        menu.add("Navegar no site");
        MenuItem deletar = menu.add("Deletar");
        deletar.setOnMenuItemClickListener(new OnMenuItemClickListener() {

            @Override
            public boolean onMenuItemClick(MenuItem item) {
                ClienteDAO dao = new ClienteDAO(ListaClientesActivity.this);
                dao.deletar(cliente);
                Toast.makeText(ListaClientesActivity.this, 
                        "Clicou no Botão", Toast.LENGTH_LONG).show();

                dao.close();
                carregaLista();

                return false;
            }
        });

        menu.add("Enviar E-Mail");

        super.onCreateContextMenu(menu, v, menuInfo);
    }
}

CLASSE DAO

public class ClienteDAO extends SQLiteOpenHelper{

    private static final String DATABASE = "db_CadClie";
    private static final int VERSAO = 2;
    private static final String TABELA = "Cliente";

    public ClienteDAO(Context ctx) {
        super(ctx, DATABASE, null, VERSAO);

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE " + TABELA + " ( "
                + "id INTEGER PRIMARY KEY, "
                + "nome TEXT UNIQUE NOT NULL, "
                + "telefone TEXT, "
                + "endereco TEXT, "
                + "email TEXT, "
                + "nota REAL, "
                + "caminhoFoto TEXT"
                + ");";

        db.execSQL(sql);


    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql = "DROP TABLE IF EXISTS " + TABELA;
        db.execSQL(sql);
        onCreate(db);
    }

    public void insere(Cliente cliente) {
        ContentValues cv = new ContentValues();
        cv.put("nome", cliente.getNome());
        cv.put("telefone", cliente.getTelefone());
        cv.put("endereco", cliente.getEndereco());
        cv.put("email", cliente.getEmail());
        cv.put("nota", cliente.getNota());
        cv.put("caminhoFoto", cliente.getCaminhoFoto());

        getWritableDatabase().insert(TABELA, null, cv);
    }

    public List<Cliente> getLista() {
        List<Cliente> clientes = new ArrayList<Cliente>();

        String sql = "SELECT * FROM " + TABELA + ";";
        Cursor c = getReadableDatabase().rawQuery(sql, null);


        while (c.moveToNext()){
            Cliente cliente = new Cliente();

            cliente.setId(c.getLong(c.getColumnIndex("id")));
            cliente.setNome(c.getString(c.getColumnIndex("nome")));
            cliente.setTelefone(c.getString(c.getColumnIndex("telefone")));
            cliente.setEndereco(c.getString(c.getColumnIndex("endereco")));
            cliente.setEmail(c.getString(c.getColumnIndex("email")));
            cliente.setNota(c.getDouble(c.getColumnIndex("nota")));
            cliente.setCaminhoFoto(c.getString(c.getColumnIndex("caminhoFoto")));

            clientes.add(cliente);
        }

        return clientes;
    }

    public void deletar(Cliente cliente) {
        String[] args = {cliente.getId().toString()};
        getWritableDatabase().delete("Cliente", "id=?", args);

    }

}
9 respostas

Oi Cristiano, tudo bem?

Acredito que o NullPointerException é porque você não está atribuindo o cliente que é o item da lista ao campo cliente da classe. Devido isso você está passando um cliente com id nulo, que é quando deve ocorrer o erro.

Tenta registrar o evento OnItemLongClickListener para que sempre que o usuário der um clique longo ele fazer essa atribuição. Fica mais ou menos assim:

public class ListaClientesActivity extends Activity{

    private ListView lista;
    private Cliente clienteSelecionado;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // código...

        lista.setOnItemLongClickListener(newAdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapter, View view, int posicao, long id) {
                clienteSelecionado = (Cliente) adapter.getItemAtPosition(posicao);

                return false;
            }
        });
    }
    // código
}

Faz sentido?

Abraço!

Eu entendi, mas continua o mesmo erro. No método "LongClick" a variável clienteSelecionado apresenta que não esta sendo usada.

Opa Cristiano. Pode postar como ficou o código de toda a Activity após a mudança?

Abraço.

Da forma que o Lucas explicou ta correta, e o atributo 'clienteSelecionado' está como não usado porque realmente não está sendo. Fazendo:

clienteSelecionado = (Cliente) adapter.getItemAtPosition(posicao); você está atribuindo um valor a ele mas não o está utilizando em nenhum lugar, para utiliza-lo você deve substituir :

dao.deletar(cliente); por dao.deletar(clienteSelecionado);

Já havia alterado.

Segue o código:

public class ListaClientesActivity extends Activity{

    private ListView lista;
    Cliente clienteSelecionado;



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

        lista = (ListView) findViewById(R.id.lista);
        registerForContextMenu(lista);    

        //Clique normal
        lista.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter, View view,
                    int posicao, long id) {

                Intent irParaFormulario = new Intent(ListaClientesActivity.this, FormularioActivity.class);
                startActivity(irParaFormulario);

                Toast.makeText(ListaClientesActivity.this, "A posição é: " + posicao, Toast.LENGTH_SHORT).show();                
            }
        });



        //Clique Longo
        lista.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> adapter, View view,
                    int posicao, long id) {
                Cliente clienteSelecionado = (Cliente) adapter.getItemAtPosition(posicao);
                return false;
            }
        });


    }

    @Override
    protected void onResume() {

        carregaLista();
        super.onResume();
        ClienteDAO dao = new ClienteDAO(this);
        List<Cliente> clientes = dao.getLista();

        ArrayAdapter<Cliente> adapter = 
            new ArrayAdapter<Cliente>(this, android.R.layout.simple_list_item_1, clientes); 
        lista.setAdapter(adapter);

    }

        private void carregaLista() {
            ClienteDAO dao = new ClienteDAO(this);
            List<Cliente> clientes = dao.getLista();

            ArrayAdapter<Cliente> adapter = 
                new ArrayAdapter<Cliente>(this, android.R.layout.simple_list_item_1, clientes); 
            lista.setAdapter(adapter);


        }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_listaclientes, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
        case R.id.novo:
            Intent irParaFormulario = new Intent(ListaClientesActivity.this, FormularioActivity.class); 
            startActivity(irParaFormulario);
            break;

        default:
            break;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        menu.add("Ligar");
        menu.add("Enviar SMS");
        menu.add("Achar no Mapa");
        menu.add("Navegar no site");
        MenuItem deletar = menu.add("Deletar");
        deletar.setOnMenuItemClickListener(new OnMenuItemClickListener() {

            @Override
            public boolean onMenuItemClick(MenuItem item) {
                ClienteDAO dao = new ClienteDAO(ListaClientesActivity.this);
                dao.deletar(clienteSelecionado);
                Toast.makeText(ListaClientesActivity.this, 
                        "Clicou no Botão", Toast.LENGTH_LONG).show();

                dao.close();
                carregaLista();

                return false;
            }
        });

        menu.add("Enviar E-Mail");

        super.onCreateContextMenu(menu, v, menuInfo);
    }
}

Opa Cristiano.

O problema agora, provavelmente, é que no evento do clique longo você declarou localmente a variável clienteSelecionado e acabou sombreando o atributo que é compartilhado em todos os métodos da classe. Por isso permanece o problema e ele diz que o atributo clienteSelecionado não é usado.

No lugar de:

Cliente clienteSelecionado = (Cliente) adapter.getItemAtPosition(posicao);

Faz:

clienteSelecionado = (Cliente) adapter.getItemAtPosition(posicao);

Fica assim:

public class ListaClientesActivity extends Activity{

    private ListView lista;
    private Cliente clienteSelecionado; // atributo

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

        lista = (ListView) findViewById(R.id.lista);
        registerForContextMenu(lista);    

        //Clique normal
        lista.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter, View view,
                    int posicao, long id) {

                Intent irParaFormulario = new Intent(ListaClientesActivity.this, FormularioActivity.class);
                startActivity(irParaFormulario);

                Toast.makeText(ListaClientesActivity.this, "A posição é: " + posicao, Toast.LENGTH_SHORT).show();                
            }
        });



        //Clique Longo
        lista.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> adapter, View view,
                    int posicao, long id) {
                clienteSelecionado = (Cliente) adapter.getItemAtPosition(posicao);
                return false;
            }
        });


    }

    @Override
    protected void onResume() {

        carregaLista();
        super.onResume();
        ClienteDAO dao = new ClienteDAO(this);
        List<Cliente> clientes = dao.getLista();

        ArrayAdapter<Cliente> adapter = 
            new ArrayAdapter<Cliente>(this, android.R.layout.simple_list_item_1, clientes); 
        lista.setAdapter(adapter);

    }

        private void carregaLista() {
            ClienteDAO dao = new ClienteDAO(this);
            List<Cliente> clientes = dao.getLista();

            ArrayAdapter<Cliente> adapter = 
                new ArrayAdapter<Cliente>(this, android.R.layout.simple_list_item_1, clientes); 
            lista.setAdapter(adapter);


        }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_listaclientes, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
        case R.id.novo:
            Intent irParaFormulario = new Intent(ListaClientesActivity.this, FormularioActivity.class); 
            startActivity(irParaFormulario);
            break;

        default:
            break;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        menu.add("Ligar");
        menu.add("Enviar SMS");
        menu.add("Achar no Mapa");
        menu.add("Navegar no site");
        MenuItem deletar = menu.add("Deletar");
        deletar.setOnMenuItemClickListener(new OnMenuItemClickListener() {

            @Override
            public boolean onMenuItemClick(MenuItem item) {
                ClienteDAO dao = new ClienteDAO(ListaClientesActivity.this);
                dao.deletar(clienteSelecionado);
                Toast.makeText(ListaClientesActivity.this, 
                        "Clicou no Botão", Toast.LENGTH_LONG).show();

                dao.close();
                carregaLista();

                return false;
            }
        });

        menu.add("Enviar E-Mail");

        super.onCreateContextMenu(menu, v, menuInfo);
    }
}

Vê se funciona e nos avisa?

Abraço!

Orra, você é o cara. Funcionou direitinho. MUITO OBRIGADO!

solução!

Aêee Cristiano, fico feliz que tenha funcionado!

Qualquer dúvida estamos por aqui.

Encerra o tópico, por favor?

Abraço!

Nossa mano, eu estava com o mesmo problema, graças ao Lucas consegui resolver também. Ressaltando, na explicação do vídeo e do exercício não está claro que devíamos tirar o tipo da variável depois que declaramos ela localmente na classe.