Agenda utilizando RMS para a persistência de dados

04 junho 2009

Vamos utilizar o exemplo do post Iniciando em J2ME: Agenda sem banco, porém agora vamos modificá-lo usando RMS para persistir os dados.


Nota: Para adquirir conhecimento sobre a teoria de RMS veja o post RMS - Persistência de Dados em J2ME

Explicaremos as principais funções e métodos relacionados ao RMS.
O código todo será disponibilizado no final do post.

No exemplo da agenda sem banco temos um form com 2 textFields, um para a entrada do nome e outro para a entrada do telefone. Também temos Commands Ok para Inserir e para Exibir os dados em um list. Além disso, temos um alert para exibir mensagens de erro ou sucesso!

Agora vamos adicionar uma classe para a agenda e uma classe com as funções relacionadas ao Record Store, como abrir, fechar, adicionar, listar, entre outros.

A classe agenda guardará cada conjunto de dados em um objeto e depois este será acessado pela classe agendaRMS para os dados serem gravados no Record Store.

A classe classAgenda é a seguinte:

package hello;

public class classAgenda {
private String nome;
private String telefone;

public classAgenda(){
nome = null;
telefone = null;
}

public void setNome(String nome) {
this.nome = nome;
}

public String getNome() {
return nome;
}

public String getTelefone() {
return telefone;
}

public void setTelefone(String telefone) {
this.telefone = telefone;
}
}


No código fonte do botão Inserir do MIDlet vamos fazer o seguinte:

if (command == cmdInserir) {
if(getTextFieldNome().getString().equals("")||getTextFieldTel().getString().equals("")){
getAlert().setString("Algum campo esta vazio! Preencha corretamente");
}else{
adicionarDadosAgenda();
getAlert().setString("Os dados foram inseridos com sucesso!");
getTextFieldNome().setString("");
getTextFieldTel().setString("");
}
switchDisplayable(getAlert(),getFormPrincipal());
}


Se um dos textFields estiverem vazios é passado a mensagem “Algum campo esta vazio! Preencha corretamente” para o alert exibir.

Caso os textFields estejam preenchidos corretamente é chamado o método adicionarDadosAgenda(), que adiciona os conteúdo dos textFields a um objeto de classAgenda. Depois é mandado uma mensagem de sucesso para o alert exibir e os textFields são limpados para poder inserir outros dados.

A função adicionarDadosAgenda() pertence ao MIDlet e é a seguinte:

public void adicionarDadosAgenda(){
classAgenda objetoAgenda = new classAgenda();
objetoAgenda.setNome(textFieldNome.getString());
objetoAgenda.setTelefone(textFieldTel.getString());
objetoRMS.adicionarNoBanco(objetoAgenda);
}


Para cada novo conjunto de dados (nome e telefone) é criado um objeto de classAgenda. É setado os valores dos atributos da classe através dos métodos setNome e setTelefone. Os dados passados para os atributos são os contidos nos textFields. Depois disso é chamada o método adicionarNoBanco(objetoAgenda), que adiciona os dados no Record Store. Ele é acessado com o objetoRMS pois é um método da classe agendaRMS.

No botão Exibir do MIDlet temos o seguinte código:

if (command == cmdExibir) {
getList().deleteAll(); //apaga o que está no list
objetoRMS.listar();
switchDisplayable(null, getList());
}


O conteúdo do list é apagado e é chamado o método listar() da classe agendaRMS.

Depois quando a aplicação for encerrada, em exitMIDlet(), chamamos o método fechar() da classe agendaRMS, que vai fechar o Record Store que estiver aberto.

A classe agendaRms é a seguinte:


package hello;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import javax.microedition.rms.InvalidRecordIDException;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;

/**
*
* @author Lais Zanfolim
*/
public class agendaRMS {
private RecordStore rs;
private HelloMIDlet objMIDlet = null;

public agendaRMS(HelloMIDlet MIDlet){
objMIDlet = MIDlet;
try {
rs = RecordStore.openRecordStore("Agenda", true);
} catch (RecordStoreException ex) {
ex.printStackTrace();
}
}

void adicionarNoBanco(classAgenda objetoAgenda) {
try {
//captura dados em um buffer da memória para depois transformá-lo
//em um array de bytes
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//escreve Strings e tipos de dados primitivos em um OutPutStream
DataOutputStream dos = new DataOutputStream(baos);
//escreve no OutPutStream(baos) o nome e telefone
//Este método é usado para escrever Strings. Para escrever outros tipos
//temos o writeChar(), writeFloat(), writeInt(), writeByte(), entre outros.
dos.writeUTF(objetoAgenda.getNome() + " - " + objetoAgenda.getTelefone());
//esvazia os dados do OutPut Stream
dos.flush();
//copia os dados capturados em um array de bytes
byte[] dados = baos.toByteArray();
//adiciona os dados contidos no array de bytes no banco, que retorna
//o id do registro que os dados ficaram armazenados
int id = rs.addRecord(dados, 0, dados.length);
//fecha o OutPut Stream e comunica os recursos do sistema associados
// com o Stream
dos.close();
//fecha o ByteArrayOutPutStream, pois este ByteArrayOutPutStream não esta mais sendo usado
baos.close();
} catch (IOException ex) {
ex.printStackTrace();
}catch (RecordStoreNotOpenException ex) {
ex.printStackTrace();
} catch (RecordStoreException ex) {
ex.printStackTrace();
}
}

void listar() {
try{
//Os records IDs iniciam em um. O for vai do ID número 1 até a quantidade
//total de records(registros), que é capturado através da função getNumRecords()
for(int i =1; i <= rs.getNumRecords();i++){ //captura o record de id igual a i String aux = getRecord(i); //chama a função que escreve na tela os dados capturados no banco, como a função //pertence ao MIDlet acessamos a função através de um objeto do MIDlet. A função //manda a String com os dados de um registro do banco objMIDlet.listarTela(aux); } }catch(RecordStoreNotOpenException e){ System.out.println(e.getMessage()); } } public String getRecord(int id){ String toReturn = ""; try{ //tamRecord recebe o tamanho do record cujo id é passado. int tamRecord = rs.getRecordSize(id); byte[] dados = new byte[tamRecord]; //transforma um array de bytes em um InPut Stream ByteArrayInputStream bais = new ByteArrayInputStream(dados); //transforma um Input Strean em uma String ou em tipos de dados primitivos DataInputStream dis = new DataInputStream(bais); //acessa o banco no id informado e grava em array dados os dados //capturados no registro do Record Store rs.getRecord(id, dados, 0); //lê a String contida no DataInPutStream e armazena-a na variável toReturn toReturn = dis.readUTF(); bais.close(); dis.close(); }catch(IOException e){ System.out.println(e.getMessage()); }catch(ArrayIndexOutOfBoundsException e){ System.out.println(e.getMessage()); }catch(InvalidRecordIDException e){ System.out.println(e.getMessage()); }catch(RecordStoreNotOpenException e){ System.out.println(e.getMessage()); }catch(RecordStoreException e){ System.out.println(e.getMessage()); } return toReturn; } public void fechar() throws RecordStoreNotOpenException, RecordStoreException { if (rs.getNumRecords() == 0) { //obtem o nome do Record Store que esta aberto String arquivo = rs.getName(); //fecha o record Store que esta aberto rs.closeRecordStore(); //deleta o Record Store com o nome passado por parâmetro. No caso //deletamos o Record Store se ele estiver vazio. RecordStore.deleteRecordStore(arquivo); } else { rs.closeRecordStore(); } } }


Pronto!
Todos os métodos relacionados ao RMS estão explicados no próprio código.

Clique aqui
para baixar o projeto completo do Netbeans.

8 comentários:

  • gostei do artigo, ele contem alguns erro, me fizeram quebrar a cabeça, mas com o codigo disponibilizado me ajudou muito, acho que a intenção era essa.

  • javamovel.com

    Que bom que gostou! a página está com problema na parte do código (logo vamos resolver) mas o projeto está correto. Quebrar a cabeça faz parte! ;)

    Att, javamovel.com

  • DF Informática

    Cara show de bola.
    sou iniciante mais tenho 5 ja trabalhando com php será que conseguir trabalhar com isso ai tranquilamente na sua opnião?

  • AlexRosaMello

    Os links para download dos códigos completos não funcionam!

  • Unknown

    Algum outro canto para download ?

  • O link para o download não esta funcionando, mas muito bom o artigo.
    Tem algum outro link para download?

  • Juliana Monteiro

    Tem como me passar o arquivo completo com RMS.

  • Postar um comentário