Meu projeto usando Sqlite em Android não funciona [RESOLVIDO]

Olá pessoal!

É a 1ª vez que posto no Guj. Se eu cometer algum erro de postagem, peço perdão desde já.

Enfim, estou criando um projeto e apenas parte dele funciona. Ele possui 3 tabelas, e destas, apenas 1 faz a pesquisa no Sqlite de forma correta. Por algum motivo desconhecido as outras 2 não o fazem corretamente. As tabelas se chamam Disciplina, Pergunta e Resposta. A pesquisa que funciona é a da tabela Pergunta.

Porém, quando insiro um dado na tabela Resposta, e faço sua pesquisa, ela funciona! Isso é intrigante.

Se alguém quiser dar uma olhada no meu projeto, eis o link dele logo abaixo.

http://www.4shared.com/rar/G7bta9S_/TesteSqlite.html

Gostaria de entender onde errei neste programa, pois ultimamente venho tentando manipular banco de dados em Android, mas sempre surge algum erro que impede que tudo funcione.

Oi,

Olha esse post: http://debugcodigos.blogspot.com/2011/06/sqlite-para-android-como-utilizar.html

Espero ajudar. Qualquer coisa, fala ae.
Abraço.

Olá Felipe!

Estava dando uma olhada no seu link. A classe DataBase extende da classe SQLiteOpenHelper. Porém, neste link, a classe SQLiteOpenHelper não está explicitada.

Por isso, saí pelo Google procurando pela implementação de tal classe, e a encontrei no link abaixo:

http://www.netmite.com/android/mydroid/cupcake/frameworks/base/core/java/android/database/sqlite/SQLiteOpenHelper.java

Porém, está classe dá erro nos métodos .lock e .unlock da variável mDatabase, cuja declaração é:

Logo, seu link não funciona para meu teste.

Será que alguém não tem um exemplo básico de CRUD (Create, Read, Update e Delete) em SQLite de Android? Os que testei de sites como o do Felipe Silveira, e do livro do Ricardo Lecheta, funcionam em parte, mas não em sua totalidade.

O que eu precisava era de um CRUD que relacionasse 3 tabelas entre si, e que soubesse diferenciar quando o banco já foi criado e quando ele ainda não foi.

Ué, o que eu te enviei faz o que você quer.
Quando você instancia, se ele não foi criado, ele cria. Se ele já está criado, ele apenas referência o database.

Acho que você não estendeu muito bem, :stuck_out_tongue:

Opa, então testarei sem instanciar mesmo…

Olá!

Criei um projeto com as dicas daquele link que você me passou. Eis a estrutura do projeto:

http://www.4shared.com/photo/vnYFGHQh/FelipeBonezi.html

Eis o conteúdo da classe Disciplina.java:

package br.com.android.projeto.bean;

public class Disciplina {
	private Integer id;
    private String nome;
    
    public Disciplina() {
    	
    }
    
    public Disciplina(Integer id, String nome) {
    	this.id = id;
    	this.nome = nome;
    }
    
	@Override
	public String toString() {
		return "Disciplina [id: " + id + ", nome: " + nome + "]";
	}

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
}

Eis o conteúdo da classe DataBase.java:

package br.com.android.projeto.dao;

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

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import br.com.android.projeto.bean.Disciplina;

public class DataBase extends SQLiteOpenHelper {
	private static String BANCO = "quizz";
	private SQLiteDatabase db = getWritableDatabase();
	private ContentValues cv = new ContentValues();
	
	public DataBase(Context context) {
		super(context, BANCO, null, 1);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table disciplina (id integer primary key autoincrement, " +
			"nome text not null)");
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
	}
	
	public void inserirDisciplina(Disciplina d) {
		cv.put("id", d.getId());
		cv.put("nome", d.getNome());
		// Inserindo
		db.insert(BANCO, null, cv);
		// Sempre é recomendado fechar o banco de dados para não haver perda de
		// memória ou até uma possível invasão de dados
		db.close();
	}

	public List<Disciplina> listarDisciplinas() {
		Disciplina d;
		// Criando nossa lista com os dados que estão contido no DB
		ArrayList<Disciplina> lista = new ArrayList<Disciplina>();
		// Inicializando modo de leitura do DB
		SQLiteDatabase db = getReadableDatabase();
		// Cursor apontará para a tabela e organizará por ordem de valor do id
		Cursor c = db.query(BANCO, null, null, null, null, null, "id");
		// Checando se o DB contém algo
		if (c.getCount() > 0) {
			// Cursor está apontando para a coluna com id = 0
			c.moveToFirst();
			// Enquanto não for a última coluna
			while (!c.isAfterLast()) {
				// Lendo os dados do DB
				Integer id = c.getInt(0);
				String nome = c.getString(1);
				d = new Disciplina(id, nome);
				// Adicionando os dados lidos na lista criada
				lista.add(d);
				c.moveToNext();
			}
		}
		// Fechando cursor e database
		c.close();
		db.close();
		return lista;
	}
}

Eis o conteúdo da classe LoginActivity.java:

package br.com.android.projeto;

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

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import br.com.android.projeto.bean.Disciplina;
import br.com.android.projeto.dao.DataBase;

public class LoginActivity extends Activity {
	public static final String CATEGORIA = "teste";
	private DataBase db = new DataBase(this);
	List<Disciplina> lista = new ArrayList<Disciplina>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Log.i(CATEGORIA, "LOGIN_ACTIVITY -> Layout criado.");
		// Inserindo
		Disciplina d1 = new Disciplina(1, "Geografia");
		db.inserirDisciplina(d1);
		imprime("Inserindo Disciplina: '" + d1.toString() + "'.");
		
		Disciplina d2 = new Disciplina(2, "Matemática");
		db.inserirDisciplina(d2);
		imprime("Inserindo Disciplina: '" + d2.toString() + "'.");
	}
	
	public void imprime(String texto) {
		Toast.makeText(LoginActivity.this, texto, Toast.LENGTH_SHORT).show();
		Toast.makeText(LoginActivity.this, texto, Toast.LENGTH_SHORT).show();
		Toast.makeText(LoginActivity.this, texto, Toast.LENGTH_SHORT).show();
	}
}

E eis os erros que aparecem quando executo esta aplicação:

http://www.4shared.com/photo/HTA9g7bH/Erro_FelipeBonezi.html?

http://www.4shared.com/photo/zSWwJqy4/LogCat_FelipeBonezi.html?

Ou seja, são os mesmos erros do projeto inicial que postei nesse tópico. Que erros são esses? São os que estão reforçados em azul no último link acima.

Retire a seguinte linha das variaveis da sua classe Database.

private SQLiteDatabase db = getWritableDatabase();

E dentro do seu método de incluir use:

private SQLiteDatabse db = getWritableDatabse();

Listar:

private SQLiteDataBase sb = getReadableDatabase();

=)

Eu modifiquei a classe DataBase.java para o seguinte código, obedecendo suas dicas. Eu mantive a linha 16 porque ela é usada no método onCreate():

package br.com.android.projeto.dao;

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

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import br.com.android.projeto.bean.Disciplina;

public class DataBase extends SQLiteOpenHelper {
	private static String BANCO = "quizz";
	private SQLiteDatabase db;
	private ContentValues cv = new ContentValues();
	
	public DataBase(Context context) {
		super(context, BANCO, null, 1);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table disciplina (id integer primary key autoincrement, " +
			"nome text not null)");
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
	}
	
	public void inserirDisciplina(Disciplina d) {
		db = getWritableDatabase();  
		cv.put("id", d.getId());
		cv.put("nome", d.getNome());
		// Inserindo
		db.insert(BANCO, null, cv);
		// Sempre é recomendado fechar o banco de dados para não haver perda de
		// memória ou até uma possível invasão de dados
		db.close();
	}

	public List<Disciplina> listarDisciplinas() {
		Disciplina d;
		// Criando nossa lista com os dados que estão contido no DB
		ArrayList<Disciplina> lista = new ArrayList<Disciplina>();
		// Inicializando modo de leitura do DB
		db = getReadableDatabase();
		Log.i("teste", "'ReadableDatabase()' obtido.");
		// Cursor apontará para a tabela e organizará por ordem de valor do id
		Cursor c = db.query(BANCO, null, null, null, null, null, "id");
		Log.i("teste", "Query executada.");
		// Checando se o DB contém algo
		if (c.getCount() > 0) {
			// Cursor está apontando para a coluna com id = 0
			c.moveToFirst();
			Log.i("teste", "Cursor no primeiro registro.");
			// Enquanto não for a última coluna
			while (!c.isAfterLast()) {
				// Lendo os dados do DB
				Integer id = c.getInt(0);
				String nome = c.getString(1);
				d = new Disciplina(id, nome);
				// Adicionando os dados lidos na lista criada
				lista.add(d);
				c.moveToNext();
			}
		}
		// Fechando cursor e database
		c.close();
		db.close();
		return lista;
	}
}

Na classe LoginActivity.java, descomentei as linhas 31 até 37:

package br.com.android.projeto;

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

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import br.com.android.projeto.bean.Disciplina;
import br.com.android.projeto.dao.DataBase;

public class LoginActivity extends Activity {
	private DataBase db = new DataBase(this);
	List<Disciplina> lista = new ArrayList<Disciplina>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Log.i("teste", "Layout criado.");
		// Inserindo
		Disciplina d1 = new Disciplina(1, "Geografia");
		db.inserirDisciplina(d1);
		imprime("Inserindo Disciplina: '" + d1.toString() + "'.");
		
		Disciplina d2 = new Disciplina(2, "Matemática");
		db.inserirDisciplina(d2);
		imprime("Inserindo Disciplina: '" + d2.toString() + "'.");
		
		imprime("Listando Disciplinas:");
		Log.i("teste", "Listando disciplinas.");
		lista = db.listarDisciplinas();
		for (Disciplina d : lista) {
			Log.i("teste", "Listando disciplinas, dentro do while.");
			imprime(d.toString());
		}
	}
	
	public void imprime(String texto) {
		Toast.makeText(LoginActivity.this, texto, Toast.LENGTH_SHORT).show();
		Toast.makeText(LoginActivity.this, texto, Toast.LENGTH_SHORT).show();
		Toast.makeText(LoginActivity.this, texto, Toast.LENGTH_SHORT).show();
	}
}

Os erros obtidos são os mesmos que comecei a obter terça-feira da semana passada, que são erros como no such table, java.lang.RuntimeException: Unable to start activity ComponentInfo. Só a clássica Caused by: java.lang.NullPointerException, seguida de at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) que não apareceu desse vez.

[list]
02-07 19:42:46.388: I/teste(419): Listando disciplinas.
02-07 19:42:46.418: I/teste(419): ‘ReadableDatabase()’ obtido.
02-07 19:42:46.418: I/Database(419): sqlite returned: error code = 1, msg = no such table: quizz
02-07 19:42:46.418: D/AndroidRuntime(419): Shutting down VM
02-07 19:42:46.428: W/dalvikvm(419): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
02-07 19:42:46.448: E/AndroidRuntime(419): FATAL EXCEPTION: main
02-07 19:42:46.448: E/AndroidRuntime(419): java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.android.projeto/br.com.android.projeto.LoginActivity}: android.database.sqlite.SQLiteException: no such table: quizz: , while compiling: SELECT * FROM quizz ORDER BY id
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.os.Handler.dispatchMessage(Handler.java:99)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.os.Looper.loop(Looper.java:123)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread.main(ActivityThread.java:4627)
02-07 19:42:46.448: E/AndroidRuntime(419): at java.lang.reflect.Method.invokeNative(Native Method)
02-07 19:42:46.448: E/AndroidRuntime(419): at java.lang.reflect.Method.invoke(Method.java:521)
02-07 19:42:46.448: E/AndroidRuntime(419): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-07 19:42:46.448: E/AndroidRuntime(419): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-07 19:42:46.448: E/AndroidRuntime(419): at dalvik.system.NativeStart.main(Native Method)
02-07 19:42:46.448: E/AndroidRuntime(419): Caused by: android.database.sqlite.SQLiteException: no such table: quizz: , while compiling: SELECT * FROM quizz ORDER BY id
[/list]

A questão é:

Eu preciso de um projeto Android que acesse banco de dados, e que crie tabelas (ou leia-as caso já existam), remova, insira e atualize, sem dar erros como os listados acima.

Já tentei diversas abordagens (Felipe Silveira, Ricardo Lecheta, Felipe Bonezi), mas elas sempre funcionam pela metade (ou só inserem, ou só pesquisam, ou só criam tabela toda vez, etc).

http://www.luiztools.com/post/Criando-uma-app-Android-com-banco-de-dados-SQLite.aspx


Cara tem que funcionar se nao tem algo errado no Projeto

public List<Pessoa> getLista(){ Cursor c = getWritableDatabase().query(TABELA, COLUNAS, null, null, null, null, null); List<Pessoa> lista = new ArrayList<Pessoa>(); while(c.moveToNext()){ Pessoa pessoa = new Pessoa(); pessoa.setId(c.getInt(0)); pessoa.setNome(c.getString(1)); pessoa.setTelefone(c.getString(2)); pessoa.setEndereco(c.getString(3)); pessoa.setSite(c.getString(4)); pessoa.setFoto(c.getString(5)); lista .add(pessoa); } c.close(); return lista; }

Opa, valeu pela ajuda Marcelo!

Darei uma lida nesses links e testarei aqui.

Olá Marcelo.

Sobre os 3 links, sinceramente, eu os achei bastante incompletos.

Faltam trechos de código e as explicações são meio vagas as vezes. Em algumas partes há trechos de código a serem digitados mas não se sabe em que arquivo .java devem-se digitá-los.

Para ambos os exemplos (1º, e o 2º e 3º links), quando terminei de copiar os códigos passados pelos tutoriais, o que via na tela era um monte de erros, simplesmente porque faltavam linhas de código ou porque não havia sido explicitada alguma estrutura do layout.

Tentei baixar o código-fonte do exemplo do Yuri Adams, porém, aquele Github está sempre fora do ar.

Sigo tentando encontrar um exemplo completo de CRUD em Android, para que enfim eu possa concluir que o manuseamento de Banco de Dados em Android é possível e fácil de ser implementado.

Alguém aqui do Guj poderia postar um projeto completo de CRUD em Android? É só isso que peço. Eu daria uma olhada no código-fonte e me viraria. Mas para me virar, preciso ter um exemplo funcional.

Acho muito mais simples ter o código completo para dar uma olhada do que tutoriais incompletos que nos induzem a completar de forma aleatória os trechos de código que ficam faltando.

Depois de 13 tentativas esta noite (estava a 8 horas sem parar tentando), e 22 no total (desde segunda-feira passada), achei um link que resolveu meu problema:

http://www.androidbrasilprojetos.org/android/introducao-a-banco-de-dados-android/

Ele realiza um CRUD em Android. E se o banco não existe, o cria. Se existe, o mantém.

Vou mudar o status do tópido para “resolvido”.

Estranho que o link que você disse que funciona esta parecidíssimo com o meu! :o

Vou dar uma analisada,
Parabéns.

É que o link que postei possui o código-fonte completo.

Pena que vc não colocou seu código completo meu amigo, infelizmente o link que vc postou agora está offline… continuarei minha busca

[quote=graffiti75]Eu modifiquei a classe DataBase.java para o seguinte código, obedecendo suas dicas. Eu mantive a linha 16 porque ela é usada no método onCreate():

package br.com.android.projeto.dao;

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

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import br.com.android.projeto.bean.Disciplina;

public class DataBase extends SQLiteOpenHelper {
	private static String BANCO = "quizz";
	private SQLiteDatabase db;
	private ContentValues cv = new ContentValues();
	
	public DataBase(Context context) {
		super(context, BANCO, null, 1);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table disciplina (id integer primary key autoincrement, " +
			"nome text not null)");
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
	}
	
	public void inserirDisciplina(Disciplina d) {
		db = getWritableDatabase();  
		cv.put("id", d.getId());
		cv.put("nome", d.getNome());
		// Inserindo
		db.insert(BANCO, null, cv);
		// Sempre é recomendado fechar o banco de dados para não haver perda de
		// memória ou até uma possível invasão de dados
		db.close();
	}

	public List<Disciplina> listarDisciplinas() {
		Disciplina d;
		// Criando nossa lista com os dados que estão contido no DB
		ArrayList<Disciplina> lista = new ArrayList<Disciplina>();
		// Inicializando modo de leitura do DB
		db = getReadableDatabase();
		Log.i("teste", "'ReadableDatabase()' obtido.");
		// Cursor apontará para a tabela e organizará por ordem de valor do id
		Cursor c = db.query(BANCO, null, null, null, null, null, "id");
		Log.i("teste", "Query executada.");
		// Checando se o DB contém algo
		if (c.getCount() > 0) {
			// Cursor está apontando para a coluna com id = 0
			c.moveToFirst();
			Log.i("teste", "Cursor no primeiro registro.");
			// Enquanto não for a última coluna
			while (!c.isAfterLast()) {
				// Lendo os dados do DB
				Integer id = c.getInt(0);
				String nome = c.getString(1);
				d = new Disciplina(id, nome);
				// Adicionando os dados lidos na lista criada
				lista.add(d);
				c.moveToNext();
			}
		}
		// Fechando cursor e database
		c.close();
		db.close();
		return lista;
	}
}

Os erros obtidos são os mesmos que comecei a obter terça-feira da semana passada, que são erros como no such table, java.lang.RuntimeException: Unable to start activity ComponentInfo. Só a clássica Caused by: java.lang.NullPointerException, seguida de at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) que não apareceu desse vez.

[list]
02-07 19:42:46.388: I/teste(419): Listando disciplinas.
02-07 19:42:46.418: I/teste(419): ‘ReadableDatabase()’ obtido.
02-07 19:42:46.418: I/Database(419): sqlite returned: error code = 1, msg = no such table: quizz
02-07 19:42:46.418: D/AndroidRuntime(419): Shutting down VM
02-07 19:42:46.428: W/dalvikvm(419): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
02-07 19:42:46.448: E/AndroidRuntime(419): FATAL EXCEPTION: main
02-07 19:42:46.448: E/AndroidRuntime(419): java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.android.projeto/br.com.android.projeto.LoginActivity}: android.database.sqlite.SQLiteException: no such table: quizz: , while compiling: SELECT * FROM quizz ORDER BY id
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.os.Handler.dispatchMessage(Handler.java:99)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.os.Looper.loop(Looper.java:123)
02-07 19:42:46.448: E/AndroidRuntime(419): at android.app.ActivityThread.main(ActivityThread.java:4627)
02-07 19:42:46.448: E/AndroidRuntime(419): at java.lang.reflect.Method.invokeNative(Native Method)
02-07 19:42:46.448: E/AndroidRuntime(419): at java.lang.reflect.Method.invoke(Method.java:521)
02-07 19:42:46.448: E/AndroidRuntime(419): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-07 19:42:46.448: E/AndroidRuntime(419): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-07 19:42:46.448: E/AndroidRuntime(419): at dalvik.system.NativeStart.main(Native Method)
02-07 19:42:46.448: E/AndroidRuntime(419): Caused by: android.database.sqlite.SQLiteException: no such table: quizz: , while compiling: SELECT * FROM quizz ORDER BY id
[/list]
[/quote]

O erro acontece porque você quer fazer a querie numa tabela que não existe!! O nome do banco é “quizz” mas a tabela é "disciplina "
por isso que dá esse erro.

Eu sei que já foi resolvido, mas é um código funcional se tirar esse erro e um bom ponto de partida para quem quer se aventurar.

Até mais.