Query não retorna nada para o cursor

Oi gente, não sei porque, o cursor não está recebendo nada da query, abaixo vão as classes envolvidas na situação: A primeira classe, na linha 37, chama um método da segunda, a segunda(através do método que começa na linha 40) deve retornar um List para o ListView da primeira.

package meus.contatos;

import java.util.List;

import meus.contatos.auxiliares.Contato;
import meus.contatos.auxiliares.ContatosListAdapter;
import meus.contatos.auxiliares.LerGravarExcluir;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class ListarContatos extends Activity implements OnItemClickListener {
	
	List<Contato> contatos;
	ListView listViewContatos;
	LerGravarExcluir acoesBancoDados;
		    
    @Override
    public void onCreate(Bundle savedInstanceState) { 
    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listarcontatos);
        
        listViewContatos = (ListView) findViewById(R.id.contatosListView);
                                       
        acoesBancoDados = new LerGravarExcluir(this);
        
        contatos = acoesBancoDados.listarContatos();       
        listViewContatos.setAdapter(new ContatosListAdapter(this, contatos)); 
        listViewContatos.setOnItemClickListener(this);
    }
    
    public boolean onCreateOptionsMenu(Menu menu){   	
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.menu, menu);
    	return true;    	
    }
    
    public boolean onOptionsItemSelected(MenuItem item){
    	
    	switch(item.getItemId()){
    	
    	case R.id.novo_contato:
    		Intent it = new Intent (this, IncluirContato.class);
    		startActivity(it);
    		finish();
    		return true;
    		
    	case R.id.sair:
    		finish();    		
    		return true;
    		
    	default:   		
    		return false;
    	}
    }
                                      
	public void onItemClick(AdapterView<?> parent, View view, int posicao, long identification) {
		
		Contato cont = (Contato) listViewContatos.getAdapter().getItem(posicao);
				
		String nome = cont.getNome();
		String email = cont.getEmail();
		String codPaisCidade = cont.getCodPaisCidade();
		String fone = cont.getFone();
		String endereco = cont.getEndereco();
		String cidade = cont.getCidade();		
		String pais = cont.getPais();
		int indice = posicao;
		
		Intent it = new Intent (this, DetalhesContato.class);		
		it.putExtra("nome", nome);
		it.putExtra("email", email);
		it.putExtra("codPaisCidade", codPaisCidade);
		it.putExtra("fone", fone);	
		it.putExtra("endereço", endereco);
		it.putExtra("cidade", cidade);		
		it.putExtra("país", pais);
		it.putExtra("indice", indice);
		
		startActivity(it);
		finish();
		
	}
	
	protected void onDestroy() {
		super.onDestroy();
		//Fecha o Banco de Dados
		acoesBancoDados.fechar();
	}
				    
}
package meus.contatos.auxiliares;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class LerGravarExcluir {
	
	//Nome do banco
	private static final String NOME_BANCO = "lista_contatos";
	//Nome da tabela
	public static final String NOME_TABELA = "contatos";

	protected SQLiteDatabase db;
	
	Cursor cursor;
	
	List<Contato> contatos;
	
	
	//Método construtor
	public LerGravarExcluir(Context ctx) {
		// Abre o banco de dados já existente
		db = ctx.openOrCreateDatabase(NOME_BANCO, Context.MODE_PRIVATE, null);
	}
	
	
	
	/*
	O dois método abaixo retorna um list, que será usado para "fabricar", dentro da classe 
	ContatosListAdapter, o conteúdo do ListView.
	*/
			
	public List<Contato> listarContatos() {		
				
        try {       	
        	//select * from contatos
			cursor = db.query(NOME_TABELA, Contato.colunas, null, null, null, null, null, null);															        	
        }catch (SQLException e) {
         	Log.e("Erro", e.toString());
         } 
         	         	         	                 
        contatos = new ArrayList<Contato>();
        
        if (cursor == null) {
        	Log.e("Erro", "Cursor nulo");
        }else{

        	if (cursor.moveToFirst()) {

        		//Recupera os índices das colunas
        		int idxId = cursor.getColumnIndex(Contato.ID);
        		int idxNome = cursor.getColumnIndex(Contato.NOME);
        		int idxEmail = cursor.getColumnIndex(Contato.EMAIL);
        		int idxCodPaisCidade = cursor.getColumnIndex(Contato.COD_PAIS_CIDADE);
        		int idxFone = cursor.getColumnIndex(Contato.FONE);
        		int idxEndereco = cursor.getColumnIndex(Contato.ENDERECO);
        		int idxCidade = cursor.getColumnIndex(Contato.CIDADE);			
        		int idxPais = cursor.getColumnIndex(Contato.PAIS);

        		//Loop até o final
        		do {
        			Contato contato = new Contato();
				
        			//recupera os atributos de contato
        			contato.setId(cursor.getLong(idxId));
        			contato.setNome(cursor.getString(idxNome));
        			contato.setEmail(cursor.getString(idxEmail));
        			contato.setCodPaisCidade(cursor.getString(idxCodPaisCidade));
        			contato.setFone(cursor.getString(idxFone));
        			contato.setEndereco(cursor.getString(idxEndereco));
        			contato.setCidade(cursor.getString(idxCidade));				
        			contato.setPais(cursor.getString(idxPais));
				
        			contatos.add(contato);

        		} while (cursor.moveToNext());
        	}
        	
        	cursor.close();
		
        }
		
        return contatos;
				
	}
	
	
			
	//Atualiza um contato
	public void atualizarContato (Contato contato) {
		
		ContentValues values = new ContentValues();
		
		values.put(Contato.NOME, contato.getNome());
		values.put(Contato.EMAIL, contato.getEmail());
		values.put(Contato.COD_PAIS_CIDADE, contato.getCodPaisCidade());
		values.put(Contato.FONE, contato.getFone());
		values.put(Contato.ENDERECO, contato.getEndereco());
		values.put(Contato.CIDADE, contato.getCidade());		
		values.put(Contato.PAIS, contato.getPais());
		
		long id = contato.getId();
		
		String where = "ID =" + id;
		
		db.update(NOME_TABELA, values, where, null);				
		
	}
	
	
	
	//Insere um contato
	public void inserirContato (String nome, String email, String codPaisCidade, String fone, String endereco, 
	String cidade, String pais) {
		
		ContentValues values = new ContentValues();
		values.put(Contato.NOME, nome);
		values.put(Contato.EMAIL, email);
		values.put(Contato.COD_PAIS_CIDADE, codPaisCidade);
		values.put(Contato.FONE, fone);
		values.put(Contato.ENDERECO, endereco);
		values.put(Contato.CIDADE, cidade);		
		values.put(Contato.PAIS, pais);
		
		db.insert(NOME_TABELA, "", values);
		
	}
	
	
	
	//Apaga um contato
	public void apagarContato(Contato contato) {
		
		long id = contato.getId();		
		String where = "ID =" + id;
		db.delete(NOME_TABELA, where, null);
		
	}
	
	
	
	//Fecha o banco
	public void fechar() {		
		db.close();
	}

}
package meus.contatos.auxiliares;

public class Contato {
	
	private Long id;	
	private String nome;
	private String email;
	private String codPaisCidade;
	private String fone;
	private String pais;	
	private String cidade;
	private String endereco;
	
	public static final String ID = "ID";
	public static final String NOME = "nome";
	public static final String EMAIL = "email";
	public static final String COD_PAIS_CIDADE = "codPaisCidade";
	public static final String FONE = "fone";
	public static final String ENDERECO = "endereco";
	public static final String CIDADE = "cidade";	
	public static final String PAIS = "pais";
	
	public static String[] colunas = new String[] { ID, NOME, EMAIL, COD_PAIS_CIDADE, FONE, ENDERECO, CIDADE, PAIS};
	
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}
	
	public String getNome() {
		return nome;
	}
	
	public void setNome(String nome) {
		this.nome = nome;
	}		
	
	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getCodPaisCidade() {
		return codPaisCidade;
	}

	public void setCodPaisCidade(String codPaisCidade) {
		this.codPaisCidade = codPaisCidade;
	}

	public String getFone() {
		return fone;
	}
	
	public void setFone(String fone) {
		this.fone = fone;
	}
	
	public String getEndereco() {
		return endereco;
	}
	
	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}
	
	public String getCidade() {
		return cidade;
	}
	
	public void setCidade(String cidade) {
		this.cidade = cidade;
	}
			
	public String getPais() {
		return pais;
	}
	
	public void setPais(String pais) {
		this.pais = pais;
	}			
					
}

Só por curiosidade, vc não tem interesse em usar uma ferramenta ORM para Android?

e o que é isso?

Removi e recoloquei o arquivo do banco de dados (o que vc faz no SQLite e depois insere na pasta databases do emulador) e ficou tudo bem denovo. Não sei não, achava que banco de dados era seguro, mas estou achando muito instável, fiz primeiramente esse aplicativo usando um arquivo txt - meu projeto de conclusão do curso de Android Básico - e tô achando que txt é + confiável que banco de dados.

Tem alguma forma de tornar + estável o uso de banco de dados no Android?

Obs.: Não vi ainda content provider e ainda vou aprender como criar o banco de dados diretamente com a API, hope they’re better…

É uma ferramenta que transforma seus objetos em registros no banco de dados.
Ou seja, vc vai apenas declarar sua classe, e a ferramenta fica responsabilizada de transformar o objeto desta classe num registro no banco de dados.
Segue um breve exemplo:

[quote=nissivm]Removi e recoloquei o arquivo do banco de dados (o que vc faz no SQLite e depois insere na pasta databases do emulador) e ficou tudo bem denovo. Não sei não, achava que banco de dados era seguro, mas estou achando muito instável, fiz primeiramente esse aplicativo usando um arquivo txt - meu projeto de conclusão do curso de Android Básico - e tô achando que txt é + confiável que banco de dados.

Tem alguma forma de tornar + estável o uso de banco de dados no Android?

Obs.: Não vi ainda content provider e ainda vou aprender como criar o banco de dados diretamente com a API, hope they’re better… [/quote]

BD é muitoooo mais estável e rápido que um arquivo TXT, eu usaria um BD sem dúvida nenhuma.

É uma ferramenta que transforma seus objetos em registros no banco de dados.
Ou seja, vc vai apenas declarar sua classe, e a ferramenta fica responsabilizada de transformar o objeto desta classe num registro no banco de dados.
Segue um breve exemplo:
http://jonatasdaniel.wordpress.com/2011/07/08/andorm-framework-orm-para-android/[/quote]

Valeu pelo exemplo Jonny =]
Pergunta: o “path_do_banco” é um caminho que começa desde o drive c ? O arquivo do bd é do SQLite e pode ficar em qualquer pasta do computador, não apenas no emulador ?

É uma ferramenta que transforma seus objetos em registros no banco de dados.
Ou seja, vc vai apenas declarar sua classe, e a ferramenta fica responsabilizada de transformar o objeto desta classe num registro no banco de dados.
Segue um breve exemplo:
http://jonatasdaniel.wordpress.com/2011/07/08/andorm-framework-orm-para-android/[/quote]

Valeu pelo exemplo Jonny =]
Pergunta: o “path_do_banco” é um caminho que começa desde o drive c ? O arquivo do bd é do SQLite e pode ficar em qualquer pasta do computador, não apenas no emulador ?[/quote]

O path do banco é o local onde se encontra seu BD no seu emulador, por exemplo: "/sdcard/meu_banco.sqlite"
Aí vc precisa ver em que local que vc jogou seu banco de dados.

Mas eu posso jogar o banco de dados(o arquivo feito no SQLite) em qualquer pasta do computador?

E o path do banco pode ser tipo: “C:\pasta1\pasta2\pasta3\pasta4\pasta5\banco_de_dados.bd” ?

[quote=nissivm]Mas eu posso jogar o banco de dados(o arquivo feito no SQLite) em qualquer pasta do computador?

E o path do banco pode ser tipo: “C:\pasta1\pasta2\pasta3\pasta4\pasta5\banco_de_dados.bd” ?

[/quote]

Não, vc tem que jogar no seu emulador.
Uma pergunta, vc está utilizando Eclipse? Usando emulador ou um aparelho real?

Chamo o emulador pelo Eclipse.

Então, use o File Explorer para jogar seu BD para o emulador:
http://sree.cc/google/file-explorer-for-android-in-eclipse-ide

E informe ao AndOrm qual é o caminho que vc jogou o BD no emulador.

Valeu j0nny =]

Deu certo?

Fiz essas perguntas para poder ter tudo pronto para testar depois, primeiro vou concluir a parte de banco de dados - falta a parte de criar o banco de dados diretamente com a API.

Mas falando em estabilidade, agora mesmo coloquei para carregar o meu app num AVD novo que criei, a página que abre automático faz, tudo no onCreate, uma pesquisa no banco de dados para retornar todos os registros do bd na forma de um List de objetos Contato(classe auxiliar que criei), depois, esse List é inserido numa classe que extende BaseAdapter, que por sua sua vez retorna o conteúdo do ListView exibido nessa página que abre automático. Só que no log apareceu “cursor nulo”, como se não houvesse um arquivo de banco de dados no emulador e tem. No AVD que eu estava executando anteriormente estava tudo certinho. Imagine isso num celular real! Acho que é por isso que no livro Google Android o autor recomenda criar o bd na própria API…

Se estou fazendo algo errado, não faço idéia do que seja…

[quote=nissivm]Fiz essas perguntas para poder ter tudo pronto para testar depois, primeiro vou concluir a parte de banco de dados - falta a parte de criar o banco de dados diretamente com a API.

Mas falando em estabilidade, agora mesmo coloquei para carregar o meu app num AVD novo que criei, a página que abre automático faz, tudo no onCreate, uma pesquisa no banco de dados para retornar todos os registros do bd na forma de um List de objetos Contato(classe auxiliar que criei), depois, esse List é inserido numa classe que extende BaseAdapter, que por sua sua vez retorna o conteúdo do ListView exibido nessa página que abre automático. Só que no log apareceu “cursor nulo”, como se não houvesse um arquivo de banco de dados no emulador e tem. No AVD que eu estava executando anteriormente estava tudo certinho. Imagine isso num celular real! Acho que é por isso que no livro Google Android o autor recomenda criar o bd na própria API…

Se estou fazendo algo errado, não faço idéia do que seja…[/quote]

Mas isso usando o AndOrm?
Tente criar o BD por fora e jogue ele no emulador pra testar.

Não, foi criando o bd pelo SQLite Expert Personal 3, nele mesmo já adicionei alguns registros, depois joguei ele em data\data\nome_do_pacote\databases

Estava tudo bem no AVD anterior que estava usando, mas nesse recém-criado, é como se o arquivo do bd não existisse, mas aí, é só eu substituir o arquivo que estava no emulador pelo original criado no SQLite que tudo volta ao normal. O tamanho do arquivo que não estava sendo encontrado era 3072, o original criado no SQLite é 4096, sendo que o que não estava sendo encontrado tinha mais registros, tu tem alguma idéia de qual seja a causa de tudo isso??

Obs.: Sempre acontece isso ao abrir o app num AVD novo

[quote=nissivm]Não, foi criando o bd pelo SQLite Expert Personal 3, nele mesmo já adicionei alguns registros, depois joguei ele em data\data\nome_do_pacote\databases

Estava tudo bem no AVD anterior que estava usando, mas nesse recém-criado, é como se o arquivo do bd não existisse, mas aí, é só eu substituir o arquivo que estava no emulador pelo original criado no SQLite que tudo volta ao normal. O tamanho do arquivo que não estava sendo encontrado era 3072, o original criado no SQLite é 4096, sendo que o que não estava sendo encontrado tinha mais registros, tu tem alguma idéia de qual seja a causa de tudo isso??

Obs.: Sempre acontece isso ao abrir o app num AVD novo[/quote]

Sim, se vc criar outro AVD, vc deverá jogar o BD novamente, pq é como se fosse outro aparelho.

Bom, então acredito que isso seja impraticável para um celular de verdade, não? Porque como o usuário vai pegar o bd e jogar no lugar certo dentro do celular dele??

Exatamente, por isso que uma das próximas funcionalidades do AndOrm será criar as tabelas a partir das classes.
Mas falei pra vc fazer assim apenas para testar.