Tutorial: Utilização do sqlite no Android (Parte I)

50 Comentários

Por Mário Baltazar para o Pplware

Tutorial realizado no âmbito do Mestrado em Computação Móvel do Instituto Politécnico da Guarda na Unidade Curricular de Seminário

A plataforma Android foi introduzida no mercado pela Google em 2007 e é composta por um sistema operativo embebido e um conjunto de aplicações que integram com a plataforma.  Além das várias inovações implementadas, o Android traz também suporte nativo para o SQLite. O SQLite é uma pequena biblioteca, desenvolvida em linguagem C, que implementa um amplo subconjunto do standard SQL 92, sendo a sua reputação proveniente da combinação do motor de base de dados com a interface dentro de uma única biblioteca. As aplicações que usam SQLite podem ter assim acesso a uma base de dados racional SQL, sem a necessidade de correrem processos RDBMS (relational database management system) em separado e sem grandes overheads. O SQLite foi desenvolvido em 2000 e é actualmente uma base de dados amplamente adoptada em dispositivos móveis, suportando até 2 TB de dados.

Este artigo será dividido em duas partes e hoje vamos começar por ensinar como criar uma pequena aplicação para registo de contactos, sendo esses contactos guardados na base dados sqlite.

sqllite_00

Vamos então começar com o desenvolvimento da aplicação, usando para isso a ferramenta de desenvolvimento eclipse.

1 – Criar Projecto
Criação de um novo projecto no Eclipse com o nome: “Contactos”
File > New > Other > Android/Android Project
image

2 – Criar uma nova classe com nome DbHelper
Esta classe será responsável por criar a base de dados no momento em que a aplicação é instalada  (método onCreate) e actualizá-la para novas versões(método onUpgrade).

2.1 – A classe DB expande a classe SQLiteOpenHelper, esta fornece os métodos
getReadableDatabase() e getWriteableDatabase(), que permitem aceder à base dados SQLiteDatabase  quer para ler quer para escrever.

public class DbHelper extends SQLiteOpenHelper { }

2.2 – Adicionar os imports necessários para a classe:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

2.3 – Adicionar as constantes necessárias:

private static final int DATABASE_VERSION = 1;
public static final String ID = "_id";
public static final String NOME = "nome";
public static final String EMAIL = "email";
public static final String TELEFONE = "telefone";
public static final String FOTO = "foto";
private static final String DATABASE_CREATE = "create table "
+ TABLE_NAME + "( " + ID
+ " integer primary key autoincrement, " + NOME
+ " text not null, " + EMAIL + " text not null, "
+ TELEFONE+" text not null" +
", "+ FOTO +" BLOB);";

2.4 – Fazer @override das classes necessárias:

@Override 
public void onCreate(SQLiteDatabase db) { 
          db.execSQL(DATABASE_CREATE); 
} 
@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
          Log.w(DbHelper.class.getName(), "Upgrading database from version " + oldVersion + " 
to " + newVersion + ", which will destroy all old data"); 
          db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
onCreate(db); 
}

2.5 – No final a classe terá um aspecto parecido com o seguinte:

public class DbHelper extends SQLiteOpenHelper {
          private static final String DATABASE_NAME = "contactos4.db";
          public static final String TABLE_NAME = "contactos2";
          private static final int DATABASE_VERSION = 1;
          public static final String ID = "_id";
          public static final String NOME = "nome";
          public static final String EMAIL = "email";
          public static final String TELEFONE = "telefone";
          public static final String FOTO = "foto";
          private static final String DATABASE_CREATE = "create table "
+ TABLE_NAME + "( " + ID
+ " integer primary key autoincrement, " + NOME
+ " text not null, " + EMAIL + " text not null, "
+ TELEFONE+" text not null" +
", "+ FOTO +" BLOB);";
         public DbHelper(Context context) {
                  super(context, DATABASE_NAME, null, DATABASE_VERSION);
         }
         @Override
         public void onCreate(SQLiteDatabase db) {
                 db.execSQL(DATABASE_CREATE);
         }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                 Log.w(DbHelper.class.getName(),
                 "Upgrading database from version " + oldVersion + " to "
                 + newVersion + ", which will destroy all old data");
                db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
                onCreate(db);
        }
}

4- Criar nova classe DBAdapter que será a classe base para trabalhar com SQLite. Esta irá permitir  abrir, fechar, fazer queries e actualizar a base de dados.
4.1 – Criar nova classe DBAdapter

public class DBAdapter {
}

4.2 – Adicionar os imports necessários para a aplicação:

import java.io.ByteArrayOutputStream;
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.graphics.Bitmap;
import android.graphics.BitmapFactory;

4.3 – Adicionar os Atributos necessários para a classe:

private SQLiteDatabase database;
private DbHelper dbHelper;
private String[] allColumns = { DbHelper.ID, DbHelper.NOME, DbHelper.EMAIL,
DbHelper.TELEFONE, DbHelper.FOTO};

4.4 – Declarar construtor da classe que irá inicializar uma instância da classe DbHelper.

public DBAdapter(Context context) {          
dbHelper = new DbHelper(context);
}

Um Context é um handle para o sistema, que fornece serviços como resources, acesso a base de dados e preferências.  O contexto da aplicação (application context) é o repositório central para a funcionalidade de todas as  aplicações de nível superior no Android. Usa-se este contexto quando queremos aceder a configurações e recursos compartilhados entre as várias janelas (activities) da aplicação.

4.5 – Criar método para criar um novo contacto na base de dados, este irá retornar um objecto  Contacto.

public Contacto createContacto(String nome, String email, String telefone, Bitmap foto) { 
            ContentValues values = new ContentValues(); 
            values.put(DB.NOME, nome); 
            values.put(DB.EMAIL,email); 
            values.put(DB.TELEFONE,telefone); 
            ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
            foto.compress(Bitmap.CompressFormat.PNG, 100, baos); 
            byte[] photo = baos.toByteArray(); 
            values.put(DB.FOTO, photo); 
            long insertId = database.insert(DB.TABLE_NAME, null, values); 
           // To show how to query 
           Cursor cursor = database.query(DB.TABLE_NAME, allColumns, DB.ID + " = " + 
           insertId, null,null, null, null); 
           cursor.moveToFirst(); 
           return cursorToContacto(cursor); 
}

Os cursores são “apontadores de dados” da base de dados – ou seja, uma interface que permite o acesso aos dados retornados pela query.  O objecto ContentValues permite definir os valores a inserir.

4.6 – Método para eliminar um contacto:

public void EliminaContacto (int idContacto){ 
              database.delete(DbHelper.TABLE_NAME, DbHelper.ID + " = " + idContacto, 
               null); 
}

4.7 – Método para devolver um Contacto passando como parâmetro um cursor.

private Contacto cursorToContacto(Cursor cursor) { 
             byte[] blob = cursor.getBlob(cursor.getColumnIndex(DB.FOTO)); 
             Bitmap bmp = BitmapFactory.decodeByteArray(blob, 0, blob.length); 
             Contacto contacto = new 
             Contacto(cursor.getLong(0),cursor.getString(1),cursor.getString(2), 
             cursor.getString(3),bmp); 
             return contacto; 
}

4.8 – Método para devolver todos os contactos da tabela:

public Cursor getContactos(){ 
            Cursor cursor = database.rawQuery("select _id, nome,telefone,foto from 
            contactos2", null); 
            return cursor; 
}

4.9 – Método que devolve o contacto passando como parâmetro o id do contacto pretendido:

public Contacto getContacto (int idContacto){ 
           Cursor cursor = database.query(DB.TABLE_NAME, allColumns, DB.ID + " = " + 
           idContacto, null,null, null, null); 
           cursor.moveToFirst(); 
           return cursorToContacto(cursor); 
}

Terminamos agora a criação das classes auxiliares para trabalhar com a base de dados, no próximo tutorial iremos criar os layouts e utilizar estas classes para guardar os dados na base de dados.

Partilhar:
Tags:

Comentários

50

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *

  1. Avatar de Márcio Soares
    Márcio Soares

    @Of Topic.

    Procuro uma aplicação que me informe através de um icon na barrasuperior que a chamada que estou a receber é uma chamada reencaminhada de outro telefone se assim for o caso.
    É que tenho o meu numero fixo encaminhado para o móvel e por vezes atendo chamadas que até nem precisava de atender mas como não sei se é reencaminhada ou não tenho de atender.
    Na StockRom do meu SGS há um popup a avisar da chamada reencaminhada mas apenas aparece ao primeiro toque o que a torna inutil uma vez que não estou sempre a olhar para o ecra do mesmo.
    Algume conhece uma? Alguem se sente capaz de desenvolver algo do género?

      1. Avatar de Márcio Soares
        Márcio Soares

        Muito, mas mesmo muito, obrigado!!!
        Vou já testar essa aplicação.

  2. Avatar de ze
    ze

    Excelente! Podiam fazer mais tutoriais de como programar em android!

  3. Avatar de Tony
    Tony

    Parabéns pela iniciativa. Continue o bom trabalho e a desenvolver estes tutoriais, como interessado em programar android agradeço-lhe.

  4. Avatar de Francisco Franco

    Espetaculo! Isto vai me ser tão útil! 🙂

    1. Avatar de Marisa Pinto

      Excelente tutorial 🙂

  5. Avatar de Filipe Leandro

    Em vez de usarem SQLite cru e duro eu aconselho usarem o ORMLite (ormlite.com).
    É uma biblioteca de Object Relational Mapping muito fácil de usar, leve e extremamente poderosa. Para não falar que o código de acesso/escrita na base de dados em sqlite fica extremamente simples e fácil de utilizar.
    Se quiserem até podia escrever um artigo para principiantes.
    Neste momento estamos a utilizar esta biblioteca na nossa app que conta com um modelo de dados bastante complexo: https://play.google.com/store/apps/details?id=com.pt.stt.h19

    1. Avatar de Pedro Pinto

      Interessante também. Vou analisar melhor

    2. Avatar de sn
      sn

      Eu também estou a usar o ormlite e das alternativas que testei pareceu-me sem dúvida a melhor.

  6. Avatar de Gabriel Queiroz
    Gabriel Queiroz

    Super util e bem explicado, gostei muito, parabens

  7. Avatar de Miguel
    Miguel

    Será possivel meter um tutorial de como usar uma base de dados nossa?

    Ou seja, ter uma BD já em sqlite, e só fazer o import e leitura da BD?

    Já estive a ler uns tutorias, mas sou ainda muito verde nisto de programar.

    Obrigado desde já!

  8. Avatar de John Kain
    John Kain

    Como adicionar campos booleanos numa base dados sqlite? É que o formato booleano, penso que não existe, tal como existe o SimpleDateFormat, etc, etc.

    Se alguém souber agradeço, já que está relacionado com o tema.
    É para utilizar num campo que em caso afirmativo aparecerá “Yes” em caso negativo aparecerá “No”.

    Obrigado.

    1. Avatar de David G.
      David G.

      Eu utilizo uma string para booleanos no android. Yes ou No são as duas alternativas. No momento de avaliar a expressão faz-se um compare(“yes”).

      Ex: cursor2.getString(cursor2.getColumnIndex(“checkComprado”)).equals(“true”)

      1. Avatar de John Kain
        John Kain

        Obrigado vou tentar dessa maneira.
        Obrigado de novo.

      2. Avatar de Mário Baltazar
        Mário Baltazar

        Também poderás usar um inteiro e utilizas 0 para negativo e 1 para positivo por exemplo. Defines o que será mais facil de usar par ti.

  9. Avatar de Nuno Gonçalves
    Nuno Gonçalves

    Uma grande pergunta já que estão a falar de SQLite no Android, existe alguma plataforma como o Core Data no iPhone, é que desta maneira é basicamente um wrapper a volta do SQLite, queria se havia uma abstracção como o Core Data.

    1. Avatar de Filipe Leandro

      O que tu queres é uma biblioteca de ORM – Object Relational Mapping.
      Eu uso o ORMLite e aconselho vivamente. É muito mais fácil de usar que o SQLite nativo do Android e tem um poder brutal.

    2. Avatar de João Pedro
      João Pedro

      Atenção que nem sempre o recurso a ORMs é a melhor solução. Estamos a desenvolver para dispositivos móveis e é necessário ter em conta factores como performance e utilização de bateria.
      ORMlite tem uma footprint mt pequena mas mesmo assim as vezes é preciso analisar bem o que se quer fazer.
      De resto, ORMLite ->Gosto

  10. Avatar de Rudy
    Rudy

    Muito bom o post, você esta de parabéns.

    Você fala que a classe DbHelper, serve para criar o banco de dados no momento em que a app for instalada. Após o banco for criado as informações são mantidas nele mesmo após encerrar o app ou até mesmo após reiniciar o aparelho?

    1. Avatar de Filipe Leandro

      Claro, é para isso que serve uma base de dados. Persistência dos dados.

  11. Avatar de José Fonseca
    José Fonseca

    Muito bem Mário!
    Gostei muito do tutorial. Como podes ver pelos posts, podes continuar a desenvolver o tema 😉
    Não pares.

    1. Avatar de Mário Baltazar
      Mário Baltazar

      Muito obrigado.
      Vou continuar 🙂

      1. Avatar de Pedro Pinto

        Já cá tenho a parte 2 🙂

        1. Avatar de xanex
          xanex

          Boas, bom tuturial 🙂

          onde esta esse parte 2? 😛

  12. Avatar de Joao
    Joao

    Falta um pouco mais de comentarios no codigo.. torna-se um pouco complicado para quem está a começar..

    1. Avatar de Danilo Tostes
      Danilo Tostes

      Concordo plenamente. Percebi isso quando fui tentar implementar, embora não tão leigo assim. Imagine um sem noção alguma? Hehehe

  13. Avatar de Rafael Sandim
    Rafael Sandim

    Excelente tutorial, estou com um probleminha quando tendo fazer em uma query o where e neste where eu quero pegar os tuplas aonde tenho “path=”+str, e str é igual a uma string deste formato “/mnt/sdcard/folder/teste/”

    porém quando eu tento fazer isso aparece um erro no logcat, informando erro perto do ‘/’, já fiz teste com strings e não tive problemas, porém quando eu coloco ‘/’ dispara erro.

    Alguém pode me ajudar?

  14. Avatar de Alex
    Alex

    Olá,

    Todas as linhas que tem DB.alguma coisa dá erro, como por exemplo:

    values.put(DB.NOME, nome);

    Estou començando agora, podem me ajudar? valeu

  15. Avatar de Anilton Brandão
    Anilton Brandão

    Tenho Problema , e tambem nos contactos e Cursor

    1. Avatar de Danilo Tostes
      Danilo Tostes

      Tbm tive nos mesmo pontos que citou, marcou em vermelho

  16. Avatar de Mike
    Mike

    Não sei se estou distraído ou não mas onde é que surge a classe Contacto? Não encontro em parte alguma o código. Talvez seja o passo 3 que saltaram (passaram do 2.5 para o 4). Se puderem disponibilizar agradecia. Cumprimentos

  17. Avatar de Ricardo Nakayama
    Ricardo Nakayama

    E ae galera, se vcs acharam que tem alguns passos incompletos, aconselho a ir para a parte 2 e puxar o código lá.

    https://pplware.sitedev.pt/tutoriais/tutorial-utilizao-do-sqlite-no-android-parte-ii/

    Dois erros que eu verifiquei nessa parte:

    – o DB que ele chama era para ser o dbHelper

    – Na classe contato dele, existe um campo long para o _id
    (a classe contatos somente tem os contrutores e os getters/setters, mas novamente, caso estejam com dúvida, aconselho a ir para a próxima parte e verificar o código)

    1. Avatar de Márcio
      Márcio

      Parabéns pelo post e Ricardo, seu comentário tb ajudou.
      obrigado

  18. Avatar de Matheus
    Matheus

    Parabéns pelo tutorial, aproveitei muito.
    Apenas me restou uma dúvida, no caso meu BD tem 3 tabelas, posso criar as três utilizando a mesma classe DbHelper?

    Ficaria assim:

    @Override
    public void onCreate(SQLiteDatabase db) {
    db.execSQL(CREATE_CAMINHOES);
    db.execSQL(CREATE_PRODUTOS);
    db.execSQL(CREATE_ACESSORIOS);
    }

  19. Avatar de rodrigocorreia
    rodrigocorreia

    Parabéns pelo tutorial!

    Alguma ideia do código para o método “editar” um contacto?
    Infelizmente essa parte não está contemplada no tutorial.

    Cumprimentos.

  20. Avatar de Jessica
    Jessica

    Eu ando lendo muito e surgem muitas dúvidas.

    Minha dúvida é como eu faço para criar um banco de de Dados com informações só para serem acessadas(consultadas)

    Por exemplo tenho 3 spinners e um botão. Vou colocar um exemplo

    na 1º Spinner eu teria opções de escola, hospitais, praças (Lugares Públicos)…
    na 2º Spinner eu teria as opções de zonas da cidade,( zona 1, zona2, zona3..)
    na 3º spinner os principais os bairros da cidade( bairro A, bairro B…)

    se a spinner 1 eu escolher Escola
    e a spinner 3 eu escolher o Bairro A,
    e a pessoa clicar no botão pesquisar
    como eu faço para na próxima tela apresentar todas as escolas do Bairro A ??

    Não é pra inserir nada, queria saber como faz um banco de dados apenas para consultar dados inseridos!
    De modo que quando alguém selecionar o Bairro A, na tela seguinte faria uma query sobre esses dados (ex. select * from escola where bairro = ‘A’)
    Como eu faço isso??

  21. Avatar de hou
    hou

    Me tira uma dúvida. Eu criei um sqlite por fora e tô colocando ele em na pasta assets pra depois copia-lo quando o aplicativo for instalado. Só que ele copia pra pasta certa o banco mas os atributos que estavam antes rw-rw-rw agora estão rw-rw- e com isso não consigo acessar o banco. Sabe o porque do arquivo ter perdido essas permissões?

  22. Avatar de nuno
    nuno

    Ainda não testei, mas gostaria de colocar uma questão.

    Se a base de dados tiver mais do que uma tabela, como se faz?

    Obrigado

  23. Avatar de MRFerrari
    MRFerrari

    Olá. Gostei deste tutorial, pois cada etapa da implementação está bem explicada. Para iniciantes em Android, como eu, é uma mão na roda!
    No entanto surgiu uma dúvida com relação aos tópicos 4.5 e 4.9. Eu não entendi o uso do “DB.”

    (ContentValues values = new ContentValues();
    values.put(DB.NOME, nome);
    values.put(DB.EMAIL,email);
    values.put(DB.TELEFONE,telefone);)

    O que é o “DB” afinal? de onde ele surgiu?
    Agradeço desde já!
    MRFerrari.

  24. Avatar de Max
    Max

    Olá,

    Achei bacana o tutorial, bem explicado parabéns.
    Contudo, notei que não foi implementado nenhum método para alteração de dados do contato, passando por exemplo o id ou o nome do contato, teria como fazer essa implementação?

    Grato.

  25. Avatar de Lucas Siqueira
    Lucas Siqueira

    Olá,

    Me tira uma duvida?… como eu faço pra carregar um listView com dados do banco SQLite sem a minha tabela ter o campo “_id”

    a tabela tem os campos “nome”,”numeroContrato”,”status”

    se eu colocar o “_id” da certo na hora de fazer o listView.setAdapter(adapter) , mas queria arrumar uma forma de não colocar esse campo “_id” na minha tabela.

    Preciso da ajuda de vocês…

    muito obrigado!

    Ótimo tutorial! esta de parabéns!

  26. Avatar de Áquilas
    Áquilas

    Utilizei esse tutorial e achei fantástico, fiz uma aplicação e funciona direitinho, porém dá esse erro: (Finalizing a Cursor that has not been deactivated or closed. database = /data/data/com.contactos/databases/contactos4.db, table = null, query = select _id, nome,telefone,foto from contactos2). Alguém poderia me ajudar a corrigi-lo? Desde já, obrigado.

  27. Avatar de Keyros
    Keyros

    Olá a todos. Estou com dificuldade para instalar o eclipse…! alguém de me pode ajudar? obrigado.

    1. Avatar de Mário
      Mário

      Boa noite, está a tentar instalar o eclipse para programar para Android?

      1. Avatar de Keyros
        Keyros

        Sim! Podes-me ajudar?

      2. Avatar de Keyros
        Keyros

        Olá de novo! Alguém para ajudar na instalação do eclipse ou outra aplicação para programar em android? Obrigado.

        1. Avatar de Matheus
          Matheus

          Olá Keyros. O Eclipse na verdade não precisa de instalação, é só baixar o zip, descompactar os arquivos em uma pasta de sua preferência, criar um atalho e rodar. Entretanto é necessário configurar o JDK e as variáveis de ambiente, para isso você pode dar uma olhada aqui: http://pt.stackoverflow.com/q/8708/3117 Se esse tópico não responder a sua pergunta você pode criar uma nova pergunta nesse site que com certeza te responderão bem rápido. Abraço;

          1. Avatar de Keyros
            Keyros

            Obrigado Matheus, vou-me tentar orientar…

  28. Avatar de Robson Cesar de Siqueira
    Robson Cesar de Siqueira

    Em 2.3 está faltando a constante TABLE_NAME :

    public static final String TABLE_NAME = “contactos2”;