19 março 2007

Introdução a programação para celulares com suporte a Java ME – parte 4

Este post faz parte de uma série de artigos técnicos sobre o desenvolvimento de software para celulares. No primeiro artigo, abordamos os conceitos básicos da tecnologia com ênfase na arquitetura de Java ME. No segundo artigo, analisamos um exemplo de código Java que ilustra o ciclo de vida da aplicação. No terceiro artigo, verificamos como são empacotadas as aplicações – conhecidas como MIDlet Suíte. Neste quarto artigo, veremos como desenvolver um exemplo de aplicação, passando pelas fases clássicas: codificar, compilar e testar os programas; tudo isso usando um ambiente de emulação do celular.

Introdução

Os desenvolvedores de aplicações Java ME podem construir e testar seus programas sem a necessidade de um telefone celular real, através dos programas emuladores. No entanto, essas ferramentas não reproduzem fielmente o comportamento dos diversos modelos de celulares existentes no mercado, por isso, acredito que deveriam denominar-se de simuladores e não emuladores. É preciso então estar ciente desse fato.

De fato, existem softwares especialmente desenvolvidos para simular o comportamento dos celulares reais. Os principais fornecedores desses programas são os próprios fabricantes de celulares, tais como Nokia e Motorola. A Sun Microsystems também oferece recursos para os desenvolvedores através do seu software WTK (Wireless Tool Kit). Nesta primeira experiência usaremos a ferramenta da SUN – WTK, por ser uma ferramenta bastante didática e de propósito geral. Se suas intenções for desenvolver software para um aparelho específico, então seria interessante utilizar um simulador do respectivo aparelho, se existir.

Ambiente de Desenvolvimento WTK

Conforme citado, usaremos o WTK 2.5 (versão mais estável e atual na data deste post). A ferramenta do Toolkit inclui ambientes de emulação, ferramentas para otimização e desempenho, documentação e exemplos que os desenvolvedores necessitam para construir de forma rápida aplicações simples ou avançadas. O WTK facilita o entendimento do ciclo de vida do desenvolvimento: codificar; compilar (pré-verificar), e rodar (testar). Veremos também alguns exemplos usando linha de comando para demonstrar esse ciclo.

O download do WTK bem como os seus pré-requisitos:

http://java.sun.com/products/sjwtoolkit/download-2_5.html

dica: após instalar, coloque no PATH do sistema o diretório de instalação: (ex. C:\WTK25\bin), e crie uma variável CLASSPATH e coloque (C:\WTK25\lib). Isso permitirá trabalhar através da linha de comando.

Testando sua instalação

Iremos testar se tudo foi instalado corretamente:

  1. vá para o prompt de comando (Command Prompt);
  2. para testar a instalação do CLDC digite o comando “preverify”, você deverá ver os comandos conforme a figura 1 abaixo;
  3. agora digite o comando “emulator -version” para testar as configurações disponíveis do WTK.
Figura 1: testando a ferramenta pré-verificador e emulator

Os emuladores atuais suportam uma especificação chamada UEI (Unified Emulator Interface), que é um padrão para interação entre ambientes IDE (Integrated Development Environments) e os dispositivos emuladores. Sendo assim, fica fácil testar todos os programas simplesmente através da ferramenta “emulator”. Experimente digitar no prompt de comando “emulator -help”. São através desses comandos que o Eclipse IDE por exemplo, através de plugins, se comunica com os emuladores do WTK.

Escrevendo um exemplo e testando através do emulator WTK

A maneira mais fácil de criar e testar um programa é utilizando a ferramenta “ktoolbar”. Abra esse programa digitando no prompt de comando “ktoolbar” ou clique no atalho do menu “Iniciar”. Então clique no botão “New Project”, dois campos são necessários, o nome do projeto (coloque PrimeiroProjeto), e o nome do MIDlet (coloque PrimeiroProgramaMIDlet). Agora vá para o diretório C:\WTK25\apps\PrimeiroProjeto\src e crie o arquivo com o código abaixo:

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.*;

/**
* Esta classe desenha uma mensagem na tela e implementa um botão para sair.
*
* @author Douglas D. Del Frari
*/
public class PrimeiroProgramaMIDlet extends MIDlet implements CommandListener {

// representa o display da aplicacao
private Display display;

// representa o comando de sair
private Command cmdQuit;

// representa uma interface de formulario
private Form form;

/** Construtor */
public PrimeiroProgramaMIDlet() {
display = Display.getDisplay(this);

cmdQuit = new Command("Sair",Command.EXIT,1);
form = new Form("Titulo do Programa");

// adicionando um texto no formulario e tambem o botao "sair"
form.append("Testando meu primeiro exemplo...");
form.addCommand(cmdQuit);

// registrando o tratamento dos eventos do formulario (botao sair) nesta classe
form.setCommandListener(this);
}

/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
*/
protected void destroyApp(boolean b) throws MIDletStateChangeException {
// chamado quando nossa aplicação será finalizada
this.notifyDestroyed();
}

/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#pauseApp()
*/
protected void pauseApp() {
// somente será chamado quando houver uma interrupção do SO
}

/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#startApp()
*/
protected void startApp() throws MIDletStateChangeException {
// Ponto Inicial de nossa aplicação
display.setCurrent(form);
}

/* (non-Javadoc)
* @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable)
*/
public void commandAction(Command c, Displayable d) {
if (c == cmdQuit) {
try {
destroyApp(true);
} catch (MIDletStateChangeException e) {
e.printStackTrace();
}
}

}
}



Próximos passos: Compilando o programa e rodando o MIDlet

  1. Clique no menu Project;
  2. Clique na opção Build
  3. Clique na opção Run
  4. Com o emulador rodando clique no botão direito abaixo da opção “Launch”
  5. Clique no botão esquerdo “Sair”

Figura 2: Compilando o primeiro projeto com WTK


Figura 3: rodando o emulador padrão


Analisando o código fonte
Toda aplicação precisa herdar de MIDlet para poder implementar o ciclo de vida, representado através dos métodos:
  • destroyApp() apenas chamou o comando para finalizar a aplicação;
  • pauseApp() nada foi feito ainda;
  • startApp() direcionou o componente do formulário (form) para ser exibido;

Foram definidos atributos para representar um comando (cmdQuit), um formulário para colocar as coisas gráficas (form). Note que precisamos SEMPRE definir ou capturar o display do aparelho, isso foi feito através da classe Display.

No construtor desta classe os objetos foram instanciados. Detalhe é que neste caso precisamos capturar os eventos que o usuário poderá fazer, por isso implementamos a interface CommandListener, que nos obriga implementar o método CommandAction, que receberá os eventos dos componentes registrados. O comando foi registrado no próprio MIDlet, pois foi nesta classe que desejamos neste exemplo tratar os eventos. Normalmente, escolhemos outra classe para tratar eventos.

No próximo artigo veremos alguns exemplos usando a API de MIDP, visando explorar os seus recursos gráficos de alto nível que são "bem fáceis" de utilizar, até lá!

12 março 2007

Introdução a programação para celulares com suporte a Java ME – parte 3

Este post faz parte de uma série de artigos técnicos sobre o desenvolvimento de software para celulares. No primeiro artigo, abordamos os conceitos básicos da tecnologia Java ME, enfatizando os fundamentos de sua arquitetura. No segundo artigo, analisamos um exemplo de código Java que ilustra o ciclo de vida da aplicação. Neste terceiro post, estudaremos o tipo de empacotamento de nossas aplicações, que serão representadas por uma suite MIDlets (MIDlet Suite).


Introdução
Após muita reflexão sobre o conteúdo deste post, achei relevante abordar como nossas aplicações são empacotadas, pois esse conhecimento facilitará e contextualizará o leitor para a distribuição das aplicações a terceiros, bem como permitirá testar em telefones celulares reais. Assim, quando codificarmos alguns exemplos e desejarmos testá-los nos ambientes apropriados, já saberemos o essencial para gerar o software – conhecido como gerar um pacote da distribuição.

A Suite de MIDlet
Um MIDlet é uma aplicação Java projetada para ser executada sobre um dispositivo móvel. Mais especificamente, um MIDlet tem no seu core classes do Java de CLDC e MIDP. Uma suite de MIDlet consiste de uma ou mais MIDlets empacotados através de um arquivo JAR (Java ARchive). Bem, em outras palavras, quase todos as aplicações vem com um instalador ou executável no qual rodamos nosso software, no caso de uma aplicação MIDlet, esse padrão obedece a mesma abordagem que Java SE e suas bibliotecas. Será através desse arquivo que o gerenciador da aplicação (AMS - Application Manager Software, post anterior), irá instalar, executar e remover os MIDlets.

Quando o AMS inicia um MIDlet ele basicamente fará as seguintes verificações:
  • acesso ao CLDC e a máquina virtual java;
  • acesso as classes definidas de MIDP; geralmente definem as implementações das interfaces do usuário, esquema de persistência, suporte a rede através dos protocolos de comunicação (ex. HTTP), tempos e configurações do usuário com o celular;
  • acesso ao arquivo JAR; se a aplicação usa arquivos de imagens, estas deverão estar empacotadas neste aquivo JAR, caso contrário ocorrerão erros.
  • acesso as informações do arquivo JAD (Java Application Descriptor); Se uma suite de MIDlet tiver um arquivo JAD, então seu conteúdo deverá estar disponível, podendo descrever mais de um MIDlet no mesmo pacote de aplicação.
Em teoria, podemos compartilhar recursos entre MIDlets diferentes, a memória de armazenamento do celular por exemplo, poderá ser acessada por dois MIDlets completamente diferentes. Essa memória pode ser tratada através do pacote RMS de MIDP2. No entanto, a maioria dos celulares suporta apenas a execução de uma aplicação por vez. Teríamos que fechar a execução do MIDlet corrente, e executar o próximo MIDlet. No futuro, a especificação de MIDP 3 promete resolver essa limitação.

JAR
Uma aplicação irá geralmente consistir em muitos arquivos. Além das tradicionais classes do Java (arquios .class), adicionalmente teremos imagens, sons e dados diversos, conhecidos como recursos (resources ou res). Dentro do JAR teremos obrigatoriamente um arquivo que define todas as propriedades da aplicação, bem como o MIDlet Suite. Esse arquivo segue a regra de Java SE, me refiro ao arquivo MANIFEST (manifest.mf). A figura 1 ilustra as propriedades desse arquivo.

Figura 1: Propriedades do arquivo MANIFEST

As principais propriedades são aquelas que indicarão para o AMS o nome de nossa aplicação, a sua localização do nome da classe MIDlet (pode conter vários pacotes no caminho), a versão do CLDC e MIDP. Na prática, toda vez que desejarmos testar nossa aplicação em algum celular necessitaremos especificar esse arquivo, pois caso contrário, o AMS não encontrará o MIDlet para ser executado. Vejamos um exemplo real de um MANIFEST da aplicação Mobile English Learning que estou mantendo:

Manifest-Version: 1.0
MIDlet-Vendor: Oxe Tche group
MIDlet-Version: 1.0.0
MIDlet-1: English Learning,res/firststeps16.PNG,oxetche.EnglishLearningMIDlet
MicroEdition-Configuration: CLDC-1.1
MIDlet-Name: English Learning
MicroEdition-Profile: MIDP-2.0

Já o arquivo JAD desta aplicação possui as seguintes propriedades:

MIDlet-1: English Learning,res/firststeps16.PNG,oxetche.EnglishLearningMIDlet
MIDlet-Jar-Size: 31462
MIDlet-Jar-URL: projeto-MobileEnglishLearning.jar
MIDlet-Name: English Learning
MIDlet-Vendor: Oxe Tche group
MIDlet-Version: 1.0.0
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0

Observe que quando iremos realizar experimentos práticos, utilizaremos ferramentas, plugins e emuladores que farão automaticamente a geração desse JAD/JAR, que servirão como ponto de entrada para realizar o teste de nosso software.

No próximo post, veremos como desenvolver um exemplo de aplicação, passando pelas fases clássicas: codificar, compilar e testar os programas; tudo isso usando um ambiente de emulação do celular.

05 março 2007

Introdução a programação para celulares com suporte a Java ME - parte 2

Este post faz parte de uma série de artigos técnicos sobre o desenvolvimento de software para celulares. No primeiro artigo, abordamos os conceitos básicos da tecnologia Java ME, enfatizando os fundamentos de sua arquitetura. Neste segundo artigo, demonstrarei um exemplo de código Java que ilustra o ciclo de vida de um aplicativo com Java ME.

Introdução
O objetivo é demonstrar um exemplo ilustrativo de uma aplicação Java ME para situar o leitor no que se refere ao processo de execução da aplicação na memória, da organização e estrutura do programa, tais como: o começo, o meio e o fim do ciclo de vida do software.

Uma aplicação Java ME precisa obedecer algumas regras para que funcione corretamente, entre elas, destacarei inicialmente o ponto de entrada, ou seja, por onde o programa começa a ser executado. Na tecnologia Java SE, por exemplo, os programas começam a execução através do método public static void main(String[] args). No entanto, em Java ME isso é diferente e não precisamos codificar esse método, pois uma aplicação que roda em conjunto com a Máquina Virtual Java (JVM do inglês), chamada de Gerenciador da Aplicação (do inglês Application Management Software - AMS), gerencia o ciclo de vida do software através de estados. A figura 1 ilustra esse processo:

Figure 1: Os possíveis estados de um MIDlet e a transição entre ele

Em outras palavras, quando minha aplicação for iniciada ela assumirá um estado Active (algo como iniciado ou rodando). O nome do método é “protected abstract void startApp()”. Quando for fechada, seja pelo usuário ou pelo Sistema Operacional (SO), nossa aplicação será finalizada – neste caso o estado que será tratado chama-se Destroyed. Isso através do método “protected abstract void destroyApp(boolean unconditional)”. Se ocorrer alguma interrupção na execução corrente de nossa aplicação, ela assumirá o estado parado – Paused. Podendo ser tratada pelo método “protected abstract void pauseApp()”. Neste último, posso citar alguns exemplos: o celular recebendo uma ligação ou recebendo uma mensagem SMS; ou ainda, descarregando a bateria do celular; algum evento sendo priorizado pelo SO do celular, tal como um aviso do despertador ou aviso programado. Em todos os estados utilizam-se os métodos citados para tratar as especificidades de nossa aplicação.

Dito isso, vejamos agora outras regras e definições de Java ME. Os métodos comentados acima referem-se as especificações das JSR-37 (MIDP 1.1) e JSR-118 (MIDP-2.0), ou seja, a biblioteca básica a ser implementada para rodar aplicações. Se um celular suporta MIDP então poderá rodar desde que nossa aplicação estenda ou herde da classe chamada MIDlet, provinda de javax.microedition.midlet.MIDlet. O ponto inicial então poderá ser codificado. A figura 2 ilustra um exemplo de código modelo (ou template) que sempre utilizaremos em nossas aplicações.


Figura 2: template da classe MIDlet com os métodos p/ tratamento dos estados

Nossas aplicações serão chamadas de MIDlets, assim como existem os Applet Java.Esse exemplo ainda não possui códigos úteis, mas seve como base para os próximos MIDlets que serão codificados no futuro. Outras definições de MIDlet segundo Wikipédia:

MIDlet É um aplicativo em Java para dispositivos móveis, mais especificamente para a máquina virtual J2ME. Em geral são aplicações para serem executadas em celulares, como jogos entre outros. MIDlets irão (deverão) rodar em qualquer dispositivo que implemente J2ME Mobile Information Device Profile. Como todos os programas em Java, MIDlets são totalmente portáveis sendo feitos para serem executados em qualquer plataforma. Para escrever um MIDlet, pode-se obter o Sun's Wireless Toolkit do site do Java, o qual é disponível para diversas plataformas e é gratuito.

Um MIDlet possui os seguintes requerimentos para ser executado em um telefone celular: Um MIDlet precisa ser empacotado em um arquivo.jar (ex: usando a jar-tool); O arquivo .jar precisa ser pré-verificado.

Fonte: WIKIPÉDIA. Desenvolvido pela Wikimedia Foundation. Apresenta conteúdo enciclopédico. Disponível em: <http://pt.wikipedia.org/w/index.php?title=MIDlet&oldid=1770115>. Acesso em: 5 Mar 2007

Para compilar esses códigos, podemos baixar algum emulador disponível da internet. Esses ambientes facilitarão o processo de compilar, rodar e empacotar nossa aplicação. Como sugestão, baixe o emulador indicado pelo Wikipédia, pois no próximo post iremos precisar de algumas de suas ferramentas. Também sugiro a IDE Eclipse (atual versão 3.2.1 até está data), que poderá ser muito útil para aumentar nossa capacidade de produção.

No próximo post iremos criar alguns programas e testar nos ambientes disponíveis, analisando o código fonte linha a linha, ampliando progressivamente os conhecimentos de Java ME.