Buscar

Todamateriaonline_ProgDispositivosMoveis

Prévia do material em texto

Programação para Dispositivos Móveis
AULA 1
Dispositivos moveis normalmente possuem algumas diferenciações quando comparados com equipamentos maiores:
Possuem memoria com menor capacidade
Possuem processador com menor capacidade
Possuem maior autonomia de bateria/menor consumo de energia
Tendem a ser mais seguros e confiáveis
Podem possuir conectividade ou não.
São mais rápidos na inicialização e no desligamento
Podem ser mais resistentes a queda
Presença no mercado
Telefones celulares comuns estão convergindo para smartphones
Os Netbooks e Notebooks sofrerão transformações, equipamentos mais robustos como ultrabooks, equipamentos que utilizam touch tomaram os seus lugares.
Surgimento de novos equipamentos com redes sem fio e com longa autonomia de bateria
Conceitos
Plataforma, essa palavra será utilizada como sendo um tipo de ambiente com características especificas.
Plataforma de execução, refere-se ao ambiente onde os softwares são executados. Ela pode ser diferente em cada tipo de dispositivo, todavia deve atender as capacidades e limitações específicas de cada um deles sem prejudicar a execução dos softwares.
Plataforma de desenvolvimento, refere-se ao ambiente que possibilita o desenvolvimento (criação ou manutenção) de softwares. 
Uso da plataforma de desenvolvimento
Normalmente as plataformas de desenvolvimento são instaladas e utilizadas em computadores do tipo desktop ou notebook e os resultados são transferidos e utilizados pelos dispositivos moveis.
Compilação, interpretação e bytecode
Compilação: processo que realiza a tradução da linguagem de programação para a linguagem da maquina. O produto final da compilação é o software.
Interpretação: processo onde programas de computador leem um código-fonte de uma linguagem e o executam sem necessariamente converte-lo em software.
Bytecode: é o termo utilizado para descrever compilação para um software, normalmente de maquina virtual. A compilação gera um programa que pode ser executado pelo sistema operacional .Um bytecode apesar de ser compilado não é imediatamente executável.
Tecnologias para desenvolvimento
Java Micro Edition (JME)
Possui compatibilidade com diversos equipamentos e é aceita na maioria dos dispositivos moveis. Programas feitos para a Java ME consomem poucos recursos dos dispositivos graças a KVM (kilo virtual machine). Tem uma vasta quantidade de bibliotecas livres que podem ser encontradas na internet.
Android
Atende dispositivos moveis mais avançados e que permite desenvolvimento de programas através da linguagem Java. Conta com sistema operacional baseado em Linux e utiliza uma maquina virtual chamada Dalvik criados a partir do java. A maquina virtual Dalvik converte o bytecode do formato java para o formato Dalvik. Plataforma de código aberto. Não possui restrição quando ao acesso as funcionalidades nativas do dispositivo móvel. Além disso, o desenvolvedor conta com recursos muito poderosos para exibição gráfica 2D e 3D e também conta com um poderoso e leve banco de dados com suporte SQL através do SQLite. Outro ponto muito importante para os aplicativos dessa plataforma é que eles podem ser divulgados e distribuídos facilmente através do Android Market, um serviço on-line que o Google oferece e que já vem pré-instalado no Android.
IOS- Object C
RIM
Aula 2
API – refere-se a um conjunto de rotinas e padrões estabelecidos por um software para a utilização das suas funcionalidades, por aplicativos que não pretendem envolver-se em detalhes da implementação do software, mas apenas usar o seu serviço.
CLDC – Connected Limited Devide Configuration, refere-se ao conjunto de configurações que caracterizam dispositivos limitados em memória e poder de processamento.
Limite de 128 KB de memória para executar o Java;
Limite de 32 KB de memória para alocação em tempo de execução;
Interface de usuário com recursos limitados;
Baixa potência, normalmente são alimentados por bateria;
Limitações de conectividade, normalmente wireless, com velocidade limitada e com algumas restrições.
CDC – refere-se ao conjunto de configurações que caracterizam dispositivos mais potentes em memória, poder de processamento e conectividade de rede.
No mínimo 512 KB de memória para execução do Java;
No mínimo 256 KB de memória para alocação em tempo de execução;
Conectividade com rede, normalmente persistente e veloz
MIDP – refere-se ao perfil que complementa a configuração que caracteriza o dispositivo. Um perfil é uma extensão da configuração e ele provê as bibliotecas para o desenvolvedor escrever aplicativos para um determinado tipo de dispositivo.
Plataforma Java ME:
usa subconjuntos reduzidos de componentes da plataforma Java SE e também define APIs, especificamente para dispositivos móveis e dispositivos embarcados
Java ME SDK 3.0.5
Integrado com NetBeans 
Gerenciamento de múltiplos dispositivos
Suporte a biblioteca LWUIT 1.5
Monitoramento de rede, CPU profiler, banco de dados do dispositivo
NetBeans suporta tanto o desenvolvimento em CLDC quanto em CDC
Se seu computador dispõe de poucos recursos, o SDK é a ferramenta mais indicada, 
Caso contrário, o NetBeans já inclui o SDK e é uma ferramenta profissional de desenvolvimento
Aula 3
Sobre KVM
A KVM é uma maquina virtual que oferece suporte ao java micro edition em plataformas de 16 ou 32 bits. A KVM possui um tamanho extremamente reduzido e consome poucos recursos do dispositivo em sua execução, pois o fabricante de um dispositivo que utiliza a tecnologia java micro edition tem a liberdade de modificar e de personalizar a KVM em conformidade com suas necessidades, por isso, ela é realmente pequena e leve. 
Como a KVM implementa parcialmente as especificações da JVM (Java Virtual Machine) os aplicativos gerados para uma plataforma podem não ser portáveis para outras. 
A vantagem, é que diversas funcionalidades de maquinas virtuais e da linguagem que não eram necessárias para a maior parte das aplicações tornam-se opcionais, possibilitando ao fabricante do dispositivo escolher uma configuração em particular.
Como desvantagem a linguagem e a maquina virtual tiveram que ser modificadas e as bibliotecas tb tiveram que ser reduzidas, tornando a programação para a plataforma de execução Java Micro Edition diferente da Java Standart Edition e da Java Enterprise Ediition.
Midlet
E uma aplicação da plataforma java micro edition que utiliza recursos do MIDP e CLDC. Para gerenciar e executar aplicações MIDlet, os dispositivos possuem um software denominado AMS que é responsável por controlar os aplicativos. Esse software gere a instalação, o armazenamento e o comportamento da MIDlet durante a execução. O AMS também é responsável por receber propriedades do arquivo descritor da aplicação e por notificar alterações no estado da MIDlet.
Os estados do Midlet
Podemos dizer que uma MIDlet possui um conjunto de classes projetadas para ser executada e controlada pelo AMS e que os métodos da MIDlet permitem ao AMS criar, iniciar, pausar e destruir uma MIDlet. Na prática da programação, trabalhamos normalmente com três estados da MIDlet geridos pelo AMS, que são:
Iniciada (started): realiza a aquisição de recursos e inicialização da execução (startApp).
Pausada (paused): realiza a liberação parcial de recursos, modo de espera (pauseApp).
Destruido (destroyed): realiza a liberação completa de recursos, finalização (destroyApp).
Empacotamento da aplicação
Para facilitar a organização e a manipulação da aplicação, as MIDlets são colocadas (empacotadas) dentro de um arquivo de extensão JAR. Todo arquivo do tipo JAR possui a capacidade de ajuntar ou de compactar arquivos e pastas dentro dele, de forma similar como acontece com um arquivo gerado pelo compactador ZIP. 
O trabalho de empacotamento normalmente é realizado pela própria ferramenta utilizada para o desenvolvimento de software e, além das classes Java que compõe o programa, também dentro do arquivo JAR é incluído um arquivo de manifesto que indica a classe que utiliza determinada MIDlet. Na estrutura empacotada podem existir também recursos quevão além dos programas Java, como, por exemplo, arquivos de imagem e som.
Distribuição da aplicação
Depois de empacotar, chega o momento de distribuir a aplicação para que ela possa ser instalada nos dispositivos.
Para auxiliar com o processo, existe um arquivo de extensão JAD (Java Application Descriptor) que deve ser gerado após o empacotamento das MIDlets e esse arquivo deve conter um texto que descreva as MIDlets que são distribuídas como arquivos JAR. O tipo JAD comumente é utilizado para distribuir aplicações Java ou jogos para que possam ser baixados para dispositivos móveis, pois dentro deles existem referências de localização do JAR, a lista das MIDlets e outros atributos. A distribuição da aplicação pode ser realizada por rede ou localmente. 
Transferindo a Aplicação
A distribuição local requer que os arquivos da MIDlet sejam transferidos para o dispositivo através de uma conexão, como cabo USB, Bluetooth ou IrDA (necessitando eventualmente de hardware e software específico para realizar a transferência).
A distribuição por rede acontece via protocolo HTTP (Hypertext Transfer Protocol) e os procedimentos a seguir acionam um tipo de instalação conhecida por OTA (over the air):
Enviar os arquivos do tipo JAR e JAD a um servidor Web que esteja acessível ao dispositivo móvel através via HTTP;
O usuário entra em um software cliente HTTP, com o navegador do dispositivo, baixa o arquivo JAD e os MIDlets necessários são instalados.
Segurança de MIDLET e Verificação do ByteCode
Assim como acontece com uma aplicação Java na plataforma Standard Edition, antes de colocar uma aplicação na memória (ou instalá-la), o verificador de classes da VM precisa verificar o arquivo recebido para ter certeza que está correto, conferindo cada item em seu conteúdo interno. 
Todavia, devido às limitações de memória e de poder de processamento disponível em um dispositivo móvel, a verificação que o verificador de classes da VM realiza pode ser apenas superficial, pois por questões de limitações os verificadores de classes da VM normalmente possuem funcionalidades reduzidas, sendo capazes apenas de realizar verificações rápidas e incompletas.
Por esse motivo, o bytecode de cada classe da MIDlet deve ser pré-verificado usando um pré-verificador, para que a VM execute a classe poupando parte do trabalho de realizar as verificações que foram realizadas previamente, tornando a execução rápida sem abrir mão da segurança.
Interface gráfica
As classes gráficas (classes GUI) do Java Micro Edition são definidas pela JCP (Java Community Process) e estão inclusas no MIDP. Estudaremos algumas das classes gráficas da MIDP para a criação de telas.
Existem dois tipos de APIs para o desenvolvimento de interfaces gráficas: a High Level API e a Low Level API.
HIGHT LEVEL: A primeira consiste em classes, como Alert, List e Form, que são componentes que possuem funcionalidades pré-determinadas e que possibilitam a portabilidade das aplicações entre dispositivos diferentes, pois a implementação High Level API se encarrega de fazer as adaptações necessárias para o hardware e o estilo da interface de usuário nativa do dispositivo. 
LOW LEVEL: A segunda classe é que capaz de desenhar e pintar objetos.
Utilizando a High Level API e a Low Level API é possível escrever aplicativos atraentes para diferentes dispositivos móveis, todavia a aparência e o comportamento são sempre um desafio. Devido a diferenças de implementação em fontes, layout, menus, dentre outras coisas, o mesmo aplicativo pode ter aparência e se comportar de forma muito diferente em diferentes dispositivos, além disso, grande parte da funcionalidade da interface do usuário avançada não é acessível via High Level API, obrigando o desenvolvedor a recorrer a Low Level API para alcançar o resultado desejado à custa de esforço adicional.
Existem 2 níveis de interface com o usuário nos MIDlets:
High-level APIs
javax.microedition.lcdui.Screen
TextBox
List
Alert
Form
Screen
Gauge
Low-level APIs
javax.microedition.lcdui.Graphics
javax.microedition.lcdui.Canvas
Herdam de javax.microedition.lcdui.Display
Bibliotecas Gráficas
O uso de bibliotecas pode simplificar o desenvolvimento de aplicações, facilitando o trabalho. Uma biblioteca notória é o LWUIT (Lightweight UI Toolkit), ela foi desenvolvida para simplificar a criação de aplicativos atraentes para diferentes dispositivos móveis, dispondo de recursos que simplificam a criação de interfaces de modo bem atraente
A vantagem dessa biblioteca é que ela emprega um paradigma de programação semelhante ao da biblioteca Swing do Java SE e usa também uma avançada ferramenta de criação de telas e temas para que os elementos se comportem da mesma maneira em todos os dispositivos. Vale a pena dar uma conferida, você pode obter mais informações sobre essa biblioteca e a ferramenta no site Oracle.
Aula 4
CLDC
Java.lang
Java.io
Java.util
Javax.microedition.io
MIDP
javax.microedition.lcdui
javax.microedition.midlet
javax.microedition.rms
Hierarquia das principais classes
Hight level API
Contem uma série de componentes para desenvolvimento de aplicativos móveis
O sistema é responsável por desenhar na tela, logo os aplicativos são desenhados utilizando o look & feel do aparelho
As interações primitivas (navegação, scroll) são executadas pelo aparelho e não pelo software/aplicativo
Entrada (input) é fornecido pelo aparelho. Logo, low-level input não é disponívelInteração com o usuário
O Command (javax.microedition.lcdui.Command) é o principal mecanismo de interação entre o seu MIDlet e o usuário
É através dele que há o fluxo de navegação entre os vários Displayables do seu software
Todo Screen e Canvas pode ter uma quantidade arbitrária de comandos
Cada comando fica associado a uma tecla
Command
Command meuCommand = new Command(label, type, priority)
label: descreve a função ao usuário. É o texto visível ao usuário
type: pode ser BACK, EXIT, STOP, HELP, OK, CANCEL, ITEM, ou SCREEN.
Cada aparelho pode mapear diferentemente cada tipo de comando!
priority: juntamente com type, permite que um comando
tenha maior prioridade
Command Listener
O gerenciamento do Command é baseado na função que “escuta” os eventos
Cada objeto Displayable tem um único CommandListener
Quando o usuário invoca um Command o evento é passado para o CommandListener definido
Um objeto necessita implementar a interface CommandListener e é seu método commandAction
Form
Utilizado em situações onde um Screen com uma única função não é suficiente
A classe Form pode conter outros elementos de interface, chamados de itens (javax.microedition.lcdui.Item)
Porém, lembrem que o espaço de uma tela pode ser pequena, logo não abusem da quantidade de itens!
Os seguintes itens podem ser colocados dentro de um Form
ChoiceGroup: utilizado em listas de opções (simples ou múltipla escolha)
DateField: componente utilizado para mostrar data e tempo
Gauge: mostra um valor numérico graficamente
ImageItem: utilizado para mostrar imagens
StringItem: utilizado para mostrar texto estático
TextField: utilizado para entrada de texto
Alert
Mostra ao usuário mensagens
 É possível associar um ícone
Este método é responsável por trocar o display corrente.
switchDisplayable(Alert alert, Displayable nextDisplayable) 
Este método é usado em todos os métodos de tratamento de eventos Actions
Controle de Fluxo
A linguagem de programação Java provê alguns meios para manipular fluxo e dados digitados pelo usuário. A partir de agora, vamos estudar o básico da manipulação de fluxo e de dados.
O comando if, por exemplo, verifica se o dado atende uma determinada condição. Se analisarmos o código que foi gerado automaticamente pela IDE NetBeans, o trecho da linha 106 possui a instrução if (command == okCommand) que serve para verificar se o menu “OK” foi acionado.
Observando o código um pouco antes, também encontramos outra verificação na linha 102 que possui a instrução if (command == exitCommand)que serve para verificar se o menu “Sair” foi acionado. A instrução else separa as duas condições da instrução if,para garantir que apenas uma delas seja executada quando uma determinada condição for atendida.
Se continuarmos nossa observação do código e olharmos um pouco antes, notaremos que outra instrução if verifica se o nosso formulário está sendo visualizado pelo usuário na linha 101, ou seja, somente se o nosso formulário estiver sendo visualizado é que as outras instruções if serão executadas.
Vamos analisar o código acima:
A variável texto recebe do campo de texto o que foi digitado pelo usuário através do método getString do objeto nomeTextField. A instrução if verifica se esse texto digitado é nulo ou vazio e informa o usuário da necessidade de preencher o campo.
Como pode ser observado, toda a verificação é realizada através da instrução if ((null == texto) || ("".equals(texto.trim()))) que verifica se o texto é nulo ou se não há texto. Para verificar se não há texto, o método trim remove quaisquer espaços digitados antes e depois do texto que foi digitado e o método equals verifica se o texto digitado é igual a nenhum texto, ou seja, se é vazio. Se as condições de não haver texto forem verdadeiras, o método getAlert retorna o objeto que representa a janela de alerta e o método setString define o texto a ser exibido ao usuário por meio desta janela
.
O método switchDisplayable foi criado pela IDE NetBeans e serve trocar o que está sendo exibido na tela e para retornar a um ponto de exibição. Neste momento, não vamos analisar esse método, vamos apenas acreditar que serve para exibir a nossa janela de alerta.
1. Como converter:
  A. Texto para inteiro:
       String texto = "8";
       int numero = 0;
       try {
              int numero = Integer.parseInt(texto, 10);
       } catch (NumberFormatException nfex) {
       // Erro ao converter
       }
  B. Inteiro para texto:
       int numero = 10;
       String texto = Integer.toString(numero);
      // ou String texto = "" + numero;
 
2.     Como ordenar números em ordem crescente:
       int[] valores = new int[]{3, 4, 7, 5, 2, 6};
       for (int j = 0; j < (valores.length - 1); j++) {
       int menor = valores[j];
       for (int i = (j + 1); i < valores.length; i++) {
         if (valores[i] < menor) {
           menor = valores[i];
           int troca = valores[j];
           valores[j] = menor;
           valores[i] = troca;
         }
       }
     }
Aula 5
Tecnica
Existem muitas boas práticas e técnicas de programação que contribuem para o bom desenvolvimento de uma aplicação. Primeiramente, entenderemos como são classificados os erros de programação e como podemos aplicar boas práticas e técnicas de programação a fim de evitá-los.
Antes de saber sobre o processo de depuração, no entanto, é preciso saber os tipos de erros que você precisará localizar e corrigir. Os erros de programação se encaixam em três categorias:
Erros de compilação
Erros em temo de execução
Erros na logica de programação
Erros de Compilação
Erros de compilação, também conhecidos como erros de compilador, são erros que ocorrem antes de seu programa executar. Quando você tenta executar um programa, o código necessita ser traduzido (compilado) para um idioma que possa ser compreendido e executado pelo dispositivo. Se o compilador encontrar algo que não possa traduzir, haverá um erro de compilação, um aviso será emitido ao programador e o processo possivelmente não irá adiante. A maioria dos erros de compilação ocorre por erros de digitação de código-fonte.
Erros de Tempo de Execução
Erros em tempo de execução são erros que ocorrem enquanto o programa é executado. Eles normalmente ocorrem quando o programa tenta uma operação que é impossível executar. Temos como exemplos clássicos a divisão por zero, a utilização de objetos que são nulos e, ainda, a conversão de objetos para tipos incompatíveis, todavia o exemplo mais simples de elucidar é o da divisão por zero.
Erros de logica
Erros lógicos são erros que impedem seu programa de fazer de maneira adequada o que deveria ser feito - existem muitas problemáticas causadas por erros lógicos. Nessa categoria de erro seu código-fonte pode ser compilado e executado aparentemente sem erros, todavia quando a lógica é processada, o erro ocorre e o resultado é de algum modo deficitário.
Boas praticas
Embora a IDE NetBeans possua fantásticos recursos capazes de apontar erros de forma antecipada a execução, é importante ressaltar a importância de se conhecer e aplicar técnicas e boas práticas de programação para facilitar nosso trabalho, pois alguns erros escapam.
Documentação e comentários: Para reduzir o tempo de manutenção e de desenvolvimento de novas funcionalidades em uma aplicação é recomendável sempre documentar o código-fonte, o fluxo do processo e a forma como os dados são armazenados e processados. Adicionalmente, tudo o que fez e faz parte do projeto deve ser documentado: 
Uso de “curto-circuito” na comparação: A fim de aumentar o desempenho da aplicação, nas comparações, sempre coloque do lado esquerdo o que possuir maior probabilidade de mudança ou o que for mais importante. A verificação da condição acontece da esquerda para a direita e, neste caso, se a primeira verificação retornar “false” a verificação da segunda não acontece e algum tempo de análise será poupado. A este encurtamento de análise dá-se o nome de “curto-circuito”.
Variáveis de objetos nulas: Nas instruções de comparação, verifique sempre qualquer objeto que tenha a possibilidade de não ter sido instanciado, pois um erro em tempo de execução ocorrerá se um atributo ou um método de uma variável de objeto nula (“null”) for invocado.
Troca da posição de variáveis e constantes na comparação: Para evitar erros em tempo de execução, em comparações, é aconselhável que a constante esteja à esquerda.
Limitação de novos objetos: Em dispositivos móveis com pouco poder de processamento e recursos de memória deve-se evitar criar novos objetos sem uma real necessidade, pois novos objetos tendem a consumir mais processamento e memória RAM do dispositivo.
Nomes apropriados: Para facilitar a compreensão do código e facilitar futuras manutenções, além dos comentários e das documentações é recomendável que você também utilize nomes apropriados para tudo o que codificar, inclusive em variáveis, métodos, classes, enumeradores e interfaces.
Além dos nomes apropriados, você também pode fazer uso de uma notação chamada CamelCase para facilitar a compreensão da codificação, pois através dela, mesmo sem entender do contexto, dá para ter uma ideia do que provavelmente está sendo realizado.
Depuração
Para analisar o funcionamento de um programa passo-a-passo ou para identificar e corrigir falhas e/ou erros de raciocínio logico de programas podemos utilizar uma ferramenta chamada depurador (debugger). Dica: Em modo de depuração, você também pode manipular o fluxo de controle alterando os valores das variáveis através da “janela de variáveis” e pode utilizar os outros botões para continuar, parar ou movimentar para o próximo ponto de parada, entrando nele ou não. Você pode aprender e evoluir muito testando a ferramenta de depuração e procurando tutoriais de depuração usando o NetBeans.
Aula 6
Construção de Formulários – A codificação
Essa é a codificação de uma MIDlet (linha 7) e os métodos obrigatórios “startApp”, “pauseApp” e “destroyApp” estão presentes. Estes métodos efetuam o tratamento dos eventos de Início, Pausar ou encerrar a aplicação.
O Construtor:
É o método que possui o mesmo nome da Classe que serve para definir como o objeto será criado. 
Quando definimos um construtor vazio, estamos deixando a sua construção implícita, para a super classe.
 public OlaMundoMidlet(){}
Quando a MIDlet iniciar, o método “startApp” será executado e a variável “current” receberá a referência do que está na tela do dispositivo (linha 12). Se a tela do dispositivo ainda não tiver recebido qualquer objeto de nossa aplicação e seu conteúdo for nulo (linha 13), então o objeto “helloScreen” será criado (linha 14). O objeto “helloScreen” é um formulário cuja a codificação está a listadaseguir. Repare que após criarmos o objeto, colocamo-lo na tela do dispositivo (linha 15).
Através deste exemplo, somos capazes de concluir que o objeto exibido na tela do dispositivo pode ser obtido através de um objeto do tipo “Displayable”. Também podemos concluir que “Display.getDisplay(this)” retorna a tela do dispositivo, onde podemos pegar o objeto que está sendo visualizado (“.getCurrent()”) no momento ou colocar um outro objeto para ser visualizado (“.setCurrent(…)”).
Esta Classe herda as características da classe Form e implementa o CommandListener.Form – Define que a classe herda as características de um formulário.
CommandListener – Implementa o tratamento de eventos para o objeto
Essa é a codificação do “OlaForm”, um Form que implementa a interface “CommandListener” (linha 5), que tem a função de receber os eventos de comando através do método “commandAction”. Quando o Form for carregado, o construtor “OlaForm” será executado (linha 10) e tudo será preparado, as variáveis “midlet” e “exitCommand” serão alimentadas e os elementos do formulário inicializados. A variável “midlet” (linha 12) receberá a MIDlet que criou o formulário e a variável “exitCommand” (linha 13) receberá um objeto de comando que terá a função de encerrar a aplicação.
	
O método “init(...)”, (linha 17) receberá o texto “Sou + Estacio” e o colocará em uma variável de objeto “helloText” (linha 18), do tipo “StringItem”, que será anexada a esse formulário (linha 19), ou seja, o formulário criado terá um ”item de String” com o texto “Olá Sou + Estacio!”.
O métodos “addCommand(...) (linha 20( coloca o menu “Sair” (“exitCommand”) no formulário e o método “setCommandListenet(this)” (linha 21) faz com que todo evento de comando deste formulário seja recebido através do método “commandAction”. 
O método “commandAction” (linha 24) recebe os eventos de comando deste formulário e compara-os com o objeto “exitCommand” (linha 25) para ver se é para sair da aplicação (linha 26).
Em MIDP 2.0, foi introduzido o pacote javax.microedition.lcdui.game que disponibiliza cinco classes com uma grande variedade de recursos para a produção de jogos, são elas:
1. GameCanvas; utiliza recursos de baixo nível para criação de telas gráficas
2. Layer; cria uma camada gráfica na interface LayerManager
3. Sprite: Desenvolvedores em Java Micro Edition (JME) podem utilizar a classe chamada Sprite que é a representação de uma imagem na memória. Um Sprite possui capacidades para manipulação de imagem que vão além da disponível em um objeto de imagem padrão
4. TiledLayer; é utilizada para desenhar cenários
5. LayerManager: é a classe responsável pelo gerenciamento das diversas camadas gráficas na interface
Aula 7
Construção de um jogo simples
Antes de iniciarmos, é preciso ressaltar que o desenvolvimento de jogos requer muito do programador, tanto na lógica, quanto na imaginação. Para dispositivos móveis, o desenvolvimento de jogos usando Java Micro Edition exige, no mínimo, uma boa lógica de programação em liguagem Java e alguns conhecimentos dos objetos da plataforma em que a aplicação será executada.
Nesta parte da aula, começaremos com um jogo bem simples, faremos um jogo da velha e criaremos passo-a-passo cada parte do jogo. Você perceberá ao longo da execução do trabalho de desenvolvimento que, apesar da simplicidade do jogo, a tarefa possui um bom grau de complexidade.
Nesta etapa, incluiremos funcionalidades para que possamos controlar e definir o que será apresentado nela. Os objetos Display e Displayable fornecem os recursos necessários para tal tarefa e o pacote “javax.microedition.lcdui”, que é nativo da plataforma Java Micro Edition, concede o acesso aos objetos de tela.
 
Observe a codificação a seguir e, prestando atenção nas observações e nas dicas, inclua os códigos-fontes conforme indicam os passos 1 e 2 da ilustração.
Java é caso-sensitivo, ou seja, maiúsculas e minúsculas são diferentes para ele.
A instrução “import javax.microedition.lcdui.Display” é necessária para o método getDisplay() e “import javax.microedition.lcdui.Displayable” é necessária para o método setDisplayable().
Sempre que quiser que o IDE NetBeans te ajude com alguma codificação, digite uma parte do código, pressione (e mantenha 
pressionada) a tecla CTRL e depois pressione uma vez a tecla de BARRA DE ESPAÇO.
Documentando o projeto do jogo
Daqui por diante, documentaremos todo o código-fonte que fizermos a fim de facilitar uma eventual e futura manutenção ou aprimoramento de nossos códigos.
O IDE NetBeans possui bons recursos para documentação e conta com um visualizador de HTML embutido que provê a capacidade de exibir a documentação de atributos e métodos na medida em que você escreve, ou seja, se você documentar um código-fonte, poderá visualizar a documentação que fez quando for reutilizar a codificação, independentemente da parte em que esteja programando.
Dica: Para documentar um método obtendo ajuda do IDE NetBeans, coloque o cursor imediatamente acima do atributo ou método desejado, digite /** e dê ENTER que o IDE preparará o local do texto para que você documente.
Você também pode incluir algumas tags de HTML na documentação para destacar partes do texto, pois a visualização dessa documentação ocorrerá ou, em um visualizador de HTML ou, em um navegador WEB.
Criando um formulário de boas vindas
Desta vez, experimentaremos desenvolver todo o trabalho de criação do formulário manualmente. Criaremos alguns objetos e, por último, os colocaremos no formulário que iremos construir e exibir. Começaremos pelo texto de boas-vindas, que será exibido através de um objeto StringItem (campo de texto). Precisaremos incluir a importação da biblioteca que dá acesso ao objeto StringItem (passo 1) e codificar o método (passos 2, 3, 4 e 5).
Dica: Para economizar digitação, você pode começar a programar pelo passo 2, ao digitar StringItem você deve pressionar CTRL e BARRA DE ESPAÇO para incluir automaticamente a importação da biblioteca StringItem na classe, ou seja, o passo 1 é realizado automaticamente	
Para testarmos a funcionalidade do menu, alteraremos o novo método para que ele assuma provisoriamente a funcionalidade de sair da aplicação e para realizarmos essa tarefa, seguiremos as instruções da ilustração. 
Com essas alterações, definimos que os eventos do CommandListener do formulário de boas-vindas serão recebidos em nossa MIDlet através do método setCommandListener(this) (passo 1), criamos um método para sair da MIDlet (passo 2) e fizemos sua documentação (passo 3). Também substituímos o conteúdo do método commandAction (passo 4) para que a aplicação seja encerrada, desde que o evento venha do formulário de boas-vindas e que o botão pressionado seja o botão de menu “OK”.
Após a conclusão dessas alterações, o menu “OK” fará nossa aplicação ser finalizada. Para validar o funcionamento das alterações e realizar testes, execute a aplicação pressionando o botão “Executar projeto principal” ou a tecla F6.
Classe Canvas
A classe Canvas também fornece métodos ao desenvolvedor para lidar com ações de jogo, eventos-chave, e eventos de ponteiro (se for suportado pelo dispositivo). Também são fornecidos métodos para identificar as capacidades do dispositivo e mapeamento de teclas e, assim como acontecem com outras subclasses, como as derivadas de Displayable, a classe Canvas também pode ouvir os comandos de menu.
Ao contrário de outros Displayables, para que seja possível usar a classe Canvas, ao menos, uma implementação é necessária na subclasse, pois o método paint é declarado como abstrato (abstract) e, por isso, deve ser implementado.
Iniciaremos criando a classe JogoDaVelhaUI. Clique como botão auxiliar do mouse sobre o pacote br.edu.estacio.j2me, depois siga as orientações da ilustração (passos 1, 2, 3, 4 e 5):
Faremos com que a classe JogoDaVelhaUI se torne uma subclasse da classe Canvas, para isso, modifique o código-fonte incluindo as instruções “extends Canvas” (passo 1) após o nome da classe. Como dito anteriormente, uma subclasse derivadada classe Canvas necessita implementar o método abstrato paint, portanto, uma marcação de erro ocorre pela falta dessa implementação e você pode aguardar que o IDE NetBeans exiba uma lâmpadazinha a esquerda da linha onde está o nome da classe para contar com ajuda e solucionar o erro com facilidade. Clique nessa lâmpada e depois em “Implementar todos os métodos abstratos” (passo 2) - o IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário automaticamente:
Ao realizar essa ação, observe que foi adicionado em nosso código-fonte um novo método, provido pela classe Canvas, que é capaz de receber o evento para desenho de tela:
Como último passo dessa etapa, modificaremos o comportamento do menu “OK” para que, ao invés de sair de nossa aplicação, ele abra a classe JogoDaVelhaUI e exiba a tela que criamos. Conforme demonstra a ilustração, selecione e abra o arquivo VelhaMidlet.java (passo 1), depois localize no código-fonte o método commandAction (passos 2). Comente a instrução que sai da aplicação (passo 3) e coloque a instrução this.setDisplayable(new JogoDaVelhaUI()) para exibir na tela a nossa classe JogoDaVelhaUI (passo 4)
Entendendo o código que desenha o tabuleiro
Quando nosso programa estiver funcionando, o método paint será chamado assim que a classe estiver pronta para ser desenhada e trará consigo um objeto gráfico (Graphics g) que permitirá desenhar na tela. Em nosso exemplo, esse objeto gráfico vem através da variável g que é copiada para a variável de classe graph. Posteriormente, os métodos limparTela e desenharTabuleiro são chamados, conforme demonstra o trecho de código:
O método limparTela faz com que o objeto gráfico defina sua cor de desenho como branca e desenhe um retângulo por toda a tela, ou seja, tudo na tela é apagado por um enorme retângulo branco. O método setColor define a cor que o objeto gráfico assumirá e o método fillRect desenha o retângulo, conforme demonstra o trecho de código:	
Os três números dentro de setColor são para definir a cor (esquema de cores RGB). Você pode experimentar alterar a cor trocando os números, todavia deve respeitar o intervalo entre 0 (zero) e 255 (duzentos e cinquenta e cinco).
Os quatro números dentro de filltRect são para definir respectivamente a posição dos eixos x e y, a largura e a altura do retângulo. Você também pode experimentar alterar as dimensões do retângulo alterando os números - tente números entre 0 (zero) e 100 (cem) para obter melhor visualização.
O método desenharTabuleiro utiliza os métodos setColor e filltRect para desenhar os traços do tabuleiro e utiliza o método drawString para desenhar um número em cada lacuna do jogo, conforme demonstra o trecho de código:
Desenvolvendo a estrutura do jogo da velha
Precisamos construir a estrutura que controlará o jogo da velha e, nesta parte da aula, teremos que utilizar bastante imaginação e lógica de programação para fazer o jogo funcionar.
Quando nosso jogo estiver concluído, utilizaremos esses métodos para emitir avisos (eventos). A ideia é que o método efetuarJogadaJogoDaVelhaPartidaEvent sirva para informar que uma jogada acabou de acontecer. No primeiro parâmetro (“char peca”) desse método, virá a peça que foi jogada, ou seja, virá um “X” ou um “O” e, no segundo parâmetro (“int posicaoTabuleiro”), virá a posição onde a jogada foi realizada, ou seja, virá um número com intervalo entre 0 (zero) e 8 (oito) para indicar a posição da jogada no tabuleiro, conforme a ilustração:
Para o método resultadoJogoDaVelhaPartidaEvent a ideia é que ele sirva para informar que o jogo acabou. No primeiro parâmetro (“boolean haVencedor”) desse método, virá a informação de que há ou não há um vencedor. Havendo um vencedor, os outros parâmetros trarão a peça vencedora (“char peca”) e um arranjo com as posições em que as peças vencedoras se encontram no tabuleiro (“int[] posicoesTabuleiro”).
Agora que já temos o conceito, aplicaremos a ideia em nossa classe JogoDaVelhaUI seguindo os passos da ilustração. Primeiro, selecione e abra o arquivo “JogoDaVelhaUI.java” (passo 1) e depois digite “implements JogoDaVelhaPartidaInterface” (passo 2) após a classe Canvas - note que o nome a ser implementado é exatamente igual ao nome do arquivo de interface que criamos sem a extensão (“.java”).
Como estamos implementando uma interface, é necessário que nossa classe contenha uma implementação dos métodos dela, portanto, uma marcação de erro ocorre pela falta dessa implementação, todavia você pode aguardar que o IDE NetBeans exiba uma lâmpadazinha a esquerda da linha onde está o nome da classe para contar com ajuda e solucionar o erro com facilidade. Clique nessa lâmpada e depois em “Implementar todos os métodos abstratos” (passo 3) - o IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário automaticamente.
Ao realizar essa ação, observe que foram adicionados dois novos métodos em nosso código-fonte, providos pela interface JogoDaVelhaPartidaInterface:
O IDE NetBeans incluiu os métodos e colocou uma instrução dentro de cada um deles para informar que operações não são suportadas ainda. Modificaremos esses métodos para que sejam capazes de desenhar na tela, siga as orientações da ilustração:
Conforme foi dito anteriormente, o método efetuarJogadaJogoDaVelhaPartidaEvent servirá para informar que uma jogada acabou de acontecer. No primeiro parâmetro (“char peca”) desse método, virá a peça que foi jogada, ou seja, virá um “X” ou um “O” e, no segundo parâmetro (“int posicaoTabuleiro”), virá a posição onde a jogada foi realizada, ou seja, virá um número com intervalo entre 0 (zero) e 8 (oito) para indicar a posição da jogada no tabuleiro. No passo 1, o valor da posição do tabuleiro é utilizado para formar uma coordenada x e y a fim de posicionar o desenho da jogada na tela. Se a variável peca trouxer um “X”, um quadrado será desenhado na cor bege, todavia, se a variável peca trouxer um “O” círculo será desenhado na cor roxa, conforme ilustra a imagem:
O método resultadoJogoDaVelhaPartidaEvent servirá para informar que o jogo acabou. No primeiro parâmetro (“boolean haVencedor”) desse método, virá a informação de que há ou não há um vencedor. Havendo um vencedor, os outros parâmetros trarão a peça vencedora (“char peca”) e um arranjo com as posições em que as peças vencedoras se encontram no tabuleiro (“int[] posicoesTabuleiro”). Em conformidade com os valores dessas variáveis, o operador ternário (“((expressao) ? verdadeiro : falso)”) irá compor uma mensagem que será armazenada na variável de texto msg e o método drawString desenhará na cor preta o conteúdo dessa variável de texto a 20 pixels acima do final do visor do dispositivo móvel, conforme o exemplo ilustrado na imagem:
Desenvolvendo a logica do jogo da velha
Precisamos construir a classe do jogo da velha e, nesta parte da aula, teremos que utilizar bastante lógica de programação para fazer o jogo funcionar. Primeiramente, criaremos no pacote br.edu.estacio.j2me uma interface chamada JogoDaVelhaInterface que terá os principais métodos necessários ao jogo. Siga os passos da ilustração, clique no pacote br.edu.estacio.j2me e selecione a “Novo” (passo 1), depois selecione “Interface Java…” (passo 2). Chame a interface de JogoDaVelhaInterface (passo 3), verifique se está no pacote br.edu.estacio.j2me (passo 4) e pressione o botão “Finalizar” (passo 5):
Agora que temos a interface pronta, criaremos a classe JogoDaVelha no pacote br.edu.estacio.j2me. Siga os passos da ilustração, clique no pacote br.edu.estacio.j2me e selecione a “Novo” (passo 1), depois selecione “Classe Java…” (passo 2). Chame a classe de JogoDaVelha (passo 3), verifique se está no pacote br.edu.estacio.j2me (passo 4) e pressione o botão “Finalizar” (passo 5):
Colocando o jogo pra funcionar
Agora que concluímos a parte lógica do jogo da velha, é chagada a hora de colocar o jogo para funcionar.
Voltaremos à interface visual para incluir a lógica do jogo da velha nela. Primeiro, selecione e abra o arquivo “JogoDaVelhaUI.java” (passos 1), depoisadicione ao código uma variável de classe com as instruções “private JogoDaVelha jogoDaVelha;” (passo 2), daí crie um construtor na classe para inicializar a variável jogoDaVelha, use “this.jogoDaVelha = new JogoDaVelha(this);” (passo 3) e, por último, modifique o método paint (passo 4). Siga os passos e as instruções da ilustração:
Agora que temos uma variável de classe jogoDaVelha inicializada pelo construtor, incluiremos os métodos para início de partida e detecção de teclas. 
Siga os passos da ilustração e adicione esses dois métodos ao código:
Temos o método iniciarPartida, que inicializa a variável graph como nula e diz ao jogo da velha, através da variável de classe jogoDaVelha, para que se prepare para iniciar uma nova partida, definindo a peça inicial com a que foi especificada em seu parâmetro.
Documentação do método iniciarPartida. 
Temos o método keyPressed, que sobrescreve um método que vem da superclasse Canvas. Esse método recebe o código da tecla pressionada e, após um cálculo, atribui o valor à variável posicaoTabuleiro. Esse cálculo faz uma subtração do código provido pela tecla pressionada com o código da tecla zero (KEY_NUM0) a fim de obter o valor numérico da tecla. Quando o resultado é obtido, é realizada a subtração de 1 (um) para compatibilizar o resultado ao intervalo do tabuleiro, que é de 0 (zero) a 8 (oito).
Após a conclusão dessas alterações, nosso jogo da velha estará funcionando. O menu “OK” fará nossa aplicação abrir a tela que monta o desenho do tabuleiro do jogo da velha e o jogo da velha estará pronto para funcionar com dois jogadores. Para validar o funcionamento das alterações e realizar testes, execute a aplicação pressionando o botão “Executar projeto principal” ou a tecla F6.
Adicionamos ao código variáveis de classe para os menus e para a interface gráfica do jogo da velha (passos 1, 2, 3, 4, 5 e 6), depois criamos dois métodos que retornam os menus “Novo” e “Sair” (passos 7, 8, 9 e 10). Por fim, modificaremos o método que recebe os eventos de comando dos menus. Codifique conforme as orientações da ilustração:
Aula 8
Persistência de Dados
Armazenamento permanente
Todo dispositivo móvel compatível com MIDP mantém uma área de memória dedicada ao armazenamento persistente de dados da aplicação. Os dados salvos nessa área de memória dedicada são mantidos mesmo se o dispositivo for desligado ou se a fonte de energia do dispositivo for removida, pois os dados são gravados atomicamente na memória do dispositivo móvel.
A partir de agora, estudaremos a API RMS, que é uma API que nos permite acessar essa área de memória dedicada ao armazenamento persistente de dados da aplicação e que provê um mecanismo uniforme para criar, destruir e modificar dados.
A API RMS garante a portabilidade para MIDlets (aplicações) em diferentes dispositivos, porque mapeia (abstrai) as capacidades que são dependentes da plataforma do dispositivo e as disponibiliza em um formato padrão, simplificando o desenvolvimento, pois os dispositivos móveis podem ser diferentes internamente, tanto no funcionamento de seus circuitos, quanto na localização física e nas capacidades de armazenamento de dados.
O objeto do armazenamento
Neste tópico, conheceremos os elementos básicos da API RMS, estudaremos alguns conceitos sobre o armazenamento de registros e entenderemos o funcionamento da classe RecordStore (armazém de registros), que pertence a API RMS e que suporta a criação e a gestão de registros:
A classe RecordStore representa o banco de dados da aplicação e possui a capacidade de armazenar registros, que são os dados que pretendemos salvar na área de memória dedicada ao armazenamento persistente de dados da aplicação.
Uma área de memória persistente reservada pela classe RecordStore pode conter zero, um ou mais registros;
Quando uma MIDlet é removida, sua área de memória persistente também é removida, ou seja, todos os dados gravados (salvos) pelo usuário nessa área de memória persistente criada por meio da classe RecordStore através dessa MIDlet também são excluídos.
O nome dado a uma área de memória persistente gerado por uma classe RecordStore é caso-sensitivo, ou seja, é sensível a caracteres minúsculos e maiúsculos e, no máximo, pode ter até 32 caracteres no padrão de codificação Unicode;
Uma classe RecordStore pode ser compartilhada para outras MIDlets desde que ele esteja dentro de um mesmo MIDlet suite (arquivo JAR) ou desde que a especificação MIDP permita chama-lo externamente em outra MIDlet suite através de um nome único. 
Agora que entendemos um pouco sobre a classe RecordStore, veremos a utilização das operações (métodos) para manipulação de registro.
Conceito para manipulação de registro
Para armazenar um dado, é preciso transformá-lo em um registro e, para isso, é preciso atribuir um código identificador a ele, pois a classe RecordStore utilizará esse código na identificação do registro (“ID de registro”) a fim de manipula-lo. Por exemplo, se quiser salvar um contato com nome e telefone, um código único deverá ser atribuído para esse contato para que ambos os campos (nome e telefone) sejam referenciados por esse código único identificador.
Se você estiver familiarizado com conceitos de banco de dados, poderá ver o “ID de registro” como o único tipo de chave primária suportada, pois os recursos para manipulação de registros são extremamente simplificados, o tipo de todo “ID de registro” é sempre do tipo inteiro (int). Também não há qualquer suporte para recursos que estão presentes na maioria dos bancos de dados relacionais, tais como tabelas, linhas, colunas, tipos de dados, e assim por diante.
Apesar da simplicidade, as operações suportadas para manipulação de registros são suficientes, pois podemos: adicionar um registro ao banco, remover um registro, alterar um registro, obter um registro salvo anteriormente e listar todos os registros existentes através de enumeração.
O registro é um arranjo de bytes (byte[]) e o desenvolvedor da aplicação deve definir como os elementos de dados serão colocados e retirados de dentro dele.
Tratamentos de Erros
Para utilizar a classe RecordStore é necessário utilizar as instruções de tratamento de erros da linguagem Java (try / catch), pois erros podem ocorrer durante as operações com os dados, tais como os relacionados na ilustração:
Cinco tipos de erros que a especificação API RMS oferece:
Como você pode notar, os erros são herdados de Exception, ou seja, são herdados também de java.lang.Throwable e podem ser manipulados através das instruções de tratamento de erros da linguagem Java (try / catch).
Banco de Dados
Para que possamos trabalhar com os registros, primeiramente é preciso abrir o banco de dados que a classe RecordStore necessita acessar. Para isso, usamos:
RecordStore.openRecordStore("NomeDoBanco", true);
Referente ao último parâmetro do método openRecordStore (String, boolean):
Quando true indica que o RecordStore será aberto e, se não existir, será criado;
Quando false, indica que o RecordStore será aberto se existir, mas não será criado caso não exista.
Atenção: É importante fechar um banco de dados que não esteja em uso, assim você poupa o dispositivo móvel (que pode ter poucos recursos) e garante o fluxo de fechamento dos dados.
Para fechar o banco de dados da RecordStore, usamos: objetoRecordStore.closeRecordStore();
Você deve considerar implementar os métodos pauseApp()e destroyApp() para que eles fechem os objetos do tipo RecordStore quando a aplicação for colocada em espera ou quando for encerrada.
Para remover um banco de dados criado, você deve utilizar o método: public static void deleteRecordStore(String recordStoreName)
A seguir temos outro trecho de codificação com um exempl
Para que seja possível remover (excluir) o banco de dados é necessário que ele pertença a MIDlet que o criou, que ele não esteja em modo de somente leitura e que também esteja fechado.
Manipulação de registro
Agora que já entendemos o básico do funcionamento da classe RecordStore estudaremos como funciona a manipulaçãode registros. Cada registro pode ser lido, localizado, removido ou modificado, segundo seu “ID de registro” e, nos exemplos a seguir, veremos como é feita a manipulação de registros.
Buscaremos o entendimento do funcionamento desses métodos da API RMS que fazem a manipulação de registros. Você perceberá que todos os dados são tratados como arranjo de bytes (byte[]) e perceberá também que, para nos auxiliar no tratamento e nas conversões dos tipos de dados, utilizamos objetos das classes ByteArrayInputStream, DataInputStream, ByteArrayOutputStream e DataOutputStream do pacote java.io.* na manipulação dos registros.
Adicionando um registro
Para salvar (incluir) um novo registro, usamos o método:
public int addRecord(byte[] data, int offset, int numBytes)
No exemplo, temos um fragmento de código-fonte modificado de uma aplicação que salva o “código”, a “descrição” e a “quantidade” de um produto. Analise o trecho e observe como o método addRecord recebe os bytes (arranjo de bytes) para adicionar o registro:
Na linha 13, a classe ByteArrayOutputStream constrói um objeto capaz de armazenar os bytes que serão salvos posteriormente como arranjo de bytes pelo método addRecord. Na linha 14, a classe DataOutputStream recebe o objeto capaz de armazenar os bytes e cria um novo objeto capaz de gravar nele, através de métodos write (linhas 15, 16 e 17) - repare como é tratado o conteúdo passado no parâmetro do método adicionarRegistro (“codigo", “descricao” e “quantidade”), neste caso temos o método writeUTF para o tipo String (texto) e writeInt para o tipo int (inteiro). Por fim, na linha 18, a variável “registro” recebe o arranjo de bytes com os dados gravados e os armazena através do método addRecord (linha 19) no banco de dados.
Alterando um registro
Para alterar um registro que já foi salvo anteriormente, usamos o método:
public void setRecord(int recordId, byte[] newData, int offset, int numBytes)
 
No exemplo, temos um fragmento de código-fonte modificado de uma aplicação que altera o “código”, a “descrição” e a “quantidade” em um registro de produto já existente. Analise o trecho e observe como o método setRecord recebe os bytes (arranjo de bytes) para modificar um registro existente:
Perceba que o código é praticamente o mesmo do exemplo anterior, salvo que temos um parâmetro novo que identifica o registro a ser modificado (int id) e que, na linha 19, ao invés de usarmos addRecord usamos setRecord. A mecânica é praticamente a mesma, ou seja, a classe ByteArrayOutputStream constrói um objeto capaz de armazenar os bytes que serão salvos posteriormente como arranjo de bytes pelo método setRecord por meio do código identificador de registro. A classe DataOutputStream recebe o objeto capaz de armazenar os bytes e cria um novo objeto capaz de gravar nele, através de métodos write. Por fim, a variável “registro” recebe o arranjo de bytes com os dados gravados e os armazena através do método setRecord no banco de dados em conformidade com o “ID de registro” (id) especificado.
Lendo um registro
Para obter um registro salvo, usamos o método:
public byte[] getRecord(int recordID)
 
Em função do “ID de registro” informado, esse método retorna um arranjo de bytes (byte[]) que contém os dados salvos no registro. 
Na linha 20, o método getRecord armazenará na variável “registro” como um arranjo de bytes (byte[]) o registro do banco de dados em conformidade com o código identificador de registro (id). Na linha 22, esse arranjo de bytes é armazenado em um objeto do tipo ByteArrayInputStream e, na linha 23, associado para um outro objeto do tipo DataInputStream que separará cada campo desse registro, através dos métodos read - observe as linha 26, 27 e 28, note que temos métodos readUTF e readInt.
Apagando um registro
ara remover um registro salvo, usamos o método:
public void deleteRecord(int recordID)
 
Em função do “ID de registro” informado, esse método remove os dados salvos no registro
NAVEGAÇÃO ENTRE REGISTROS
Para navegar entre registros, podemos utilizar uma instrução “for” do Java e o método getNumRecords de um objeto RecordStore. Dessa forma todos os registros serão percorridos, como no exemplo: for (int i = 1; i <= recordStore.getNumRecords(); i++) {byte[] registro =recordStore.getRecord(i);// ...}
Todavia, um objeto da classe RecordEnumeration é mais apropriado, eficiente e ainda permite que naveg
uemos pelos registros da classe RecordStore de forma filtrada e ordenada. Para criar tal objeto é necessário invocar o método enumerateRecords da classe RecordStore, que funciona da seguinte forma:
public RecordEnumeration enumerateRecords(RecordFilterfilter, RecordComparator comparator, boolean keepUpdated)
Por exemplo, para atribuir um objeto da classe RecordEnumeration para uma variável, podemos executar as seguintes instruções para navegar por todos os registros:
RecordEnumeration re = RecordStore.enumerateRecords(null, null, false);
Dica: Para navegar para trás você pode usar “previous” no lugar de “next” nas linhas 12 e 13.
Aula 9
Controle da aplicação
Coletor de dados de produtos
Neste passo, criaremos uma nova aplicação capaz de realizar coleta de dados de produtos. Basicamente, nossa aplicação terá três campos para preenchimento, que serão:
Código;
Descrição (nome do produto);
Quantidade.
Também incluiremos uma área na aplicação que nos permitirá listar os produtos cadastrados e editá-los. Conceitualmente a ideia da aplicação é bem simples, todavia você verá que teremos algum trabalho para desenvolver todo o controle de fluxo da aplicação, pois teremos que empregar praticamente tudo o que aprendemos até esta aula e prestar bastante atenção nos novos conceitos que ainda serão abordados.
Iniciaremos um novo projeto no IDE NetBeans, conforme demonstra a ilustração:
Seguindo os passos, primeiramente pressionamos o botão “Novo Projeto…” (passo 1), depois selecionamos “Java ME” (passo 2), daí selecionamos “Aplicativo móvel” (passo 3) e, por último, pressionamos o botão “Próximo >” (passo 4).
Seguindo os passos, nomeamos o projeto como “ColetorMobileApplication” (passo 1), deixamos selecionadas as caixas de seleção “Configurar como projeto principal” e “Criar MIDlet Olá” (passo 2) e pressionamos o botão “Próximo >” (passo 3).
Seguindo os passos, nós verificamos as configurações, mantemos selecionadas as opções CLDC 1.1 e MIDP 2.1 e pressionamos o botão “Finalizar” (passo 1).
Criando uma classe para persistência de dados
Antes de criarmos qualquer tela e alterarmos qualquer fluxo existente, primeiramente criaremos uma nova classe capaz de salvar os dados através da API RMS. A fim de facilitar o desenvolvimento futuro, construiremos esta classe para ser a mais genérica possível usando o conceito de abstração:
Com o botão direito do mouse (botão auxiliar), escolhemos as opções: “Novo” e “Classe Java…” (passo 1). Depois nomeamos a classe como “Persistencia” (passo 2) para o pacote “br.edu.estacio” (passo 3) e pressionamos o botão “Finalizar” (passo 4).
A classe produto
Neste passo, construiremos a classe para armazenamento persistente dos dados dos produtos. Essa classe será útil para manipular dados para objetos de produto.
Neste passo, construiremos a classe para armazenamento dos dados dos produtos. Essa classe será útil para construir objetos capazes de transferir valores para outros objetos.
Seguindo os passos, com o botão auxiliar do mouse, selecionamos o pacote “br.edu.estacio” e no menu popup selecionamos “Novo >”, depois “Classe Java…” (passo 1). Na janela “Nova Classe Java”, nomeamos a classe como “Produto” (passo 2) para o pacote “br.edu.estacio” (passo 3) e pressionamos o botão “Finalizar” (passo 4).
A seguir, em conformidade com a ilustração, modifique o código para que ele tenha os atributos do produto com seus respectivos tipos e adicione a documentação, conforme indica a seta:
Seguindo os passos, criamos os atributos e seus respectivos tipos para a classe (passo 1). A seguir, geraremos automaticamente, através do IDE NetBeans, os métodos do tipo “get” e “set”.
Em conformidadecom a ilustração que está a seguir, clique sobre a variável “id” (passo 1), depois clique novamente nela (sobre a variável “id”) com o botão auxiliar do mouse e, no menu popup, posicione o mouse sobre o item “Refatorar” (passo 2) e clique em “Encapsular Campos…” (passo 3):
Em conformidade com a ilustração a seguir, clique sobre a variável “id” (passo 1), depois clique novamente nela (sobre a variável “id”) com o botão auxiliar do mouse e, no menu popup, posicione o mouse sobre o item “Refatorar” (passo 2) e clique em “Encapsular Campos…” (passo 3):
Seguindo os passos, geramos através do IDE NetBeans os métodos do tipo “get” e “set”. O resultado obtido deverá ficar conforme demonstra a ilustração:
Agora que temos a classe que armazena os valores do produto, construiremos a classe que manipula esses dados a partir da classe abstrata de persistência (Persistencia.java).
Antes de prosseguirmos salve o projeto, pressione o botão “Salvar Todos”
A classe de persistência de produto
Neste passo, construiremos a classe para armazenamento persistente dos dados dos produtos. Essa classe será útil para manipular dados para objetos de produto. Siga os passos da ilustração para criar a classe de persistência de produto
Seguindo os passos, com o botão auxiliar do mouse, selecionamos o pacote “br.edu.estacio” e no menu popup selecionamos “Novo >”, depois “Classe Java…” (passo 1). Na janela “Nova Classe Java”, nomeamos a classe como “ProdutoPersistencia” (passo 2) para o pacote “br.edu.estacio” (passo 3) e pressionamos o botão “Finalizar” (passo 4).
Faremos com que a nossa classe herde da classe abstrata de persistência e implemente seus métodos. Siga a ilustração, digite “extends Persistencia” (passo 1), e aguarde uma lâmpadazinha surgir a esquerda. Clique na lâmpada e depois em “Implementar todos os métodos abstratos” (passo 2). O IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário automaticamente:
Como resultado, o IDE NetBeans adicionou todo conteúdo necessário automaticamente
Através dessa codificação, temos os pontos de entrada para os métodos de evento que nos permitirão ler e salvar registros quando os eventos de leitura e/ou gravação ocorrerem na classe pai, ou seja, ao ler ou salvar registros, esses eventos efetivarão a leitura ou o salvamento.
Note que, em nossa codificação, a importação dos pacotes também foi realizada automaticamente pelo IDE NetBeans nas linhas 3, 4 e 5.
Iniciaremos a programação dos métodos para ler, para salvar e para obter o último produto manipulado.
Entendendo o fluxo
O método abrirRecordStore chama internamente o método abrirRecordStore da classe pai (classe Persistencia) informando o nome do banco de dados para abrir ou criar.
Para o fluxo de salvamento, é preciso observar e entender que este método salvarProduto além de armazenar o produto recebido na variável de classe produto, também chama internamente o método salvarRegistro que está na classe pai (ou seja, na classe Persistencia). O método salvarRegistro, por sua vez, aciona internamente o evento salvamentoRegistroEvent de nossa classe, transcrevendo o produto recebido na variável de classe produto para o objeto dados, salvando-o através do método addRecord ou setRecord.
Para entender o fluxo de leitura, é preciso notar que este método lerProduto chama internamente o método lerRegistro que está na classe pai (ou seja, na classe Persistencia). O método lerRegistro aciona internamente o evento leituraRegistroEvent de nossa classe, criando um novo produto na variável de classe produto e abastecendo-o com o valor da variável id e com os valores existentes no objeto dados
Navegando entre produtos
Para navegarmos pelos produtos salvos no banco de dados, é preciso incluir na classe ProdutoPersistencia um método que inicie a navegação e que indique a ordenação dos registros. Para realizar essa tarefa, criaremos uma nova classe que posteriormente utilizaremos nesse método. 
Seguindo os passos, com o botão auxiliar do mouse, selecionamos o pacote “br.edu.estacio” e no menu popup selecionamos “Novo >”, depois “Classe Java…” (passo 1). Na janela “Novo Classe Java”, nomeamos a classe como “ProdutoComparator” (passo 2) para o pacote “br.edu.estacio” (passo 3) e pressionamos o botão “Finalizar” (passo 4).
Faremos nossa classe implementar os métodos da interface RecordComparator. Siga a ilustração, importe o pacote “javax.microedition.rms. RecordComparator” (passo 1), depois digite “implements RecordComparator” a direita do nome da classe (passo 2), e aguarde uma lâmpadazinha surgir a esquerda. Clique na lâmpada e depois em “Implementar todos os métodos abstratos” (passo 3). O IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário automaticamente:
Quando criarmos o método para iniciar a navegação na classe ProdutoPersistencia, utilizaremos essa classe ProdutoComparator e esse método compare será utilizado internamente pelo enumerador de registros para ordenação. Note que os argumentos desse método são do tipo arranjo de byte e recebem dois registros que necessitam ser comparados para que a ordenação aconteça. Faremos a codificação para comparar esses registros no quesito “nome do produto”, portanto, siga os passos da ilustração:
Seguindo os passos, importamos os pacotes para manipulação dos dados nos arranjos de byte dos registros recebidos (passo 1) e codificamos uma lógica capaz de determinar se o nome de um produto é alfabeticamente maior ou menor quando comparado a outro produto.
Como cada registro recebido será o registro de um produto observe que extrairmos os dados de seus campos na mesma ordem em que eles foram armazenados, ou seja, se compararemos a ordem dos registros pelo “nome do produto”, então será preciso primeiro extrair o campo de “código do produto” para depois extrair o campo “nome do produto”.
Agora que temos a classe ProdutoComparator concluída, incluiremos o método que inicia a navegação e que indica a ordenação dos registros na classe ProdutoPersistencia.
Siga os passos da ilustração, inclua o método iniciarNavagacaoProduto na classe ProdutoPersistencia e faça sua documentação:
Seguindo os passos, abrimos nossa classe ProdutoPersistencia (passo 1) e incluímos o método iniciarNavagacaoProduto em nosso código (passo 2). Portanto, concluímos a codificação que cuida do armazenamento e da recuperação dos dados dos produtos.
 
No próximo passo, integraremos nossa interface visual com essas funcionalidades, todavia antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”
Construindo o fluxo da interface visual
A partir de agora, começaremos a unir a interface visual com a programação que fizemos anteriormente. Primeiro, selecione a classe da MIDlet (passo 1), depois pressione o botão fluxo (passo 2), depois selecione o formulário “form” (passo 3) e altere o “Título” para “Cadastro de Produtos”. Veja os passos na ilustração:
Agora, renomearemos o “form” para “produtosForm”. Siga os passos da ilustração:
Daremos funcionalidades ao nosso formulário, incluiremos um menu para salvar o produto e outro menu para listar os produtos salvos. Siga os passos da ilustração:
Seguindo os passos, selecionamos o grupo “Comandos” e arrastamos o menu tela (Comando Tela) para cima do formulário “produtoForm” por duas vezes (passo 2).
Siga o exemplo da ilustração e renomeie os menus apontados com nomes correspondentes a suas funcionalidades. Os nomes serão “sairCommand”, “salvarCommand” e “listarCommand”:
Ao concluir, os nomes serão “sairCommand”, “salvarCommand” e “listarCommand”. Altere também o rótulo de cada um dos menus para que exibam os nomes “Sair”, “Salvar” e “Listar”:
Adicionaremos uma tela de listagem para exibir todos os produtos cadastrados. Siga os passos da ilustração, inclua o objeto e altere seu título para “Listagem de Produtos”:
Utilizando os conhecimentos que você já possui, renomeie o objeto “list” para “produtoList” e arraste o menu “listarCommand” sobre ele. O resultado deverá ficar conforme a ilustração: Para renomear, clique com o botãoauxiliar do mouse no objeto, daí use “Renomear”
Criaremos dois menus, sendo um para editar um produto na listagem e o outro para voltar à tela anterior. Selecione o grupo “Comandos” (passo 1) e siga o segundo passo da ilustração:
Seguindo a ilustração, acrescentamos o menu voltar e o menu tela. Renomeie esses menus para que eles tenham seus nomes e seus rótulos em conformidade com sua funcionalidade, ou seja, renomeie o menu “backCommand” para “voltarCommand” e o menu “screenCommand” para “editarCommand” e altere seus rótulos para “Voltar” e “Editar” respectivamente.
Para criar um fluxo de retorno, arraste o menu “voltarCommand” sobre o “produtoForm” para definir que voltaremos a essa tela quando esse menu “voltar” for acionado.
 
Seu fluxo deverá ser semelhante ao da ilustração a seguir, observe as setas:
Na próxima ilustração, incluiremos nosso último objeto no fluxo. Baseado em seu conhecimento, selecione o grupo “Exibições” (passo 1), depois arraste o objeto “Alerta” para dentro de nosso fluxo (passo 2), daí o renomeie de “alert” para “produtoAlert” (passo 3) e defina seu título como “Informação”. Por último, para que esse “Alerta” possa nos informar do resultado do salvamento quando o menu “Salvar” for pressionado, arraste o menu “salvarCommand” sobre “produtoAlert” (passo 5).
Para renomear, clique com o botão auxiliar do mouse no objeto, daí use “Renomear”.
Agora que temos todo o fluxo preparado, o próximo passo é o de desenharmos a tela que realiza o cadastro ou a edição do produto, ou seja, prepararemos o objeto “produtoForm”.
 
Antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”.
Desenhando e preparando o formulário
Com a MIDlet aberta (passo 1), prepararemos o objeto “produtoForm”, portanto, pressione o botão “Tela” (passo 2) e selecione “produtoForm” (passo 3). Visualize os passos na ilustração:
 Siga os passos da próxima ilustração para remover o “item de String” que foi criado automaticamente pelo assistente do IDE NetBeans. Agora, siga os passos da próxima ilustração para incluir três “caixas de texto” em nosso formulário de cadastro e edição de produtos:
Seguindo a ilustração, selecionamos o grupo “Itens” (passo 1) e arrastamos o item “caixa de texto” (passo 2) em nosso formulário por três vezes, gerando os campos “textField”, “textField1” e “textField2”.
Baseado em seus conhecimentos, renomeie os campos “textField”, “textField1” e “textField2” para, respectivamente, “codigoTextField”, “nomeTextField” e “quantidadeTextField”. Altere também os rótulos de cada campo para “Código”, “Descrição” e “Quantidade”.
Quanto terminar, seu formulário deverá estar semelhante ao da próxima ilustração:
Na próxima ilustração, alteraremos o campo “Quantidade” de produtos para que comporte somente números com no máximo quatro dígitos. Selecione o campo “Quantidade” e siga as indicações de valores da ilustração:
 Seguindo os passos, selecionamos e configuramos as propriedades do campo “Quantidade”, definindo a propriedade “Restrições de entrada” como “NUMERIC” e a propriedade “Tamanho máximo” como “4”.
 
Se quiser testar a aplicação, você pode executar o programa para visualizar os menus e testar o fluxo que construímos até aqui. Você poderá ver que o campo “Quantidade” aceita somente números e que os menus “Listar”, “Salvar” e “Voltar” possuem os comportamentos que definimos no fluxo.
 
Iremos agora para a última etapa, ou seja, a codificação da interface visual. Antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”.
Alterando a codificação da interface visual
Para darmos continuidade a integração, selecione o menu “salvarCommand”, depois clique nele com o botão auxiliar do mouse e, no menu popup, clique em “Ir para o código-fonte” (passo 1).
Ao realizar essa ação, você será posicionado dentro do método commandAction e poderá realizar a codificação do menu no local apontado pela seta vermelha:
A estrutura de construção dessa codificação poderá variar de acordo com a ordem de suas ações, todavia, você deve observar que dentro do método commandAction, seu cursor estará dentro de um “if” que verifica se displayable é igual a produtoForm e dentro de um outro “if” (aninhado ao primeiro) que verifica se command é igual a salvarCommand.
Antes de codificarmos no ponto indicado pela seta vermelha, precisamos incluir algumas variáveis para utilizarmos o produto e a persistência de produto. Siga os passos da ilustração, codifique e documente:
Ao codificar o passo 2, um aviso de erro será informado no construtor. Você deve seguir adiante, ou seja, deve ignorar o aviso de erro e realizar a codificação do passo 3. Esse aviso de erro acontece devido ao uso da instrução “final”, que exige a inicialização da variável dentro do construtor (passo 3).
Para que possamos salvar produtos de modo persistente, procure pelo método commandAction no navegador e faça a codificação no menu “Salvar”, ou seja, dentro do “if” que verifica se command é igual a salvarCommand. Faça a codificação da ilustração:
Conforme você pode acompanhar pela ilustração, na linha 1, tentamos abrir o banco de dados. Havendo um retorno positivo (true), na linha 2, 3 e 4 pegamos os textos digitados das caixas de texto e, na linha 5, verificamos se há algum texto nelas. Se não houver texto, no objeto de alerta será colocado um texto pedindo para que o usuário preencha os campos antes de salvar, do contrário, na linha 6, verificamos se a variável produto possui um valor nulo e, se um valor nulo for encontrado na variável produto, então colocamos um novo objeto nela. Da linha 9 a linha 15, abastecemos a variável produto com os valores que foram digitados nas caixas de texto - note que o código e o nome do produto são interpretados como texto, todavia a quantidade de produto é interpretada como número inteiro.
 Na linha 16, salvamos o produto em banco de dados através da variável de objeto produtoPersistencia. Na linha 17, definimos a variável produto como nula para permitir a entrada de outro novo produto. Na linha 18, fechamos o banco de dados. Nas linhas 19, 20 e 21 limpamos (esvaziamos) as caixas de texto e, na linha 22 colocamos no objeto de alerta um texto indicando sucesso ou erro, de acordo com o resultado da variável salvo.
Pronto, neste passo já temos a parte que salva os registros, faremos a parte que lista os registros existentes. Antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”.
Precisamos incluir mais uma variável de classe para armazenar o que será carregado na listagem de produtos. Para acumular objetos de produto, utilizaremos uma variável de objeto do tipo vetor, siga os passos da ilustração:
Ao codificar o passo 2, um aviso de erro será informado no construtor. Você deve seguir adiante, ou seja, deve ignorar o aviso de erro e realizar a codificação do passo 3. Esse aviso de erro acontece devido ao uso da instrução “final”, que exige a inicialização da variável dentro do construtor (passo 3).
Novamente, devemos ir ao ponto inicial para criar uma lógica capaz de listar os produtos salvos no banco de dados. Procure pelo método commandAction no navegador do IDE NetBeans e faça a codificação dentro do “if” que verifica se command é igual a listarCommand. Faça a codificação conforme está indicado na ilustração:
Conforme você pode acompanhar pela ilustração, na linha 1, tentamos abrir o banco de dados. Na linha 2, havendo um retorno positivo (true) do método, acionamos o objeto produtoPersistencia para iniciar a navegação entre produtos. Nas linhas 3 e 4, limpamos (esvaziamos) todo o conteúdo do vetor e da listagem de produtos. Nas linhas 5, 6, 7 e 8 navegamos e adicionamos registros no vetor e na listagem de produtos - usamos os métodos “irParaProximoNavegavel” e “getProduto” para executar essas ações. Na linha 9, fechamos o banco de dados
Pronto, já temos a parte que lista os registros, faremos a parte que edita os registros existentes. Antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”.
Programaremos dentro do menu “Editar” da listade produtos. Procure pelo método commandAction no navegador do IDE NetBeans e faça a codificação dentro do “if” que verifica se command é igual a editarCommand. Faça a codificação conforme está indicado na ilustração:
Conforme você pode acompanhar pela ilustração, na linha 1, verificamos se há algum item selecionado na lista de produtos e, se houver, na linha 2, recuperamos da variável de vetor o produto selecionado em conformidade com o índice do item selecionado na lista de produtos. Da linha 3 a 7 criamos um novo objeto de produto e o abastecemos com os dados do produto selecionado. Nas linhas 8, 9 e 10 preenchemos as caixas de texto com os dados do produto, ou seja, com seu código, descrição e quantidade. Na linha 11, voltamos a exibir o formulário de cadastro de produtos.
Para esta atividade, como nosso último passo, usando seus conhecimentos, renomeie a MIDlet HelloMIDlet para ColetorMIDlet e o pacote hello para coletor.
Pronto, concluímos nossa missão e você já pode testar sua aplicação. Salve o projeto, pressione o botão “Salvar Todos”.
 
Para praticar, faça algumas melhorias, por exemplo, inclua a opção de exclusão de produtos, pesquisa e adicione um menu para limpar os campos.
Através dos conhecimentos obtidos nessa aula e na aula passada, armazene a pontuação do jogo da velha de forma persistente utilizando a API RMS e monte um ranking com as 10 (dez) melhores pontuações:
A solução é constituída pela utilização da classe RecordStore e da interface 
RecordEnumeration, podendo conter os seguintes métodos:
 
- openRecordStore da classe RecordStore;
- enumerateRecords da classe RecordStore;
- hasNextElement da interface RecordEnumeration;
- nextRecordId da interface RecordEnumeration;
- getRecord da classe RecordStore;
- closeRecordStore da classe RecordStore;
Aula 10
Comunicação Remota
O framework genérico de conexão
Apesar das bibliotecas da plataforma Java Standard Edition para conectividade a rede possuírem recursos eficientes, devido as características limitadas de hardware, um dispositivo móvel poderia não suportar a quantidade de classes e interfaces presentes nos pacotes java.net e java.io e, por este motivo, esses pacotes foram simplificados e um framework genérico de conexão, também conhecido por GCF (Information Module Profile), foi desenvolvido para tratar assuntos de i/o (Connected Device Configuration) e conectividade.
O GCF não tinha por objeto ser um novo conjunto de classes, mas sim proporcionar um subconjunto do JSE (Java Standard Edition) que estivesse em sintonia com as limitações e as variações que possam ser encontradas em dispositivos de aplicação MIDP, todavia, atualmente, você encontra o GCF não somente em dispositivos baseados em CLDC, como os que utilizam MIDP(Mobile Information Device Profile) e IMP (Information Module Profile), mas também em dispositivos que usam CDC (Connected Device Configuration). Indo além, devido à padronização do uso, você também pode encontrar o GCF em um número crescente de pacotes opcionais, incluindo aqueles que proveem acesso a arquivos, suporte a Bluetooth e smart cards.
Estrutura do Framework Genérico de Conexão (GCF)
O GCF possui uma estrutura simplificada de interfaces e classes para executar fluxos de entrada e saída de dados, seja para arquivos ou conexões (como HTTP, datagramas e soquetes).
Como o próprio nome indica, o GCF provê uma abordagem genérica para conectividade e é genérico porque provê um conjunto de APIs comuns para todos os tipos básicos de conectividade, seja para pacotes e para fluxos de entrada e saída (contínuos ou não).
A generalização é possível através da utilização de:
Uma interface hierárquica que pode ser estendida;
Uma fábrica de conexão;
Pela padronização da URL para indicar o tipo apropriado de conexão a ser criado.
Embora cada tipo de conexão tenha suas particularidades, para usar o GCF é muito simples, basta utilizar a classe Connector e uma URL para criar uma conexão. A classe Connector cria e abre o tipo de conexão apropriado de acordo com a URL que você especificar, desde que a URL seja suportada.
Por exemplo, para criar uma conexão, basta chamar o método Connection.open.
Abrindo uma conexão
O GCF suporta um grande número de tipos de conexões e as URLs são importantes para definir as regras da conexão, descrevendo a localização e o meio de acesso ao recurso desejado. O formato geral de uma URL, como definido na RFC 1738 (e depois na RFC 2396), é o seguinte:
scheme://user:password@host:port/url-path;parameters, onde:
scheme é obrigatório, especifica o método ou o protocolo e define o tipo de conexão a ser usada;
user é opcional e especifica uma conta (nome de usuário);
password é opcional e especifica uma senha para uma conta;
host é o local, nome ou o endereço IP a quem se destina a conexão;
port é opcional e depende do esquema. Especifica a porta a ser utilizada na conexão;
url-path é o caminho até o recurso, depende do esquema e pode possuir parâmetros
Note que os delimitadores são requeridos em conformidade com cada parte do formato da URL e que os parâmetros opcionais devem contê-los quando estiverem presentes. Segue um exemplo de URL com parte dos parâmetros opcionais e respectivos delimitadores:
ftp://aluno:senha@portal.estacio.br/arquivos
Na API do GCF, a classe Connector define três modos para abrir a conexão, são eles:
open(String url)
open(String url, int mode)
open(String url, int mode, boolean timeouts)
A variável url descreve a URL para onde a conexão será criada. A variável mode descreve a forma como a conexão acontece, ou seja, READ, WRITE ou READ_WRITE (modo padrão). A variável timeouts indica que você quer ser avisado acerca de timouts (InterruptedIOException), desde que a conexão permita tal notificação (o aviso, por padrão, é desativado, ou seja, falso).
A forma mais comumente utilizada deste método é a primeira, ou seja, open(String url):
// Cria um SocketConnection e um InputStream
String url = "socket://portal.estacio.br:80";
SocketConnection c = (SocketConnection)Connector.open(url);
InputStream s = c.openInputStream();
A classe Connector também possui alguns métodos de conveniência para criação de vários tipos de fluxo de entrada e saída:
- static DataInputStream  openDataInputStream(String name)
- static DataOutputStream openDataOutputStream(String name)
- static InputStream      openInputStream(String name)
- static OutputStream     openOutputStream(String name)
 
Como esses métodos são estáticos, você consegue utilizar os objetos de fluxo de entrada e saída diretamente. Veja um exemplo de uso de um dos métodos, ou seja, do openInputStream:
// Create an InputStream
String url = "socket://portal.estacio.br:80";
InputStream s = (InputConnection)Connector.openInputStream(url);
Todavia, apesar de simplificar o caminho, a utilização desses métodos podem não ser satisfatórias na maioria dos casos e, por isso, sua utilização é, por muitas vezes, desencorajada, pois não se obtém um objeto que faz referência à conexão e, por conta disso, você fica sem acesso aos métodos e atributos desse objeto. Por exemplo, se você fosse conectar um site usando openInputStream não teria acesso a qualquer um dos métodos que manipulam o cabeçalho HTTP e seus códigos de retorno.
Vejamos exemplos para criar algumas conexões através do uso da classe Connector:
Criando uma conexão via soquete (SocketConnection):
String url = “socket://portal.estacio.br:80”;
SocketConnection c = (SocketConnection) Connector.open(url);
Criando uma conexão via HTTP (HttpConnection):
String url = http://portal.estacio.br/portal;
HttpConnection c = (HttpConnection)Connector.open(url);
Criando uma conexão a um arquivo de recurso (Foundation Profile e J2SE):
String url = file://myResourceFile.res;
Como você pode observar, o tipo de esquema (scheme) de uma URL altera completamente a forma de escrever a conexão. A JCP (jcp.org - Java Community Process), que é a entidade responsável pelo mecanismo de padronização do desenvolvimento de especificações técnicas para a tecnologia Java, define os seguintes

Continue navegando