Tutorial: Utilização do sqlite no Android (Parte II)
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.
Este artigo será dividido em duas partes e depois de termos ensinado a criar criar as classes para interagir com o sqlite, hoje vamos proceder à criação da aplicação.
No tutorial anterior deixamos as classes auxiliares para ligar à base de dados prontas a serem “consumidas” pela nossa aplicação, vamos agora ver como as iremos utilizar.
5 - vamos desenhar inicial que irá listar os contactos existentes na base de dados e terá um botão que permitirá adicionar um novo Contacto.
5.1 - Abrir o ficheiro main.xml e alterar o layout para o seguinte:
<LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/btNovoContacto" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Novo Contacto" /> <ListView android:id="@+android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout> |
6 - Vamos criar um novo Layout com o nome: “contacto_list_item” onde iremos definir a forma como cada item da lista será mostrado.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="8px"> <TextView android:id="@+id/nome" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/telefone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/nome" android:layout_below="@+id/nome" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </RelativeLayout> |
7 - Vamos agora alterar a classe ContactosActivity.java para listar os contactos existentes na base de dados.
import android.app.ListActivity; import android.os.Bundle; public class ContactosActivity extends ListActivity { ListAdapter adapter; DBAdapter datasource; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); datasource = new DBAdapter(this); datasource.open(); Cursor cursor = datasource.getContactos(); String[] columns = new String[] { "nome","telefone" }; int[] to = new int[] { R.id.nome, R.id.telefone}; adapter = new SimpleCursorAdapter(this, R.layout.contacto_list_item, cursor, columns, to); this.setListAdapter(adapter); datasource.close(); } } |
- ListAdapter permite mostrar várias informações em uma linha do ListView.
- DBAdapter permite fazer operações na base de dados.
8 - Adicionar Novo contacto Vamos agora permitir que na nossa aplicação possa adicionar contactos.
8.1 - Acrescentar um layout com o nome novocontacto.xml
Código do layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Nome:" /> <EditText android:id="@+novocontacto/ednome" android:layout_width="match_parent" android:layout_height="wrap_content" > <requestFocus /> </EditText> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Email" /> <EditText android:id="@+novocontacto/edEmail" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Telefone" /> <EditText android:id="@+novocontacto/edTelefone" android:layout_width="match_parent" android:layout_height="wrap_content" /> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+novocontacto/tirarFoto" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="tirar fotografia" /> <Button android:id="@+novocontacto/btadicionar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Adicionar" /> </LinearLayout> <ImageView android:id="@+novocontacto/ivReturnedPic" android:layout_width="250dp" android:layout_height="250dp" android:layout_gravity="center" android:src="@drawable/ic_launcher" /> </LinearLayout> |
9 - Vamos agora acrescentar uma activity no ficheiro AndroidManifest.xml
<activity android:label="@string/app_name" android:name=".NovoContacto" > <intent-filter > <action android:name="mbaltazar.contactos.NovoContacto" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> |
10 - Alterar o ficheiro ContactoActivity para passar para o ecrã NovoContacto. 10.1 - Criar variável para aceder ao botão Novo Contacto:
Button btNovoContacto;
10.2 - Criar ligação entre botão e o elemento da interface, e adicionar a acção que irá fazer o botão, no método onCreate:
btNovoContacto = (Button) findViewById(R.id.btNovoContacto); btNovoContacto.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub Intent novo = new Intent("mbaltazar.contactos.NovoContacto"); startActivity(novo); } }); |
11- Acrescentar nova classe chamada NovoContacto e indicar que expande a classe Activity
public class NovoContacto extends Activity { } |
11.1 - Acrescentar o método onCreate e alterar o parâmetro do método setContentView para indicar o novo ficheiro de layout novocontacto.xml como o layout da nova Activity.
public class NovoContacto extends Activity { protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.novocontacto); } } |
11.2 - Criar variáveis para aceder aos elementos da interface Novo Contacto:
Button btadicionar; Button btTirarFoto; EditText edtNome; EditText edtEmail; EditText edtTelefone; ImageView iv; final static int cameraData = 0; |
11.3 - No evento onCreate criar a ligação entre as variáveis e os elementos da interface:
edtNome = (EditText) findViewById(R.novocontacto.ednome); edtEmail = (EditText) findViewById(R.novocontacto.edEmail); edtTelefone = (EditText) findViewById(R.novocontacto.edTelefone); btadicionar = (Button) findViewById(R.novocontacto.btadicionar); btTirarFoto = (Button) findViewById(R.novocontacto.tirarFoto); iv = (ImageView) findViewById(R.novocontacto.ivReturnedPic); |
11.4 - Adicionar, no método onCreate, a acção do botão tirar Foto:
btTirarFoto.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub Intent i= new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(i,cameraData); } }); |
11.5 - Adicionar o método onActivityResult, quando for tirada a fotografia é apresentada a imagem no controlo imageView:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub if(resultCode == RESULT_OK){ Bundle extras = data.getExtras(); Bitmap bmp = (Bitmap) extras.get("data"); iv.setImageBitmap(bmp); } super.onActivityResult(requestCode, resultCode, data); } |
11.6 - Adicionar uma instância da classe DBAdapter
private DBAdapter datasource; |
11.7 - inicializar datasource no método onCreate
datasource = new DBAdapter(this); |
11.8 - Alterar o método onCreate e adicionar a acção do botão Adicionar:
btadicionar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub datasource.open(); Contacto c = datasource.createContacto(edtNome.getText().toString(), edtEmail.getText().toString(), edtTelefone.getText().toString(),loadBitmapFromView(iv)); datasource.close(); AlertDialog.Builder dialogo = new AlertDialog.Builder(NovoContacto.this); dialogo.setTitle("Aviso"); dialogo.setMessage("Contacto:" + c.getNome()); dialogo.setNeutralButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }); dialogo.show(); } }); |
11.9 - Adicionar um método adicional para retornar o bitmap da imageView:
public static Bitmap loadBitmapFromView(View v) { Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height); v.draw(c); return b; } |
Com este código já é permitido adicionar um contacto à base de dados.
12 - Vamos agora alterar na classe ContactosActivity para que no final de adicionarmos o contacto este já seja apresentado na lista:
@Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); datasource.open(); Cursor cursor = datasource.getContactos(); String[] columns = new String[] { "nome","telefone" }; int[] to = new int[] { R.id.nome, R.id.telefone}; adapter = new SimpleCursorAdapter( this, R.layout.contacto_list_item, cursor, columns, to); this.setListAdapter(adapter); datasource.close(); } |
12.1 - Vamos adicionar o método onListItemClick, método que é chamado sempre que é clicado um item da lista:
@Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent intent = new Intent("com.contactos.DetalhesContacto"); Cursor cursor = (Cursor) adapter.getItem(position); intent.putExtra("idContacto",cursor.getInt(cursor.getColumnIndex("_id"))); startActivity(intent); } |
13 - criar a interface para ver os detalhes do contacto. 13.1 - Criar um novo ficheiro com o nome detalhecontacto.xml e alterar o ficheiro com o seguinte layout:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/ivFoto" android:layout_width="150dp" android:layout_height="150dp" android:src="@drawable/ic_launcher" /> </LinearLayout> <LinearLayout android:id="@+id/layoutNome" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Nome:" android:textColor="#ffff00" android:textSize="20sp"/> <TextView android:id="@+lista/txtnome" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ffffff" android:textSize="20sp"/> </LinearLayout> <LinearLayout android:id="@+id/layoutTelefone" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Telefone:" android:textColor="#ffff00" android:textSize="20sp" /> <TextView android:id="@+lista/txtTelefone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ffffff" android:textSize="20sp" /> </LinearLayout> <LinearLayout android:id="@+id/layoutEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Email:" android:textColor="#ffff00" android:textSize="20sp" /> <TextView android:id="@+lista/txtEmail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ffffff" android:textSize="20sp" /> </LinearLayout> <LinearLayout android:id="@+id/layoutBotoes" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> </LinearLayout> <Button android:id="@+lista/btmenu" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Voltar" /> <Button android:id="@+id/btEditar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Editar" /> <Button android:id="@+id/btEliminar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Eliminar" /> </LinearLayout> |
No final a interface ficará com o seguinte aspecto:
14 - De seguida vamos acrescentar a nova activity para mostrar os detalhes do contacto:
<activity android:label="@string/app_name" android:name=".ContactosDetalhes" > <intent-filter > <action android:name="mbaltazar.contactos.ContactosDetalhes" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> |
15 - Adicionar nova classe com nome Contactos Detalhes, esta vai expandir a classe Activity:
public class DetalhesContacto extends Activity { } |
15.1 - Acrescentar o método onCreate e alterar o parâmetro do método setContentView para indicar o novo ficheiro de detalhecontacto.xml como o layout da nova Activity DetalheContacto.
@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.detalhecontacto); } |
15.2 - Criar variáveis para aceder aos elementos da interface:
int idContacto; ContactoDataSource datasource; Contacto contacto; TextView edtNome; TextView edtEmail; TextView edtTelefone; Button btVoltar; Button btEliminar; ImageView ivFoto; |
15.3 - No evento onCreate criar a ligação entre as variáveis da classe e os elementos da interface.
@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.detalhecontacto); edtNome = (TextView) findViewById(R.lista.txtnome); edtEmail = (TextView) findViewById(R.lista.txtEmail); edtTelefone = (TextView) findViewById(R.lista.txtTelefone); ivFoto = (ImageView) findViewById(R.id.ivFoto); btEliminar = (Button) findViewById(R.id.btEliminar); btVoltar = (Button) findViewById(R.lista.btmenu); } |
15.4 - Adicionar um nova função que irá colocar nos elementos da interface os detalhes do contacto:
private void carregaDetalhesContacto(){ idContacto = getIntent().getIntExtra("idContacto", 0); datasource = new DBAdapter(this); datasource.open(); contacto = datasource.getContacto(idContacto); datasource.close(); ivFoto.setImageBitmap(contacto.getFoto()); edtNome.setText(contacto.getNome()); edtEmail.setText(contacto.getEmail()); edtTelefone.setText(contacto.getTelefone()); } |
15.5 - Chamar a função carregaDetalhesContacto() na função onCreate.
15.6 - Adicionar à função onCreate a acção dos botões da interface:
btVoltar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub finish(); } }); btEliminar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub AlertDialog.Builder dialogo = new AlertDialog.Builder(ContactosDetalhes.this); dialogo.setTitle("Aviso"); dialogo.setMessage("Eliminar Contacot?"); dialogo.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { } }); dialogo.setPositiveButton("Eliminar",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { datasource.open(); datasource.EliminaContacto(idContacto); datasource.close(); finish(); } }); dialogo.show(); } }); |
Com isto terminamos a nosso pequena aplicação de registo de contactos utilizando o sqlite.
Download: Projecto Android - Contactos
Este artigo tem mais de um ano
Bom dia ,
@Pedro é minha impressão ou usaste o Big Linux ? só mesmo por curiosidade , é que como já disse estou a usar esta Distro e a ponderar seriamente em me manter com ela como a minha distro principal .
Cumprimentos
Serva
Ainda não usei, tenho de testar 🙂
Está um tutorial muito completo, Mário.
Parabéns!
Pedro , muito obrigado , então deverá ter sido o @Mário que usou .
Cumprimentos
Serva
Muito bem Mário, e podes continuar…a pedido de várias famílias!
Abraço.
Muito bom. Parabéns!!
Boas,
Tenho uma questão… Como devo proceder para inserir outra tabela na mesma base de dados? Cumps
Boas, para inserir outra tabela na mesma base de dados tens que, na classe DbHelper (na parte 1 deste tutorial), adicionar outra variável como a “DATABASE_CREATE” (ponto 2.3) com o comando de criacao da tabela desejada, e de seguida no método onCreate (ponto 2.4) fazer: db.execSQL();
Espero ter ajudado.
Cumprimentos
O artigo está excelente .
Aceita os meus sinceros cumprimentos
Serva
Keep it coming 🙂 mt bom.
Alguém me consegue ajudar no que coloquei aqui?
Desculpem escrever aqui mas como o tópico já é muito antigo ninguém vai ler 🙁
https://pplware.sapo.pt/smartphones/android/smartphone-sapo-a5-vamos-dar-lhe-uma-nova-vida/comment-page-1/#comment-524568
Muito obrigado a todos.
Cumprimentos
Bom artigo.
Mais seriam bem vindos.
ps: Um ponto a melhorar seriam os comentários no código para quem faz download do projecto.
para Pedro Pinto:
porque não, quando fazem tutorias android, colocar os icons do pplware?!?!?!
aqui fica um programinha muito simpes que encontrei na net que transforma uma imagem nos icones pretendidos, hdpi, ldpi e mdpi.
parabéns pelo vosso site!!!!!!!!
Abraço.
http://www.redrails.com.br/2011/09/criando-icones-para-todas-as-densidades-de-tela-do-android-com-um-so-clique/
So faltou fechar o cursor qndo clicar no botão voltar :D. Do resto ta de parabens!!!!
O Link para baixar o projeto não está funcionando.
https://pplware.sapo.pt/wp-content/uploads/ppinto/contactos_pplware.zip
Poderia consertar o link ou enviar o projeto por e-mail?
Obrigado
Diego
Thank you for the tutorial,
but the button editar doesn’t work!
Este tutorial me ajudou muito a entender melhor o uso do SQLite no Android.
Obrigado!
Muito bom o tutorial, mas o código para o botão editar não foi incluído… é importante… poderia dar uma dica ?
Boas.
Algum código para o botão editar??
Cumprimentos.
Tuto muito bom parabens
Fera…
Estou iniciando na interação BD + android…desculpe a “ignorância”, mas não encontrei a classe “Contactos”…
Vlw!
Obs.: a classe é Contacto***** que não estou encontrando..
Desde já obrigado e parabéns pelo tuto!
Parabens,
Você tem o código do botão editar?
Ótimo tutorial. Didática perfeita!
Tópico antigo mas, muito útil. Parabéns.
Ola!
Ótimo tutorial! Consegui fazer aqui com alguns ajustes.
Mas ficou faltando o código do botão “Editar”.
Poderia dar alguma dica?
Abraços
Shyde
Olá, muito bom o tutorial! Mas para mim essa função dá erro:
public Contacto getContacto (int idContacto){
Cursor cursor = database.query(dbHelper.TABLE_NAME, allColumns, dbHelper.ID + ” = ” + idContacto, null,null, null, null);
cursor.moveToFirst();
return cursorToContacto(cursor);
}
não consigo retornar o cursor, diz que não pode converter objeto em cursor e por consequência não funciona a exibição dos detalhes do item clicado na lista…como posso resolver isso? obrigada!
estou com esta mesma duvida, Tassiana conseguiu sair dessa etapa? ou senão alguem que tenha passado pelo mesmo?
E se eu quiser editar um contato? como eu faço seguindo esse mesmo modelo teu? outra dúvida: esse teu projeto é baseado em algum padrão?
bom dia
estou a tentar adaptar esta base de dados ao meu código, mas não estou a conseguir.
para já, o database.open() não funciona, diz-me que não consegue resolver o método
Coloque isto na sua classe adapter:
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
Bom dia, tenho tudo a funcionar menos o editar que pelo o que parece não está feito.
Será que alguém me consegue ajudar?
Olá Pedro! Este tutorial estava muito interessante. Para quando um tutorial com webservices para sincronização entre SQLite e MySQL?
Abraço.
Para quem quer a função editar é qualquer coisa do género:
Na classe DbAdapter:
public void editarContacto(int foodId, ContentValues contentValues){
database.update(DbHelper.TABLE_NAME, contentValues, DbHelper.ID + ” = ” + foodId, null);}
Na atividade editar:
contentValues podem definir da seguinte maneira:
ContentValues contentValues = new ContentValues();
ContentValues.put(“nome”,”João”);
ContentValues.put(“telefone”,”933333333″);