Instituto Superior de Engenharia do Porto Departamento de Engenharia Informática Tecnologia Java Aplicada a Telemóveis Trabalho realizado no âmbito da disciplina de Projecto, do 5º ano da licenciatura de engenharia informática. Aluno: José Filipe Soeiro Teixeira Orientador: Eng.º Luís Pinho Porto, 2003 Tecnologia Java aplicada a telemóveis II Tecnologia Java Aplicada a Telemóveis Realizado por: José Filipe Soeiro Teixeira Orientador ISEP: Eng.º Luís Pinho Data de realização: Agosto, 2003 III Tecnologia Java aplicada a telemóveis IV Índice ÍNDICE ................................................................................................................V AGRADECIMENTOS........................................................................................VII 1. INTRODUÇÃO................................................................................................ 1 2. TELEMÓVEIS E TECNOLOGIA..................................................................... 3 2.1.AUDIO ......................................................................................................... 3 2.1.1. Sons polifónicos................................................................................. 3 2.1.2. Leitores de MP3................................................................................. 4 2.2. VÍDEO ........................................................................................................ 4 2.2.1. Captura de Imagens .......................................................................... 4 2.2.2. Display ............................................................................................... 5 2.3. MEMÓRIA.................................................................................................... 6 2.4. SOFTWARE ................................................................................................. 6 2.4.1. Exemplos ........................................................................................... 8 2.4.2. Suporte ............................................................................................ 10 3. JAVA............................................................................................................. 11 3.1 – CONCEITOS BÁSICOS ............................................................................... 12 3.1.1 – A linguagem de programação ........................................................ 12 3.1.2 – A plataforma................................................................................... 15 3.2 – J2SE / J2EE / JAVA CARD ....................................................................... 16 3.3 – J2ME..................................................................................................... 18 3.3.1 – Arquitectura do J2ME .................................................................... 18 3.3.1.1. Configuração .........................................................................................19 3.3.1.2. Perfil ......................................................................................................21 3.3.2 – Connected Limited Device Configuration....................................... 23 3.3.2.1. CLDC Java Virtual Machine ..................................................................23 3.3.2.2. Virtual Machine e especificações de linguagem ...................................24 3.3.2.3. Carregamento de classes .....................................................................26 3.3.2.4. Considerações de segurança ...............................................................26 3.3.2.5. Compilar e correr código com KVM ......................................................29 3.3.3 – O Mobile Information Device Profile e MIDlets .............................. 36 3.3.3.1. MIDP .....................................................................................................36 3.3.3.2. Requisitos de hardware do MIDP .........................................................37 3.3.3.3. Requisitos de software do MIDP...........................................................38 3.3.3.4. A plataforma MIDP ................................................................................39 3.3.3.5. MIDlets e MIDlet suites .........................................................................40 3.3.3.6. Segurança nas MIDlets.........................................................................41 3.3.3.7. MIDlet packaging ..................................................................................42 3.3.3.8. Ciclo de vida e ambiente de execução das MIDlets .............................44 4. ALTERNATIVAS AO J2ME.......................................................................... 51 4.1. EXECUTION ENGINE (EXEN)....................................................................... 52 4.2. MOPHUN .................................................................................................. 53 4.3. WIRELESS GRAPHICS ENGINE (WGE) ........................................................ 54 4.4. BINARY RUNTIME ENVIRONMENT FOR WIRELESS (BREW) ........................... 55 4.5. SYMBIAN OS ............................................................................................ 56 V Tecnologia Java aplicada a telemóveis 5. QUESTÕES FUNDAMENTAIS AO DESENVOLVIMENTO PARA TELEMÓVEIS ................................................................................................... 59 5.1. MEMÓRIA.................................................................................................. 59 5.2. PROCESSADOR ......................................................................................... 59 5.3. DISPLAY ................................................................................................... 60 5.4. SOM ......................................................................................................... 61 5.5. INPUT ....................................................................................................... 61 5.6. SEGURANÇA ............................................................................................. 61 5.7. FUNCIONALIDADE ...................................................................................... 62 5.8 – INSTALAÇÃO ............................................................................................ 62 6. FERRAMENTAS PARA O DESENVOLVIMENTO DE APLICAÇÕES ........ 63 6.1. J2SE SDK ............................................................................................... 63 6.2. J2ME WIRELESS TOOLKIT ......................................................................... 64 6.2.1. Default Device Selection.................................................................. 65 6.2.2. Documentation................................................................................. 65 6.2.3. KToolbar .......................................................................................... 66 6.2.4. OTA Provisioning ............................................................................. 84 6.2.5. Preferences ................................................................................ 84 6.2.6. Run MIDP Application... .............................................................. 84 6.2.7. Utilities ......................................................................................... 86 6.3. EDITOR JAVA ............................................................................................ 86 7. DESENVOLVIMENTO .................................................................................. 87 7.1. HELLO WORLD .......................................................................................... 89 7.2. PRINCÍPIOS BÁSICOS ................................................................................. 91 7.3. DESENVOLVIMENTO DE UMA MIDLET .......................................................... 94 8. CONCLUSÃO ............................................................................................. 117 9. BIBLIOGRAFIA .......................................................................................... 119 10. ANEXO ..................................................................................................... 123 11. ÍNDICE DE FIGURAS............................................................................... 129 12. ÍNDICE DE TABELAS .............................................................................. 131 VI Agradecimentos Existem algumas pessoas sem as quais não teria sido possível a realização deste projecto e, por isso, merecem um especial agradecimento. Quero agradecer em primeiro lugar à minha Mãe e à minha Avó (adorovos) que, apesar de infelizmente, já não estarem entre nós, sempre me apoiaram no decurso deste projecto e, de certeza, ainda estão comigo. Quero também agradecer ao meu Pai (também te adoro) que me apoiou em tudo, especialmente nos momentos mais difíceis. Um agradecimento especial à Ana, que está sempre comigo e me aturou durante este tempo todo (um enorme beijinho para ti!). Um abraço para os meus amigos, com quem posso contar para tudo! Obrigado Samuel (pelas ideias), Rui “Les” Matos, Wilson “Bizu” Carvalho, Nuno “Presi” Soares, Ana “Timon” Azevedo, Aníbal “Flintstone” Couto, Luís “Viagra” Leal, Leandro “Julieta” Castro, Daniel “Spielberg” Martinho, Victor, Romeu, Mário, Nuno e o resto do pessoal do ISEP que me apoiou e, mesmo não notando, ajudou à realização deste projecto. Quero agradecer também ao meu orientador Luís Pinho que foi uma ajuda fundamental em todas as formalidades necessárias ao sucesso deste projecto. Para finalizar, como de certeza que me esqueci de alguém, quero agradecer a essa pessoa e pedir desculpa pelo esquecimento. Obrigado! Este projecto é dedicado à minha Mãe e à minha Avó. VII Tecnologia Java aplicada a telemóveis VIII 1. Introdução Nestes últimos anos, tem-se vindo a observar uma enorme evolução no campo das novas tecnologias, nomeadamente na área das telecomunicações. O aparecimento do telemóvel foi revolucionário, e alterou radicalmente o modo de estar e de pensar de milhares de pessoas que possuem e até dependem deste pequeno aparelho. Desde a viragem do milénio, o telemóvel tem evoluído a uma velocidade estonteante e é agora muito mais do que um simples meio de comunicação. Os grandes telefones portáteis com um pequeno visor monocromático onde apenas se escreviam números, transformaram-se em pequenos aparelhos dotados de uma grande capacidade de memória, destinados às mais diversas operações, desde captura de imagens ou filmes, até leitores de MP3 e, mais recentemente, consola de jogos. O telemóvel é agora uma ferramenta de trabalho e lazer com grandes potencialidades, para a qual se consegue antever um futuro muito promissor. Porém, uma grande evolução tecnológica tem que ser acompanhada por uma evolução a nível de software de modo a que seja possível tirar partido de todas as capacidades desta nova ferramenta de trabalho. O recente aparecimento de telemóveis que suportam linguagens de programação de alto nível, nomeadamente Java, vem fundamentar esta teoria. Este suporte vem alargar consideravelmente as potencialidades deste aparelho. Novos programas ou jogos podem ser desenvolvidos e facilmente inseridos no telemóvel. Em comparação com outros aparelhos portáteis como PDAs ou consolas de jogos, o telemóvel tem inúmeras vantagens. As pessoas habituaram-se a levar o telemóvel para todo o lado, ao contrário do que acontece com outros dispositivos e, por isso, é muito mais confortável ter todas as funcionalidades necessárias aí incluídas. Num futuro próximo, qualquer pessoa poderá consultar a sua agenda, navegar na internet ou jogar um jogo, enquanto toma café ou espera numa fila, apenas utilizando o seu telemóvel que anda sempre consigo. O objectivo deste documento é dar a conhecer o estado actual das tecnologias móveis de comunicação, as suas verdadeiras potencialidades e o modo de as explorar. Só através do conhecimento das tecnologias e desenvolvimento de software é possível tirar partido das funcionalidades que os telemóveis têm actualmente para oferecer. Ao longo deste documento, no capítulo 2 irão ser ilustradas as características principais dos telemóveis mais actuais, como capacidade de memória, número de cores ou resolução suportada. No capítulo 3 será abordada a linguagem Java como linguagem principal para o desenvolvimento de aplicações destinadas a este tipo de plataformas móveis. Neste capítulo, será feita uma distinção entre a linguagem Java normal (J2SE), que é utilizada em inúmeras aplicações para computador, e a sua versão “micro” que se destina a plataformas móveis, como é o caso dos telemóveis. 1 Tecnologia Java aplicada a telemóveis No capítulo 4, será feita uma breve referência a outras linguagens existentes que, em alternativa ao J2ME, também podem ser utilizadas para desenvolver aplicações destinadas a telemóveis. O 5º capítulo faz uma abordagem a algumas questões fundamentais que o programador deve ter em conta quando programa para esta plataforma. Mais adiante, no capítulo 6, será feita uma análise ás ferramentas necessárias para o desenvolvimento de aplicações em J2ME para telemóveis. É importante conhecer as aplicações utilizadas, de modo a optimizar e toda a fase de desenho e programação de aplicações. Por fim, no capítulo 7, será descrito passo a passo todo o processo de desenvolvimento de uma pequena aplicação J2ME (jogo), desde a sua criação utilizando as ferramentas adequadas, até à sua instalação, passando por diversos exemplos de codificação das características mais importantes de uma aplicação deste tipo. Todo o código referente à aplicação desenvolvida no capítulo 7, será disponibilizado em anexo. 2 2. Telemóveis e tecnologia Actualmente quando alguém quer comprar um telemóvel tem uma enorme variedade de marcas e modelos à escolha, cada um com características diferentes desde o seu formato, até à sua memória ou número de cores do ecrã. A gama de telemóveis varia desde o mais barato que serve apenas para telefonar e escrever mensagens (Nokia 3310, ...) até ao mais caro, topo de gama com câmara de vídeo incorporada, ecrã a cores, Bluetooth e suporte para linguagens de programação de alto nível, como J2ME (Nokia 3650, ...). Os telemóveis mais actuais disponibilizam um enorme leque de capacidades para uso do consumidor. Agora, para além de comunicar, é possível gravar vídeo e tirar fotografias com o telemóvel, navegar na internet, ouvir música ou mesmo jogar. Estas são algumas das tecnologias mais recentes que se podem encontrar nos telemóveis: 2.1.Audio A componente audio dos telemóveis foi a primeira a ser explorada. Desde já há algum tempo que os telemóveis têm variados tipos de toques para todos os gostos. No entanto, a evolução a este nível continua e, nos últimos anos, apareceram os toques polifónicos e os leitores de MP3. 2.1.1. Sons polifónicos Esta tecnologia permite aos telemóveis um nível sonoro bastante melhorado. Isto é possível através do uso de 16, 32 ou mais canais em vez de apenas 1, como acontece nos telemóveis mais antigos. Deste modo, é possível ouvir o som de diversos “instrumentos” diferentes ao mesmo tempo, elevando assim a sua qualidade. É importante ter em conta este facto quando se programa para um telemóvel. No caso da criação de um jogo (que é actualmente o mais habitual...), é possível separar a musica de fundo dos efeitos sonoros. Aqui está uma lista de telemóveis que suportam toques polifónicos: Marca Motorola Nokia Panasonic Samsung Sony Ericsson Modelos C330, C350, T720I, ... 3510, 3650, 5100, 7650, ... GD700, GD87, GU87, ... SGH-X400(40), SGH-V200(40), ... P800, T310(32), T610(32), ... Tabela 2. 1 - Toques Polifónicos Tecnologia Java aplicada a telemóveis 2.1.2. Leitores de MP3 Por outro lado, temos os telemóveis que funcionam como leitor de MP3. Nestes aparelhos, é possível armazenar uma quantidade variável de musicas no formato MP3, dependendo da qualidade de gravação e da memória do aparelho. 2.2. Vídeo Esta componente só há relativamente pouco tempo é que começou a sofrer alterações. Inicialmente, um telemóvel servia apenas para telefonar e continha um visor monocromático, o que era suficiente para as suas funcionalidades. Actualmente já não é bem assim... Quando se fala da componente vídeo num telemóvel, fala-se de captura de vídeo ou imagens, e da resolução, tamanho e número de cores suportadas pelo ecrã. Estas são características cada vez mais importantes a ter em consideração, quando se pensa em adquirir um telemóvel. 2.2.1. Captura de Imagens No que diz respeito à captura de imagens, não se pode considerar um factor de muita importância para a programação, pois a maioria dos programas não necessita de câmara digital. De qualquer forma, a lista que se segue indica alguns dos telemóveis mais recentes que suportam esta tecnologia. Marca Nokia Modelo 7650 Nokia Nokia Nokia Panasonic Samsung Siemens Sony Ericsson 3650 6600 6650 GU87 SGH-V200 SL55 T310, T300 T610 P800 Sony Ericsson Sony Ericsson Tipo de câmara Resolução Captura de vídeo Incorporada 640x480 Sim (por software) Incorporada 640x480 Sim Incorporada 640x480 Sim Incorporada 640x480 Sim Incorporada 132x176 Não Incorporada 640x480 Não Incorporada 640x480 Não Como 640x480 Não acessório Incorporada 288x352 Não Incorporada 640x480 Não Tabela 2. 2 - Captura de imagens/vídeo Note-se porém, que a programação destinada a este tipo de plataformas moveis está ainda a dar os primeiros passos e tudo indica que futuramente se faça uso das capacidades de captura de vídeo para o desenvolvimento de programas, por exemplo, de videoconferência ou até mesmo de entretenimento. 4 Telemóveis e tecnologia A grande popularidade das câmaras digitais nos telemóveis, irá certamente despertar o interesse de muitos programadores que tentarão tirar o melhor partido desta tecnologia. 2.2.2. Display Este é um dos factores mais importantes a ter em conta quando se programa para um telemóvel. É necessário ter em atenção a resolução, o tamanho do ecrã e mesmo a quantidade de cores suportada varia, o que quer dizer que um determinado programa pode funcionar apenas num determinado modelo de telemóveis, ou pode ser mais genérico e adaptar-se a um leque mais variado de modelos. Actualmente a grande maioria dos programas desenvolvidos para telemóveis são jogos, e como tal, possuem uma elevada componente visual. O grafismo deste tipo de aplicações é muito importante e, se por um lado um jogo fica melhor quando desenvolvido para uma mais alta resolução e um elevado número de cores, por outro lado, isto pode limitar a sua compatibilidade e restringi-lo a um ou dois modelos disponíveis no mercado. Segue-se uma lista das características do display de alguns dos telemóveis mais recentes. Marca Nokia Nokia Nokia Nokia Nokia Nokia Panasonic Panasonic Samsung Samsung Samsung Samsung Samsung Samsung Siemens Sony Ericsson Sony Ericsson Sony Ericsson Modelo N-Gage 7650 6600 3650 6800 5100 GU87 X70 SGH-X400 SGH-V200 SGH-C100 SGH-S200 SPH-N270 SPH-A500 SL55 T310 T610 P800 Resolução 176x208 px 176x208 px 176x208 px 176x208 px 128x128 px 128x128 px 132x176 px 132x176 px 128x160 px 128x160 px 128x128 px 128x144 px 128x160 px 128x160 px 101x80 px 101x80 px 128x160 px 208x320 px Cores 4,096 4,096 65,536 4,096 4,096 4,096 65,536 65,536 65,536 65,536 65,536 65,536 65,536 4,096 4,096 256 65,536 4,096 Tabela 2. 3 - Características do display Desta extensa lista, presta-se especial atenção ao Nokia N-Gage que se apresenta não só como um telemóvel mas, principalmente, como uma consola de jogos, tendo já feito referência a alguns jogos de nome já conhecido (“Tomb Raider”, “Sonic”, ...) desenvolvidos pela Sega especialmente para o N-Gage. 5 Tecnologia Java aplicada a telemóveis 2.3. Memória Outra característica muito importante a ter em conta é a memória disponível no telemóvel, para os programas desenvolvidos. Actualmente, estes aparelhos possuem uma memória muito escassa o que dificulta a programação e limita a qualidade dos programas. Por isso, é necessário ter em consideração a capacidade de memória do telemóvel para o qual se pretende desenvolver uma aplicação. Existem três tipos de memória a ter em atenção: a memória de armazenamento, a memória de execução e o tamanho máximo dos ficheiros JAR. • Memória de armazenamento - A memória de armazenamento limita o tamanho máximo disponível para o programa. Esta é a memória onde o programa desenvolvido fica alojado. Alguns telemóveis suportam o uso de cartões de memória externos para aumentar a sua capacidade. • Memória de execução – Esta é a memória utilizada em tempo de execução por uma aplicação, ou seja, é a capacidade máxima de memória que uma aplicação pode utilizar durante a sua execução. • Ficheiros JAR – Esta memória define o tamanho máximo suportado para os ficheiros JAR. Note-se que um ficheiro JAR é um ficheiro comprimido que contém código e é muitas vezes utilizado como forma de reduzir o tamanho de uma aplicação, o que é muito útil no caso da programação para este tipo de suporte. As capacidades de memória de alguns dos telemóveis mais propícios ao desenvolvimento de programas, encontram-se na seguinte tabela: Marca Nokia Nokia Nokia Nokia Nokia Nokia Modelo N-Gage 7650 6600 3650 6800 5100 Armazenamento 4MB+MMC (memory cards) 4MB 6MB+MMC 3.4MB+MMC 5.2MB 725KB Execução 2.8MB 1.4MB 3MB 1.4MB 200KB 200KB Ficheiros JAR 4MB 4MB (não disponível) 4MB 64KB 64KB Tabela 2. 4 - Capacidades de memória Embora seja fundamental que um programador saiba as características de memória do telemóvel para o qual se destina uma aplicação a ser desenvolvida, está é ainda uma informação de difícil acesso. Deste modo, só foi possível obter as características de memória, relativas aos telemóveis Nokia, disponibilizadas no site da marca. 2.4. Software O software criado para telemóveis encontra-se actualmente numa fase ainda inicial de desenvolvimento. No entanto, tem-se notado uma rápida evolução neste campo. Todos os dias surgem novos programas destinados a estas plataformas e cada vez mais programadores interessados por esta tecnologia. 6 Telemóveis e tecnologia Existem actualmente diversas plataformas de programação suportadas pelos telemóveis mais recentes, sendo o Java a mais popular e, quando se fala em Java para telemóveis, fala-se em jogos e programas ligados à área de entretenimento. A verdade é que a grande maioria do software que se pode inserir num telemóvel são jogos, desenvolvidos quer por grandes empresas, quer por programadores independentes. Já na industria da informática, os jogos ocupam um lugar de destaque e representam uma parcela considerável das vendas e dos lucros, no que diz respeito a software. Daqui se pode concluir que as novas tecnologias não são só uma ferramenta de trabalho, mas também um instrumento de lazer para que se possa fugir do stresse do dia-a-dia. É por isso natural que nos telemóveis, a área do entretenimento prospere ainda mais. Se pelo ponto de vista do utilizador os jogos são mais apelativos e um óptimo meio para descontrair, para a grande parte dos programadores, desenvolver um jogo é mais motivante e vende-se melhor. Também à semelhança do que acontece com os computadores pessoais, são os jogos que vão tirar o máximo partido de todas as capacidades do aparelho. São estes programas que vão combinar uma elevada resolução de imagem com uma boa qualidade sonora, o que dá a conhecer ao utilizador todas as capacidades do seu telemóvel, e permite ao programador, usar as mais recentes tecnologias no desenvolvimento de aplicações. Além disso, a utilidade de outro tipo de ferramentas num telemóvel, como uma folha de cálculo, uma base de dados ou um processador de texto, é bastante questionável. O aparecimento de alguns modelos de telemóveis como o SGHX400 da Samsung e o N-Gage da Nokia vêm reforçar a ideia de que os jogos têm uma crescente importância neste meio. O N-Gage, mais do que um telemóvel é já considerado uma consola capaz até de rivalizar num Figura 2. 1 - Nokia N-Gage futuro próximo com o já conhecido “Game Boy”. Para este caso, a Nokia assumiu uma parceria com a Sega que produzirá jogos de grande qualidade (“Sonic”, “Tomb Raider”, ...) para esta consola/telemóvel. Em seguida, serão mostrados alguns exemplos de software que se pode obter para as diversas plataformas suportadas pelos telemóveis mais recentes. 7 Tecnologia Java aplicada a telemóveis 2.4.1. Exemplos Figura 2. 2 - Imagens de Dragon Island Figura 2. 3 - Imagens de XFinity 8 Título: Dragon Island Desenvolvido por: Macrospace Tipo: Jogo Plataforma: J2ME Memória: 65K Preço: 3,00 Telemóveis: Nokia 7650, 3650, 6800, 5100, ...; Siemens SL55; ... Comentário: Este é um dos mais recentes jogos desenvolvidos para a plataforma J2ME. Como pode ser visto nas imagens, foi feito um bom aproveitamento das 4,096 cores utilizadas, o que também torna este jogo compatível com um maior número de telemóveis. Aqui está um bom exemplo do que se consegue desenvolver para um telemóvel. Título: XFinity Desenvolvido por: Synergenix Tipo: Jogo Plataforma: Mophun Memória: 118K Preço: 5,00 Telemóveis: Sony Ericsson T300, T310, ... Comentário: Este é um exemplo de uma aplicação desenvolvida sobre a plataforma Mophun. A qualidade mantêm-se bastante boa e, existe bastante suporte para Mophun, quer em termos de software disponível, quer em termos de telemóveis . Note-se que este é um jogo mais caro, e ocupa bastante mais memória. Telemóveis e tecnologia Título: Hurricane Space Fighters Desenvolvido por: TTPCom Tipo: Jogo Plataforma: WGE Memória: Não disponível Preço: Não Disponível Telemóveis: Innostream I1000, ... Figura 2. 4 - Imagens de Hurricane Space Fighters Comentário: Aqui temos uma plataforma que demonstra possuir grandes potencialidades mas, encontrar uma aplicação desenvolvida para “Wireless Graphics Engine”, revela-se uma tarefa quase impossível. Além da falta de software, existem ainda poucos telemóveis a suportar WGE. Título: Crash Bandicoot Desenvolvido por: In-Fusio Tipo: Jogo Plataforma: ExEn Memória: Não disponível Preço: Não Disponível Telemóveis: Panasonic GD67, GD87, ... Comentário: O “Execution Engine” (ExEn) revela-se uma plataforma capaz de produzir bons resultados. Apesar disso, existe alguma dificuldade de encontrar Figura 2. 5 - Imagens de Crash Bandicoot software desenvolvido para ExEn. Também se nota alguma escassez de telemóveis a suportar esta plataforma. Título: Fantom Overdrive Desenvolvido por: Overloaded Tipo: Jogo Plataforma: Symbian OS Memória: 581K Preço: 5,95 Telemóveis: Nokia 3650, 7650, Sony Ericsson P800, ... Comentário: Embora não tenha a popularidade do Java, a plataforma Symbian possui já bastante software disponível, com uma boa qualidade. Além disso, existe já uma vasta gama de telemóveis com este suporte. Figura 2. 6 - Imagens de Fantom Overdrive 9 Tecnologia Java aplicada a telemóveis 2.4.2. Suporte Um dos principais aspectos a ter em conta quando se pretende desenvolver uma aplicação para uma determinada plataforma, é o suporte disponibilizado. Antes de se começar a desenvolver, é necessário saber que telemóveis suportam as diversas plataformas existentes, de forma a fazer a opção mais adequada. Aqui está uma pequena lista de telemóveis que suportam as diversas tecnologias. Marca Fujitsu Innostream Motorola Motorola Nokia Nokia Nokia Nokia Nokia Nokia Panasonic Panasonic Sagem Sagem Samsung Samsung Samsung Samsung Siemens Siemens Sony Ericsson Sony Ericsson Sony Ericsson Modelo F2051 I-1000 V600 T725 N-Gage 7650 6600 3650 6800 5100 GU87 X70 my G-5 my X-5 SGH-X400 SGH-V200 SGH-C100 SGH-S200 SL55 U10 T310 Plataformas J2ME, Symbian WGE J2ME J2ME J2ME, Symbian J2ME, Symbian J2ME, Symbian J2ME, Symbian J2ME J2ME ExEn J2ME, ExEn ExEn ExEn J2ME J2ME J2ME J2ME J2ME J2ME Mophun T610 J2ME, Mophun P800 J2ME, Symbian Tabela 2. 5 – Tecnologias suportadas Como se pode observar, o Java ocupa actualmente a maior parcela de mercado, comparativamente com outras plataformas de programação. 10 3. Java Actualmente os telemóveis de ultima geração, associam-se à tecnologia Java, mesmo que não se saiba exactamente o que isso é. A grande quantidade de publicidade feita a esta plataforma tem resultado e, para comprovar, pode-se observar a crescente importância do Java na área das comunicações móveis, e a quantidade de software e suporte existente para esta tecnologia. As campanhas publicitárias feitas aos telemóveis já nos habituaram à palavra Java, falando insistentemente de jogos Java e tecnologia Java, de tal maneira que quando se vai comprar um telemóvel, é normal perguntar ao vendedor: “Este modelo suporta Java?” Muitas das vezes a resposta é afirmativa e o cliente vai para casa satisfeito por ter adquirido um telemóvel que até ficou um pouco mais caro mas suporta Java. No entanto, a verdadeira pergunta é: Mas afinal o que é o Java? E qual é a vantagem de ter Java no telemóvel? Este documento é destinado pessoas que já possuem algum conhecimento na área da programação e, certamente já estão familiarizados com o conceito Java como linguagem de programação mas, de qualquer maneira existem algumas diferenças quando se programa nesta linguagem para plataformas móveis. Neste capítulo, irá ser feita uma breve referência à linguagem Java e à sua utilização em telemóveis. Quem tenciona desenvolver uma aplicação destinada às mais recentes tecnologias móveis usando esta plataforma deve, em primeiro lugar, saber as características e o modo de funcionamento desta linguagem de programação, em particular da sua versão “Micro” que se destina exactamente a máquinas com baixa capacidade de memória e processamento (telemóveis). Tecnologia Java aplicada a telemóveis 3.1 – Conceitos básicos O Java é um ambiente de programação que combina uma plataforma específica com uma linguagem de alto nível, muito prática e funcional. 3.1.1 – A linguagem de programação O Java é uma linguagem de programação de alto nível, orientada ao objecto e de fácil compreensão. Esta linguagem possui determinadas características que a tornam muito apetecível para programadores que trabalham sobre qualquer plataforma. Podemos então definir o Java como uma linguagem de programação que se distingue pelas seguintes características: • Simples – O Java é uma linguagem simples e não necessita de treino extensivo de programação para que se consiga obter resultados. Os conceitos básicos do Java são facilmente apreendidos e as ferramentas são intuitivas e facilitam o trabalho do programador. • Orientada ao objecto – O Java adopta o conceito de objecto, para facilitar e organizar todo o processo de programação. O código passa a ser encapsulado e reutilizável, podendo abstrair o programador de funções mais complexas ou permitir o uso de objectos já desenvolvidos. Podem ser utilizadas librarias externas com código já desenvolvido bem como quaisquer outros objectos que possam ser úteis para a programação de uma aplicação. • Arquitectura neutra – O Java foi desenhado de forma a poder interagir com diversos sistemas, com diversas arquitecturas distintas e heterogéneas. Para que isto seja possível e para que seja independente da plataforma utilizada, o compilador Java compila o código desenvolvido para uma arquitectura intermédia denominada byte codes, neutra e independente, destinada a transportar o código eficientemente entre diferentes plataformas de hardware e software. • Portável – A arquitectura neutra utilizada pelo Java, torna-o numa linguagem altamente portável e compatível com diferentes tipos de máquinas ou software. Cada máquina (plataforma) é responsável pela interpretação do código de byte codes, através de uma Java Virtual Machine (JVM). Assim sendo o código desenvolvido em Java pode correr em qualquer plataforma desde que esta possua uma JVM. • Distribuída – Devido à sua grande portabilidade, o Java consegue estabelecer comunicação entre diversas plataformas distintas o que a torna ideal para a programação distribuída. 12 Java • • • • • • • Interpretada – O Interpretador Java pode executar byte codes em qualquer máquina para a qual tenha sido portado o sistema. Por outras palavras, num sistema interpretado, como é o caso do Java, a fase de linkagem do programa é simples, incremental e de baixo processamento, tornando os ciclos de desenvolvimento mais rápidos, comparativamente a outras linguagens. Robusta – Esta linguagem de programação foi criada tendo em vista o desenvolvimento de software robusto e de confiança. São efectuadas diversas verificações durante as fases de desenvolvimento, compilação e em execução. Além disso, a gestão de memória é encapsulada, feita implicitamente pelo Java, diminuindo drasticamente os erros e facilitando a sua gestão. Um programador pode desenvolver uma aplicação com a confiança de que quaisquer erros serão rapidamente encontrados e resolvidos. Segura – O Java foi desenhado para operar em ambientes distribuídos, por isso, foi prestada uma especial atenção ao factor segurança. Deste modo, quaisquer aplicações desenvolvidas estão seguras contra possíveis ataques vindos do exterior. Alta performance – Numa linguagem de programação, a performance é sempre importante. No Java, o interpretador pode correr e converter os byte codes em código, sem ter que fazer verificações ao sistema. Algumas empresas estão a tentar desenvolver um compilador de Java para a arquitectura nativa da máquina o que aumentará a performance. Multi-processo – O Java suporta programação multi-processo. Num único programa, podem estar múltiplos processos independentes a correr código distinto e continuamente, de uma forma concorrente. Dinâmica – A fase de linkagem é dinâmica. As classes desenvolvidas são linkadas apenas quando necessário o que permite que, a qualquer altura, novas classes internas, externas ou até vindas de uma rede, possam ser linkadas com o programa em desenvolvimento. As aplicações desenvolvidas podem assim ser actualizadas em qualquer altura. Garbage Collector – Não é necessário fazer qualquer alocação explícita de memória no Java. A memória é alocada quando necessário e recolhida pelo Garbage Collector quando deixa de ser necessária. Ao contrário da maior parte das linguagens de programação, em que um programa pode ser compilado ou interpretado para que possa correr num computador, com Java o programa é compilado e interpretado. Primeiro o compilador traduz o programa para uma linguagem intermédia e independente da plataforma, denominada byte codes. A partir daí, o interpretador é responsável por correr o código desenvolvido em cada plataforma. 13 Tecnologia Java aplicada a telemóveis No caso do Java, o código é compilado apenas uma vez, e interpretado cada vez que é corrido. Figura 3. 1 - Esquema de funcionamento do Java Cada interpretador, quer seja uma aplicação ou um browser que suporte Java applets é uma implementação de uma Java Virtual Machine (JVM) preparada para receber o código em byte codes e corre-lo. É isto que faz com que o Java seja uma linguagem do tipo “write once, run anywhere”. Uma aplicação pode ser desenvolvida e compilada sobre qualquer plataforma, e depois corrida em cima de qualquer implementação da JVM, independentemente da nova plataforma utilizada. Figura 3. 2 - Portabilidade do Java 14 Java 3.1.2 – A plataforma Uma plataforma pode ser descrita como o ambiente de hardware e software onde pode ser corrido um programa. Ao contrario da maior parte das plataformas conhecidas que resultam na combinação de componentes de hardware com software específico, a plataforma Java é baseada apenas numa componente de software que corre em cima de hardware de outras plataformas. A plataforma Java é constituída por dois componentes: • Java Virtual Machine (JVM); • Java Application Programming Interface (API); Tal como foi já referenciado, o JVM é um interpretador que analisa o código traduzido para byte codes e faz com que possa ser corrido sobre qualquer plataforma. O JVM é portanto toda a base da portabilidade do Java. O Java API (Application Programming Interface) é uma colecção de componentes de software já desenvolvidos que disponibilizam muitas utilidades aos programadores, como por exemplo, um interface gráfico (GUI). A API está agrupada em librarias de interfaces e classes relacionados, que são conhecidas como packages. Os programadores podem assim utilizar livremente quaisquer packages disponibilizados afim de facilitar e optimizar o desenvolvimento de aplicações sobre esta plataforma. O esquema que se segue, mostra a plataforma Java e os seus constituintes: Figura 3. 3 - Constituintes do Java Devido ao uso de um estado intermédio de compilação, onde são gerados os byte codes, a plataforma Java torna-se um pouco mais lenta do que código nativo, contudo, com a utilização de bons compiladores e interpretadores, a performance pode-se aproximar bastante do código nativo sem porém pôr em causa a sua portabilidade. O Java é portanto ideal para trabalhar em diversas plataformas distintas e, por isso, teoricamente, seria apenas necessário desenvolver uma JVM que se pudesse aplicar às diversas plataformas moveis existentes. À primeira vista, o Java adaptar-se-ia perfeitamente como linguagem para programar aplicações destinadas a telemóveis. 15 Tecnologia Java aplicada a telemóveis 3.2 – J2SE / J2EE / Java Card De modo a optimizar a programação em áreas muito distintas, foram desenvolvidas diferentes versões do Java, destinadas a diferentes utilizações. • • • J2SE – Standard Edition – A edição standard é a base da tecnologia Java. No J2SE está contido tudo o que é essencial para programar em Java, incluindo o compilador, ferramentas e APIs para desenvolver applets e aplicações. Esta edição é mais direccionada aos programadores que pretendem desenvolver aplicações standalone ou que corram como cliente. J2EE – Enterprise Edition – Esta edição considerada “empresarial” pela “Sun”, além dos componentes básicos e essenciais para programar em Java, contém algumas outras funcionalidades mais vocacionadas para o desenvolvimento em empresas ou aplicações que corram do lado do servidor. O J2EE suporta Enterprise Java Beans (EJB) para optimizar a programação distribuída e segura, com bom suporte de bases de dados, e contém uma API para o desenvolvimento de Java Servlets, Java Server Pages e tecnologia XML. Java Card – O Java Card foi desenhado especialmente para plataformas com memória muito limitada que usa smart cards (cartões de memória) como a maioria dos telemóveis, cartões de identificação, etc. Esta tecnologia permite correr pequenas aplicações denominadas applets que utilizam a tecnologia Java. Embora o Java demonstre ter muitas capacidades e uma grande vocação para se apresentar em diversas plataformas muito distintas, existem ainda alguns pormenores que impedem de ter um bom desempenho numa plataforma móvel. Tanto a Standard Edition como a Enterprise Edition não se adequam a ser utilizadas num telemóvel, pelo que foi necessário fazer algumas alterações ás versões existentes de modo a adaptar esta linguagem de grande potencial a estas novas plataformas. Figura 3. 4 - Diversas versões do Java 16 Java Também a tecnologia Java Card, embora suficientemente simplificada para poder ser utilizada em plataformas móveis (como já é o caso), demonstrase demasiado limitativa, permitindo apenas a criação de pequenas applets muito simples. Deste modo, as já grandes potencialidades dos telemóveis mais recentes não seriam minimamente aproveitadas. Era então necessário o aparecimento de uma nova edição Java que conseguisse conjugar as grandes vantagens e potencialidades disponibilizadas pelo J2SE e J2EE com a vertente mais leve e simplificada da tecnologia JavaCard. Foi assim lançada recentemente uma nova edição do Java denominada J2ME (Micro Edition). Java: A figura que se segue dá uma ideia mais clara das diferentes versões do Figura 3. 5 - Plataformas Java 17 Tecnologia Java aplicada a telemóveis 3.3 – J2ME A edição Micro do Java é uma versão reduzida e altamente optimizada para máquinas com recursos limitados de memória, vídeo e processamento. O J2ME destina-se a pequenos aparelhos como telemóveis, PDAs, sistemas móveis de navegação e quaisquer outros tipos de plataformas móveis que necessitem de um bom desempenho sobre recursos muito limitados. Anunciado em 1999, o J2ME traz muitas das funcionalidades multiplataforma presentes no Java, permitindo assim o desenvolvimento de aplicações bastante poderosas para as plataformas moveis que têm vindo a surgir. Em seguida, serão analisadas cuidadosamente todas as funcionalidades mais relevantes, presentes no J2ME, dando mais ênfase à plataforma específica dos telemóveis, visto ser esse o tema e objectivo deste documento. Para ter uma boa compreensão do modo de funcionamento da tecnologia Java aplicada aos telefones móveis e saber o procedimento mais adequado para o desenvolvimento de uma aplicação robusta e funcional, é necessário obter o máximo de informação acerca da linguagem / plataforma a utilizar. Serão aqui introduzidos e explicados alguns conceitos essenciais para o desenvolvimento de aplicações com esta tecnologia, que serão utilizados mais adiante, já na fase de desenvolvimento de aplicações. 3.3.1 – Arquitectura do J2ME De modo a ser mais eficaz e ao mesmo tempo versátil, o J2ME usa “configurações” e “perfis” para personalizar o seu ambiente de trabalho em runtime (Java Runtime Environment – JRE). O JRE do J2ME é altamente configurável, podendo ser especificado o tipo de JVM utilizado e o perfil que se adequa a modelos mais restritos de plataformas. Conforme cada situação, são seleccionadas classes especificas que melhor se enquadram no tipo de programa que irá ser desenvolvido e na plataforma que servirá de suporte. A “configuração” define um tipo básico de ambiente para runtime baseado num conjunto específico de classes, e uma JVM apropriada ao tipo de máquina que será alvo da programação. O “perfil” é responsável pela definição da aplicação. Aqui, são adicionadas classes à configuração do J2ME que definem determinadas utilidades adequadas ás máquinas em questão. 18 Java 3.3.1.1. Configuração A configuração é uma especificação que define o ambiente de software para uma gama de aparelhos definidos por determinadas características, tais como: • Tipo e quantidade de memória disponível; • Tipo e velocidade do processador; • Tipo de ligação de rede disponível para o aparelho; A configuração deve representar o suporte mínimo para a plataforma em questão, e não definir outras funcionalidades opcionais. Os fabricantes devem garantir que as especificações estão implementadas de modo a que os programadores possam desenvolver software consistente e o mais independente de plataforma possível. Actualmente existem duas configurações possíveis no J2ME: Connected Limited Device Configuration (CLDC) A configuração CLDC destina-se a aparelhos com recursos mais limitados. Uma plataforma típica CLDC é um telemóvel ou um PDA com um máximo de 512 KB de memória disponível. É por esta razão que o CLDC está muito ligado à vertente wireless do Java, que permite aos utilizadores de telemóveis o download de aplicações denominadas MIDlets. Um grande número de fabricantes de telefones móveis assinaram já acordos com a Sun Microsystems que lhes permite o uso desta tecnologia. Por isso mesmo, prevê-se que o número de telemóveis programáveis em Java, cresça muito rapidamente durante os próximos anos. Connected Device Configuration (CDC) O CDC destina-se aos aparelhos com capacidades superiores aos abrangidos pelo CLDC, mas que se encontram abaixo dos computadores pessoais. Estes aparelhos, normalmente dispõem de uma memória superior a 2 MB e processadores mais potentes, pelo que podem usufruir de um ambiente muito mais complexo e poderoso do que os anteriores. Esta configuração é muito utilizada nos PDAs topo de gama. Cada configuração consiste numa JVM e numa colecção base de classes Java que fornecem um ambiente adequado, para o desenvolvimento de aplicações de software. 19 Tecnologia Java aplicada a telemóveis As muitas limitações em termos de processamento e memória, especialmente em aparelhos com menos recursos como é o caso dos telemóveis, tornam impossível para uma J2ME Virtual Machine suportar todas as funcionalidades, instruções em byte code e optimizações de software suportadas pela Virtual Machine do J2SE. Por isso mesmo, as VMs do J2ME são definidas mediante o caso para o qual se pretende programar, ou seja, uma VM irá ser adequada a um tipo concreto de configuração. Por exemplo, como na maioria dos casos, os aparelhos abrangidos pelo CDLC não suportam operações com virgula flutuante, a VM do CLDC não tem que suportar tipos de dados como float e double, ou quaisquer classes ou métodos que envolvam este tipo de operações. Note-se no entanto que as configurações não requerem o uso de VMs específicas. Os fabricantes são livres de criar as suas próprias VMs ou licenciar VMs que respondam melhor aos seus requisitos. A Sun fornece já VMs específicas para cada tipo de configuração: • Com a configuração CLDC, está incluída uma VM denominada Kilobyte Virtual Machine (KVM). Esta é uma VM com funcionalidades reduzidas, necessita de pouca memória e possui um garbage collector optimizado para ambientes com poucos recursos. Embora a KVM seja muito provavelmente a mais utilizada em implementações CLDC, existe uma outra VM da IBM denominada “J9”, que também pode ser utilizada nestes casos. • O CDC inclui uma VM denominada “CVM” que suporta a grande parte das funcionalidades da VM utilizada pelo J2SE, à excepção de alguns aspectos incluídos nas versões mais recentes. Também para este caso existem alternativas lançadas pela IBM. As configurações também incluem algumas classes Java essenciais. As librarias de classes Java definidas para uma determinada configuração ( e perfil) são baseadas na plataforma Java 2. Isto permite aumentar a compatibilidade entre aplicações desenvolvidas em J2ME e J2SE, e diminui o tempo e dificuldade de aprendizagem para os programadores de J2ME. Por outras palavras, isto quer dizer que os programadores podem confiar no seguinte: • Sempre que possível, o J2ME reutiliza as classes e packages do J2SE. Isto quer dizer que tudo o que se sabe do J2SE pode ser aplicado ao J2ME, tendo em conta as limitações do suporte físico, configuração e perfil escolhido. • Quando uma classe J2SE é incorporada no J2ME, não podem ser acrescentados novos métodos ou campos. Isto assegura que, se uma aplicação J2ME é feita exclusivamente com classes vindas do J2SE, então é possível compilar e correr essa aplicação em J2SE. Isto permite a troca de código entre plataformas distintas. Para o caso específico da programação aplicada a telemóveis, a configuração mais adequada seria a CLDC, com o uso da KVM. 20 Java Adiante será vista mais pormenorizadamente esta configuração, bem como a Virtual Machine que lhe está associada (KVM) e que será utilizada no desenvolvimento de aplicações para este tipo de plataforma. 3.3.1.2. Perfil Um perfil complementa a configuração acrescentando classes adicionais que disponibilizam funcionalidades apropriadas a um tipo particular de aparelho ou segmento de mercado. Ambas as configurações do J2ME têm um ou mais perfis associados, alguns dos quais podendo até estar dependentes de outros perfis. Os perfis actualmente existentes são os seguintes: Mobile Information Device Profile (MIDP) Este perfil acrescenta componentes de rede, interface de utilizador e armazenamento ao CLDC. O MIDP é destinado a aparelhos com recursos gráficos e de armazenamento limitados, como é o caso dos telemóveis e, deste modo, disponibiliza um interface de utilizador relativamente simples e funções básicas de rede, baseadas em HTTP 1.1. O MIDP é o perfil mais conhecido e utilizado do J2ME porque é a base para o Java destinado a plataformas móveis (Wireless Java) e é actualmente o único perfil disponível para aparelhos que utilizem o sistema operativo “PalmOS”. PDA Profile (PDAP) O PDA Profile é muito similar ao MIDP mas destina-se a PDAs com melhores ecrãs e mais memória disponível do que os telemóveis. O PDAP oferece uma libraria de interface de utilizador mais sofisticada e uma Java API que fornece algumas utilidades do sistema operativo. Foundation Profile Este perfil é uma extensão ao CDC que inclui quase todas as librarias do Java 2 versão 1.3. Tal como o seu nome sugere, este perfil destina-se a servir de base à maioria dos outros perfis que estendem o CDC. Personal Basis e Personal Profile O Personal Basis Profile acrescenta funcionalidades básicas do interface de utilizador ao Foundation Profile sendo assim destinado a ser utilizado por aparelhos com um interface de utilizador menos sofisticado. Por exemplo, este perfil permite apenas uma única janela activa de cada vez. Para plataformas que suportem um interface de utilizador mais complexo, é utilizado Personal Profile. 21 Tecnologia Java aplicada a telemóveis RMI Profile O perfil RMI acrescenta librarias de invocação remota de métodos (Remote Method Invocation) do J2SE ao Foundation Profile. Game Profile O Game Profile que se encontra ainda em desenvolvimento, vai disponibilizar uma plataforma para o desenvolvimento de jogos em aparelhos com configuração CDC. Para o desenvolvimento de aplicações para telemóveis, será utilizado o perfil MIDP, visto ser este o perfil especialmente desenvolvido para o caso. Note-se porém que já existem outros perfis em desenvolvimento que podem eventualmente substituir o MIDP. Também a rápida evolução deste tipo de tecnologia pode influenciar a escolha de um perfil adequado e é certo que num futuro próximo o MIDP poderá ser substituído por outro perfil que ofereça novas potencialidades. No entanto, para já, para desenvolver aplicações para telemóveis, o MIDP é a solução mais adequada. A figura que se segue ilustra as configurações e os perfis referidos: Figura 3. 6 - Configurações e Perfis 22 Java 3.3.2 – Connected Limited Device Configuration O CLDC é a base em que são construídos os perfis destinados a pequenos aparelhos móveis como é o caso dos telemóveis ou PDAs de pouca capacidade. A especificação CLDC destina-se a dispositivos com as seguintes características: • 160 a 512 KB de memória total disponível para a plataforma Java; • Processadores de 16 bits ou 32 bits; • Baixo consumo de energia (alimentação por bateria); • Ligação à rede intermitente e sem fios, com largura da banda limitada; Estes aparelhos são caracterizados pelos recursos de memória limitados e baixo poder de processamento, o que torna impossível o suporte de uma plataforma Java completa e funcional. No CLDC está especificado um conjunto mínimo de packages e classes, assim como uma JVM com funcionalidades reduzidas que pode ser utilizada tendo em consideração as limitações impostas por este tipo de aparelhos. Seguidamente serão descritas as funcionalidades fornecidas pela VM do CLDC, bem como as principais diferenças entre essa VM e a VM do J2SE. Ao longo deste capítulo serão também vistos alguns packages e classes disponibilizadas pelo CLDC. 3.3.2.1. CLDC Java Virtual Machine As limitações de hardware e software impostas pelo tipo de aparelhos aos quais se destina o CLDC, tornam impraticável o suporte de uma versão completa do JVM ou até mesmo do conjunto das classes suportadas pelo J2SE. Uma aplicação que corre na plataforma Windows, por muito simples que seja (por exemplo uma aplicação do tipo “Hello World”), necessita que cerca de 16 MB de memória sejam alocados. Pelo contrario, os requisitos mínimos para o CLDC são: • 128 KB de memória ROM, flash, ou qualquer outro tipo não volátil para armazenamento da JVM e librarias de classes constituintes da plataforma CLDC; • 32 KB de memória volátil para alocação em runtime. Esta memória destina-se a satisfazer os requisitos dinâmicos das aplicações Java que incluem o carregamento de classes e alocação de espaço de pilha para objectos. Para suportar um ambiente Java com tão poucos recursos, o CLDC define requisitos muito reduzidos para a VM, para a linguagem ou mesmo até para as librarias utilizadas. Além dos requisitos de memória, o CLDC faz algumas assunções acerca da plataforma que o suporta, por exemplo, é assumido que o aparelho tem sempre um ecrã e um mecanismo de input, e não é necessário que haja memória disponível para o armazenamento de aplicações. É assumido que estas questões são da responsabilidade dos fabricantes dos aparelhos. 23 Tecnologia Java aplicada a telemóveis O CLDC limita o número de requisitos para maximizar o número de plataformas em que pode ser implementado. Em termos de ambiente de software, o CLDC assume que o aparelho já possui um sistema operativo capaz de gerir e executar a VM. Embora o Java suporte programação milti-processo, não é necessário que esta funcionalidade seja suportada ou sequer reconhecida pelo sistema operativo. Por outro lado, a VM tem por obrigação conseguir a simulação de ambiente multi-processo, usando qualquer funcionalidade que lhe seja disponibilizada. A especificação completa do CLDC pode ser encontrada em http://jcp.org/jsr/detail/30.jsp. 3.3.2.2. Virtual Machine e especificações de linguagem A especificação do CLDC define algumas características que a VM tem que ter, descrevendo as partes da especificações da Java Virtual Machine completa e da linguagem Java que não requerem suporte e as partes em que existem limitações ou alterações. A Sun disponibiliza uma VM denominada Kilobyte Virtual Machine que satisfaz os requisitos do CLDC. Contudo, os fabricantes não são obrigados a basear os seus produtos na KVM. Pode ser utilizada qualquer VM que satisfaça os requisitos do CLDC. Suporte de virgula flutuante Visto que a maior parte dos processadores englobados pelo CLDC não suporta o uso de operações com virgula flutuante, a VM também não necessita de suportar este tipo de operações. Isto leva às seguintes restrições: • Variáveis do tipo float ou double, ou arrays de variáveis destes tipos, não podem ser usados ou declarados; • Constantes do tipo float ou double (ex: 1.5, 354.98, ...) não podem ser usadas; • Os argumentos dos métodos não podem ser do tipo float ou double; • Métodos não podem retornar valores do tipo float ou double; • Objectos do tipo Float ou Double não podem ser criados, aliás, esses métodos nem sequer existem no CLDC; A Sun não tem uma versão diferente do compilador Java para aplicações CLDC, pelo que é possível usar o compilador normal do J2SE e, assim, usar virgula flutuante e violar as regras acima descritas. No entanto, as classes criadas seriam rejeitadas quando carregadas na Virtual Machine do CLDC, durante a fase de verificação de classes. 24 Java Omissões de linguagem Além das restrições de virgula flutuante, existem algumas funcionalidades da linguagem Java que também não estão disponíveis para aplicações CLDC: • Reflection – O package “java.lang.reflect” assim como todas as funcionalidades de “java.lang.Class” que estão de alguma maneira ligadas ao reflection, não estão disponíveis. Esta restrição é aplicada em parte para poupar memória, mas também porque evita determinar se o código tem ou não privilégios para aceder a estas funcionalidades. • Weak References – Weak references e o package “java.lang.ref” não são fornecidos devido à elevada quantidade de memória necessária para a sua implementação. • Finalização de objectos – A finalização de objectos é de uma elevada complexidade para a VM e, no entanto, traz muito poucos benefícios. Deste modo, a finalização não está implementada e a classe “java.lang.Object” não tem o método finalize(). • Threads – O CLDC suporta threads mas não permite a criação de deamons (threads que são terminados quando todos os outros threads na VM terminam), ou grupos de threads. • Erros e Excepções – O J2SE tem um grande número de classes que representam erros e excepções. Visto que, em geral, não é esperado que as aplicações Java recuperem deste tipo de condições (excepções derivadas da classe “java.lang.error”), a maioria das classes representativas destes erros não está incluída no CLDC. Quando há uma situação de erro, o próprio aparelho é responsável por tomar as devidas medidas, em vez de enviar o erro para o código da aplicação. • Interface Nativo do Java – O CLDC não contém a funcionalidade JNI (Java Native Interface) do J2SE, que permite que código nativo seja invocado por classes Java. O JNI é omitido pois requer muita memória para a sua implementação e, em parte, para proteger aparelhos que usem o CLDC de problemas de segurança causados por código. 25 Tecnologia Java aplicada a telemóveis 3.3.2.3. Carregamento de classes No J2SE o carregamento de classes é feito por class loaders, incluindo class loaders, definidos pelas aplicações que podem implementar um conjunto de mecanismos para localizar e carregar classes Java. Pelo contrario, a especificação CLDC requer implementações específicas para conseguir os seus próprios mecanismos de carregamento de classes, que depois não podem ser estendidos ou sobrepostos por código das aplicações, pois isto teria algumas implicações no que diz respeito a segurança. O CLDC especifica que todas as implementações da VM têm que ser capazes de carregar aplicações comprimidas em ficheiros JAR. É sob a forma de ficheiros JAR que a grande maioria das aplicações desenvolvidas para telemóveis se encontra, sendo por isso que esta característica é muito importante. Por isso, é também importante saber a capacidade que cada aparelho disponibiliza para correr ficheiros JAR. No entanto, o CLDC não exclui outros meios dependentes da plataforma de representação ou acesso ao código de aplicações. Este tipo de tarefas seria delegado a software específico, dependente da plataforma e fora do âmbito do CLDC. Cada aparelho pode transformar aplicações apresentadas sob qualquer formato externo, num formato interno que seja mais apropriado ou mais eficiente. 3.3.2.4. Considerações de segurança No J2SE, o modelo de segurança é suficientemente poderoso para permitir que código originário de diferentes fontes, tenha diferentes níveis de privilegio e consequentemente diferentes níveis de acesso aos recursos do sistema. Se por um lado, por defeito, as aplicações instaladas no sistema não têm restrições de acesso, por outro lado uma applet descarregada de um site, opera num ambiente extremamente restrito que não permite o acesso a recursos locais, e apenas um aceso muito limitado à rede. Entre estes extremos, o modelo de segurança permite que os privilégios sejam individualmente atribuídos a uma aplicação ou applet baseados num “nível de segurança”. Código dito “de confiança” pode vir acompanhado de um certificado que assegura a sua proveniência. É possível também o uso de uma assinatura criptográfica que assegure que o código não foi modificado durante o seu percurso desde a origem até ao seu destino. A VM do CLDC poderia ser usada num dispositivo que não permitisse a instalação de código pelo utilizador e que, por isso mesmo, não necessitaria de uma segurança muito apertada. Poderia também ser utilizado num telemóvel ligado a uma rede que permitisse que aplicações fossem descarregadas directamente, possivelmente provenientes de fontes não seguras. Neste caso estaria sujeita ao mesmo tipo de verificações efectuadas pelo J2SE a applets. Também seria útil a definição de estados intermédios de segurança para código confiável. 26 Java Infelizmente estes cenários são impraticáveis para a grande maioria dos casos pois a memória e o processamento necessários para a implementação do modelo de segurança do J2SE, verificação de assinaturas criptográficas, verificação de certificados, e principalmente a definição de diversos níveis de segurança estão muito acima dos disponibilizados por este tipo de aparelhos. As funcionalidades de chaves criptográficas e assinaturas só começam a ser possíveis, com o lançamento do MIDP 2.0. Assim sendo, a VM do CLDC corre as aplicações num ambiente isolado que assegura que o dispositivo no qual a aplicação está a ser executada, não pode ser danificado. Este tipo de ambiente é conseguido da seguinte forma: Controlo de carregamento de classes Cada implementação do CLDC é responsável por carregar as suas classes que podem ser provenientes de diversas localizações distintas. Ao contrário do que acontece no J2SE, as aplicações não podem criar os seus próprios class loaders, pelo que não é possível afectar o class loader do sistema ou as classes que este utiliza. Como consequência desta restrição, o código das aplicações não pode actualizar as suas próprias versões das hierarquias dos packages Java e “javax.microedition”. Se isto fosse permitido, poderia comprometer a segurança do ambiente onde é corrida a aplicação. Quaisquer classes que estejam incluídas numa aplicação e que se digam fazer parte destes packages serão ignoradas. Acesso a código nativo Como já foi referenciado, o CLDC não inclui uma implementação do JNI e, por isso mesmo, não é possível fazer uma ligação dinâmica ao código nativo em tempo de execução, mesmo que esse código pudesse ser instalado como parte de uma aplicação. Como efeito secundário, é impedido o acesso directo a funcionalidades disponibilizadas pelo sistema operativo do aparelho, a não ser que exista para isso um interface Java específico fornecido pelo CLDC ou por um dos seus perfis. Esta restrição impede que o código de uma aplicação aceda a informação contra a vontade do utilizador. Contudo é possível estender a API disponível para aplicações Java, efectuando uma pré-linkagem de código nativo com a VM, mas esta funcionalidade está apenas disponível para aplicações que corram sobre uma VM desenvolvida de uma forma personalizada, pelo que não constitui um risco genérico. 27 Tecnologia Java aplicada a telemóveis Verificação de classes O J2SE sempre disponibilizou um verificador de byte codes capaz de verificar a integridade de ficheiros class do Java. Isto assegura que os ficheiros class não põe em risco a segurança do sistema, falhando na aplicação de regras da linguagem Java que normalmente são verificadas e reforçadas pelo compilador, tais como: • Todas as variáveis devem ser inicializadas antes de serem usadas; • Aquando da criação de um objecto, o seu construtor deve ser chamado antes de qualquer utilização; • Cada construtor deve começar com a invocação de um construtor da sua “superclasse” (com a excepção do construtor de java.lang.Object); • Variáveis locais, instâncias e membros estáticos declarados contendo referências a objectos de um tipo particular, devem conter sempre uma referência a um objecto cujo tipo lhe esteja legalmente associado; Por defeito a VM do J2SE corre um verificador de byte codes por todas as classes vindas de fontes externas, mas não pelas classes locais. Em ambientes móveis, é aconselhável fazer a verificação em todo o código, contudo, os algoritmos necessários a este tipo de verificações necessitam de muita memória e poder de processamento, tornando impossível a sua execução neste tipo de aparelhos. Para isso, esta verificação foi dividida em duas etapas: • É feita uma pré-verificação nos ficheiros class antes de estes serem instalados. Esta operação envolve a parte mais complexa e consumidora de recursos da verificação de código e é feita como parte ou durante a fase de compilação. O resultado desta pré-verificação é guardado nos ficheiros class onde pode ser acedido em tempo de execução. • A verificação em tempo de execução é efectuada no próprio aparelho. Dependendo da natureza do aparelho, a verificação pode ser feita quando a classe é carregada ou como parte da instalação da aplicação, impedindo assim o código instalado de ser posteriormente modificado. Este passo utiliza a informação guardada pela pré-verificação em conjunto com uma passagem linear pelos byte codes apenas para assegurar que as regras da linguagem foram respeitadas. É um procedimento muito mais rápido do que a pré-verificação e necessita de muito menos recursos. 28 Java 3.3.2.5. Compilar e correr código com KVM Para compilar e correr código utilizando o KVM, é necessário fazer o download de algum software: • Java 2 SDK (Software Development Kit) ou outro ambiente de desenvolvimento que contenha um compilador Java em linha de comandos; • O CLDC reference implementation da Sun; Caso não esteja instalado nenhum Java 2 SDK adequado, pode-se fazer o download em http://java.sun.com/j2se/. O CLDC reference implementation contém o código fonte e a documentação da implementação do CLDC da Sun, que corre em Windows, Linux e Solaris, contendo ainda o KVM e as ferramentas a ele associadas na forma executável. Isto pode ser obtido em http://java.sun.com/products/cldc/. Esta implementação é fornecida sob a forma de um ficheiro executável apropriado à plataforma em questão, que deve ser descompactado para a directoria conveniente. Para referir as directorias de instalação do SDK e CLDC, são utilizadas as seguintes variáveis: %JAVA_HOME% (Windows) ou $JAVA_HOME (Solaris/Linux) Aqui será indicada a directoria base da instalação do Java 2 SDK. Normalmente, no caso do Windows é “c:\jdk1.3.1”. %CLDC_HOME% (Windows) ou $CLDC_HOME (Solaris/Linux) Aqui será indicada a directoria base de instalação do CLDC Reference Implementation, por exemplo, “c:\CLDC”. O arquivo extrai-se automaticamente para a directoria “j2me_cldc”, abaixo desta localização. %CLDC_PATH% (Windows) ou $CLDC_PATH(Solaris/Linux) Esta variável refere-se à directoria “bin” dentro da directoria de instalação do CLDC. 29 Tecnologia Java aplicada a telemóveis Exemplo de compilação de uma aplicação Para exemplificar o processo de compilação, vamos supor que temos uma pequena aplicação do tipo “Hello World”, desenvolvida para CLDC, e que a compilação irá ser feita em Windows: Hello World package ora.ch2; public class HelloWorld{ public static void main(String [] args) { System.out.println(“Hello World”); } } O primeiro passo é abrir uma linha de comandos e definir a variável PATH com os ficheiros executáveis do Java 2 SDK e CDLC Reference Implementation. PATH=%JAVA_HOME%\bin; %CLDC_PATH%\win32; %PATH% O Segundo passo é compilar o exemplo de código acima, de forma a produzir um ficheiro class. Para simplificar este exemplo, muda-se a directoria de trabalho para “%HelloWorld%\src”, sendo que esta é a directoria onde se encontra o código fonte da aplicação “hello world”. Em seguida, devem ser introduzidos os seguintes comandos: md tmpclasses javac –bootclasspath %CLDC_PATH%\common\api\classes –d tmpclasses ora\ch2\HelloWorld.java Estes comandos compilam o código fonte “ora\ch2\HelloWorld.java” originando um único ficheiro do tipo class com o nome “tmpclasses\ora\ch2\HelloWorld.class”. O uso da opção “–d” serve para indicar ao compilador que deve colocar o ficheiro class na directoria criada (“tmpclasses”) em vez da mesma directoria onde se encontra o código fonte, como definido por defeito. Isto porque todos os ficheiros class a ser carregados na KVM têm de ser pré-verificados, resultando daí um ficheiro class modificado. Esse ficheiro será utilizado como entrada para a pré-verificação, e o ficheiro de saída será colocado na directoria onde se encontra o código fonte. Também foi utilizada a opção “–bootclasspath” para mudar a localização de onde as classes são carregadas, durante a compilação. O CLDC não contém todos os packages e classes disponíveis para uma aplicação J2SE, por isso, é necessário que o compilador utiliza as librarias do CLDC em vez do J2SE, o que seria feito por defeito. 30 Java Antes que os ficheiros class sejam utilizados pelo KVM, é necessário fazer uma pré-verificação. Isto pode ser feito usando o comando “preverify” do CLDC. Para pré-verificar um ficheiro class e gravar o ficheiro resultante na mesma directoria do código fonte, é usado o seguinte comando: preverify –classpath %CLDC_PATH%\common\api\classes; tmpclasses –d . ora.ch2.HelloWorld A opção “–classpath” indica a directoria na qual o comando “preverify” deve procurar os ficheiros class tanto os das librarias como os que irão ser préverificados. A opção “–d” será para indicar a directoria para onde será gravado o ficheiro resultante da pré-verificação. No caso de uma aplicação consistir em mais do que um ficheiro class, é necessário efectuar uma pré-verificação para cada ficheiro. Existem duas maneiras para executar esta operação: Podem ser listadas todas as classes na linha de comandos: preverify –classpath %CLDC_PATH%\common\api\classes; tmpclasses –d . ora.ch2.HelloWorld ora.ch2.HelloWorld2 Alternativamente, pode ser fornecida a directoria onde se encontram os ficheiros. O comando “preverify” irá percorrer a directoria e verificar todos os ficheiros class, ZIP e JAR: preverify –classpath tmpclasses %CLDC_PATH%\common\api\classes –d . Finalmente, o programa pode ser executado pelo comando “kvm”: kvm –classpath . ora.ch2.HelloWorld Como output, será mostrada a seguinte mensagem: Hello World Note-se que neste caso é apenas necessário indicar a directoria onde se encontra o programa a ser corrido, pois o comando “kvm” já sabe onde se encontram todas as librarias necessárias. 31 Tecnologia Java aplicada a telemóveis 3.3.2.6. Librarias de classes do CLDC Como já foi referenciado, o CLDC abrange um largo número de dispositivos que não têm capacidade suficiente para suportar as librarias disponibilizadas pelo J2SE, e porque o CLDC é uma configuração e não um perfil, não pode conter funcionalidades opcionais. Por isso, os packages e as classes contidas no CLDC devem ser adequadas mesmo aos aparelhos que tenham apenas os requisitos mínimos suportados pelo CLDC. A libraria de classes do CLDC é extremamente pequena, contendo apenas um package com funcionalidades específicas do J2ME denominado “javax.microedition.io” e uma selecção de classes dos seguintes packages da especificação J2SE: • Java.io; • Java.lang; • Java.util; Todos os perfis e configurações J2ME incluem packages ou classes do J2SE. Quando J2ME incorpora interfaces de software do J2SE, deve respeitar as seguintes regras: • Os nomes das classes ou packages deve ser o mesmo sempre que possível; • A semântica de classes ou métodos, transportados para o J2ME devem ser idênticos aos que tenham o mesmo nome em J2SE; • Não é possível acrescentar campos do tipo public ou protected ou métodos a uma classe partilhada entre o J2ME e o J2SE; Por causa destas regras, os packages e classes do J2ME serão sempre derivados do J2SE. Assim sendo, o comportamento do J2ME será muito similar ao J2SE facilitando a tarefa de aprendizagem aos programadores familiarizados com o Java tradicional. Não é também permitido às configurações e perfis do J2ME adicionar quaisquer funcionalidades extra aos packages e classes partilhadas com o J2SE, sendo deste modo preservada a compatibilidade com o J2SE. J2ME. 32 Seguidamente serão analisados os packages mais importantes do Java Java.lang O package “java.lang” do CLDC tem apenas cerca de metade das classes da sua versão J2SE e, mesmo assim, algumas das classes implementadas não são versões completas. • Classe Object – A classe “java.lang.Object” não contém o método “finalize()” visto que a VM não suporta finalização. Também o objecto “clone()” foi removido bem como o interface “java.lang.Clonable”. • Classes relacionadas com números – Como mencionado anteriormente, o CLDC não suporta operações com virgula flutuante e, como consequência, as classes “java.lang.Float” e “java.lang.Double” foram retiradas. As outras classes numéricas (“Byte”, “Integer”, “Long” e “Short”) estão incluídas, à excepção da sua classe base do J2SE “java.lang.Number”. As classes numéricas são portanto derivadas de Object em vez de Number. Também é de referir que o interface “java.lang.Comparable” não existe no CLDC, pelo que não é possível fazer comparações directas. • Funcionalidades de Reflection – todos os métodos relacionados com esta funcionalidade foram removidos. É porém possível fazer algumas operações limitadas em classes cujo tipo não é conhecido na altura da compilação, usando métodos como “forName()” ou “newInstance()”. • Propriedades do sistema – O CLDC define apenas um pequeno conjunto de funcionalidades do sistema, e nenhuma destas está incluída no J2SE. As propriedades que uma implementação deve disponibilizar estão listadas na seguinte tabela: Nome Detalhes Exemplo microedition.configuration microedition.encoding microedition.platform microedition.profiles Nome da configuração J2ME suportada e sua versão A codificação default de caracteres suportada pelo aparelho Nome da plataforma ou dispositivo Perfis J2ME suportados CLDC-1.0 ISO8859_1 J2ME MIDP-1.0 Tabela 3. 1 - Propriedades do sistema • O valor de uma propriedade específica pode ser obtido usando o método getProperty() (ex: System.getProperty(microedition.profiles)). Visto que o package “java.util” do CLDC não inclui a classe “Properties”, a classe “system” não inclui o método “getProperties()”, não sendo assim possível obter uma lista de todas as propriedades disponíveis. Os fabricantes são livres de incluir propriedades específicas mas as aplicações não as conseguem definir, devido à ausência do método “setProprerty()”. Um dispositivo que suporte um ou mais perfis, deve inclui-los na propriedade “microedition.profiles” e estes definem as suas próprias propriedades automaticamente. Classes de sistema e de execução – As classes de execução e de sistema do J2SE fazem operações de mais baixo nível. Devido à natureza dependente de plataforma e às restrições impostas pela VM, algumas funcionalidades destas classes foram removidas, incluindo as seguintes: 33 Tecnologia Java aplicada a telemóveis o Acesso directo às propriedades do sistema usando os métodos “getProperties()”, "setProperty()” e “setProperties()”; o Métodos que permitam que o standard input, output e error sejam modificados; o Os métodos que permitem o acesso a librarias de código nativo foram removidas visto que o JNI não é suportado; o A habilidade para obter referências ou modificar o SecurityManager; • Threads – O CLDC permite programação multi-thread mesmo que a plataforma base não o permita. Todos os objectos base utilizados pelo J2SE para suportar threads, estão incluídos no CLDC. Contudo não são suportados grupos de threads e algumas funcionalidades da classe thread do J2SE foram omitidas: o Todos os métodos e construtores relacionados com ThreadGroups foram removidos; o Os métodos “getName()” e “setName()” não são suportados e, por isso, foram removidos; o Os métodos “resume()”, “suspend()” e “stop()” foram removidos; o Os métodos “destroy()”, “interrupt()” e “isInterrupted()” não existem; o O método “dumpStack()” foi removido; • Erros e excepções O CLDC suporta a maioria das excepções definidas pelo package “java.lang” do J2SE mas a maioria das classes respeitantes a erros foi removida, deixando apenas as seguintes: o “java.lang.Error”; o “java.lang.OutOfMemoryError”; o “java.lang.VirtualMachineError”; java.util O “package java.util” do CLDC contém classes relacionadas com colecções de objectos e com o tratamento de tempo e datas. • Classes de colecções – O CLDC contém as seguintes classes relacionadas com colecções de objectos: o “Hashtable”; o “Stack”; o “Enumeration”; o “Vector”; • Classe Data – Contrariando a complexidade do objecto Data do J2SE, aqui, “Data” é apenas um valor do tipo long que representa uma data e um tempo. Apenas tem construtores que permitem a criação do objecto Data, representando o tempo corrente ou um tempo especificado, um par de métodos que permitem a especificação e obtenção do tempo, e um método “equals()” que possibilita a comparação entre dois objectos do tipo Data. 34 Java • • Classe TimeZone – Esta classe especifica o tempo de uma determinada zona. No CLDC esta classe está muito mais restrita do que no J2SE, suportando apenas GMT e UTC (que, para todos os efeitos, é idêntico ao GMT). Classe Callendar – A classe Callendar do CLDC é uma versão simplificada da mesma classe do J2SE, cuja função principal é fazer a conversão de um tempo no formato Data no valor correspondente em termos de anos, meses, dias, horas, minutos e segundos, e viceversa. java.io O CLDC disponibiliza apenas uma versão muito limitada do extensivo package java.io do J2SE. As únicas fontes de input ou output que podem ser ligadas a uma fonte real de dados são ByteArrayInputStream e ByteArrayOutputStream. Estas fontes podem ser usadas pare ler de ou escrever para um array de bytes directamente, ou, quando incluídas num DataInputStream ou DataOutputStream servem para armazenamento ou transmissão de tipos de dados primitivos do Java. O acesso a outros tipos de dados é feito através de implementações privadas de InputStream e OutputStream que são obtidas com a invocação de métodos de outras classes. Os métodos openInputStream() e openOutputStream() são bons exemplos desta situação, pois fazem parte do interface StreamConnection que é utilizado para aceder a fontes de dados externas. O package java.io do CLDC também possibilita o input e output de caracteres, associando byte streams com um InputStreamReader ou OutputStreamReader. No entanto, o tipo de codificação de caracteres que pode ser usado com estas classes é dependente da implementação e é necessário que seja uma extensão da codificação do aparelho. Javax.microedition.io Este package, que não é herdado do J2SE, contém uma colecção de interfaces que definem o Generic Connection Framework que se destina a ser usado por perfis baseados em CLDC de forma a fornecer um mecanismo para acesso a recursos de rede e outros recursos que podem ser endereçáveis por nome e podem enviar ou receber dados via InputStream ou OutputStream. Um exemplo típico é uma página HTML ou um servlet Java que podem ser identificáveis pelo seu Uniform Resource Locator (URL). 35 Tecnologia Java aplicada a telemóveis 3.3.3 – O Mobile Information Device Profile e MIDlets O CLDC fornece a base para correr Java em dispositivos que não têm recursos suficientes para suportar uma Virtual Machine completa, com a versão completa dos packages do J2SE. No entanto, é extremamente improvável que um programador alguma vez necessite desenvolver uma aplicação baseada apenas nas APIs disponibilizadas pelo CLDC, visto que estas não contêm nada que permita interacção com utilizadores, armazenamento ou funcionalidades de rede. O CLDC foi desenhado de forma a servir como base em cima da qual um alargado leque de perfis pode assentar e disponibilizar as funcionalidades em falta, de acordo com a classe do dispositivo. O Mobile Information Device Profile (MIDP) é um perfil que se destina a ser utilizado com aparelhos que possuam um interface de utilizador limitado, na forma de um pequeno ecrã, e com alguma capacidade de input. Ao longo deste capítulo será feita uma introdução ao MIDP e serão analisadas algumas das suas características e funcionalidades. 3.3.3.1. MIDP O MIDP é uma versão da plataforma Java baseada no CLDC e na KVM, que se destina a aparelhos que disponham de poucos recursos, principalmente telemóveis. A especificação MIDP pode ser encontrada para download em http://jcp.org/jsr/detail/37.jsp. O MIDP enquadra-se na arquitectura de software de um dispositivo como é demonstrado no seguinte esquema. Figura 3. 7 - MIDP e MIDlets 36 Java O software responsável pela implementação do MIDP corre na KVM fornecida pelo CLDC, e disponibiliza serviços adicionais para benefício do código escrito usando APIs do MIDP. Estas aplicações serão denominadas “MIDlets”. Como é mostrado no esquema, as MIDlets podem ser usadas com MIDP, ou directamente com as APIs herdadas do CLDC. As MIDlets não têm acesso à plataforma do sistema operativo, e não o podem fazer sem prescindir da sua portabilidade. Como o JNI não é suportado pela KVM, a única maneira de ter acesso a código nativo da plataforma é através de uma Virtual Machine personalizada. A Sun disponibiliza uma implementação do MIDP que pode ser utilizada com o Windows, o Wireless Toolkit, que contém versões do MIDP para Windows, Solaris e Linux, e um MIDP específico para uso com PDAs baseados em Palm-OS. Normalmente os fabricantes utilizam a implementação da Sun como base para os seus produtos, e acrescentam código adicional para instalação, remoção e gestão de MIDlets que não são portáveis entre aparelhos distintos. Como demonstrado no esquema, o código OEM pode usar uma combinação de serviços MIDP e CLDC, dependendo também da plataforma do sistema. Também algumas partes nucleares do software MIDP são dependentes da plataforma e, por isso, fornecidos pelo fabricante. Normalmente estas partes contêm suporte de rede, componentes de interface de utilizador e código que permite armazenamento persistente. 3.3.3.2. Requisitos de hardware do MIDP Como referido anteriormente, o MIDP destina-se a ser utilizado por pequenos aparelhos com recursos de memória, CPU e display muito limitados. • Memória – O MIDP inclui muito software que não faz parte da base da plataforma Java e, por isso, requer mais memória do que o mínimo requisitado pelo CLDC. A especificação MIDP requer um mínimo de 128 KB de RAM para armazenamento da sua própria implementação, acima do necessário para o CLDC. Além disso são necessários mais 32 KB disponíveis para o heap do Java que, mesmo assim, se tornam muito limitativos e exigem que um programador tenha muito cuidado na alocação de objectos e tome as medidas possíveis para evitar guardar referências a objectos que já não são necessários, de forma a que o Garbage Collector recupere o espaço da heap o mais rápido possível. O MIDP requer também um mínimo de 8 KB de memória não volátil para ser usada como armazenamento persistente, de forma a que as MIDlets possam manter a informação mesmo que o aparelho seja desligado. Porém não é garantido que esta informação se mantenha no caso de mudanças de bateria. • Display – Os aparelhos MIDP são caracterizados por terem ecrãs muito pequenos. A especificação requer que um ecrã tenha no mínimo 96 pixels de largura e 54 pixels de altura, e que cada pixel seja aproximadamente quadrado. O ecrã deve suportar no mínimo duas cores (como a maioria dos telemóveis) e pode ir até 65.536 cores (no caso de alguns telemóveis topo de gama). 37 Tecnologia Java aplicada a telemóveis • Dispositivos de input – Embora o MIDP suporte diversos tipos de dispositivos de input, normalmente usados para PDAs, no caso da programação destinada a telemóveis é usado o input mínimo suportado pelo MIDP que permite a um utilizador escrever números de 0 a 9, utilizar setas e um botão de selecção, como demonstra a figura. Figura 3. 8 - Keypad normal de um telemóvel • Rede – O MIDP não assume que tenham acesso permanente a uma rede, ou que a rede suporte TCP/IP. No entanto, um fabricante deve incluir no aparelho, pelo menos, uma simulação de suporte de HTTP 1.1. 3.3.3.3. Requisitos de software do MIDP Como o MIDP não é um produto comercial, é esperado que os fabricantes adoptem esta implementação para o seu hardware e software, e desenvolvam código de forma a ligar as potencialidades do código da Sun com o hardware e software do sistema operativo. A implementação do MIDP faz as seguintes assunções acerca das características oferecidas pelo software base do sistema operativo: • O sistema operativo deve providenciar um ambiente protegido de execução no qual a VM pode correr; • É necessária alguma forma de suporte de rede. O fabricante deve disponibilizar algum meio de acesso a uma rede, via HTTP 1.1; 38 Java • • • O software deve permitir o acesso ao teclado (input) do sistema. O software deve ser capaz de reconhecer eventos relativos a quando uma tecla é pressionada ou solta. O fabricante deve mapear os códigos das teclas de forma a que se obtenham os mesmos resultados em plataformas de hardware diferentes. Deve ser possível o acesso ao ecrã do aparelho. O MIDP permite que as MIDlets tratem o ecrã como um array rectangular de pixels, a cada um dos quais deve poder ser atribuída independentemente uma das cores suportadas pelo aparelho. A plataforma deve providenciar uma qualquer forma de armazenamento persistente de dados, que não perca a informação quando o aparelho é desligado. Para isto, o MIDP permite o acesso ao nível de registo, sendo portanto necessário que o software anfitrião contenha um interface programático para o seu mecanismo de armazenamento persistente. 3.3.3.4. A plataforma MIDP Esta é a plataforma disponível para as MIDlets, fornecida pelo CLDC em conjunto com uma colecção de packages específicos para o MIDP, sob a hierarquia do package “javax.microedition”. As librarias base, quase não são afectadas pela especificação MIDP. A única alteração é a adição do timer do Java 1.3, ao package “java.util”. A especificação MIDP coloca os seguintes requisitos às librarias base: • Tal como acontece nos applets, as MIDlets são geridas num ambiente de execução ligeiramente diferente das aplicações. O ponto principal de entrada para uma MIDlet não é o método “main()” da classe “MIDlet”, e não é permitido à MIDlet terminar a execução da VM. De forma a aplicar esta restrição, os métodos “exit()” das classes de sistema e de execução, se invocados, devem lançar a excepção “SecurityException”; • Em adição às propriedades do sistema definidas pelo CLDC, os aparelhos MIDP devem conter a propriedade “microedition.locale” de modo a reflectir a região onde o aparelho está a operar. Os identificadores do locale estão formados de uma maneira ligeiramente diferente dos usados pelo J2SE: enquanto no J2SE a língua e o país estão separados por um underscore, no MIDP estão separados por um hífen. Esta informação não tem grande utilidade para as MIDlets em geral, e é utilizada principalmente para MIDlets externas, para que possa ser seleccionada a versão mais apropriada conforme a localização do aparelho. Esta informação será portanto interpretada por um agente externo (como um servlet a correr num browser) para este efeito; • A propriedade do sistema “microedition.profiles” deve conter pelo menos o valor “MIDP-1.0”. No futuro, à medida que novas especificações do MIDP forem lançadas (MIDP 2.0), os dispositivos que suportem diversos perfis devem lista-los a todos, separando os seus nomes com espaços; 39 Tecnologia Java aplicada a telemóveis 3.3.3.5. MIDlets e MIDlet suites Aplicações Java que corram em aparelhos MIDP, são conhecidas como MIDlets. Uma MIDlet consiste em pelo menos uma classe Java derivada da classe abstracta do MIDP “javax.microedition.midlet.MIDlet”. As MIDlets correm num ambiente de execução com uma Java VM que fornece ciclos de vida controlados e bem definidos via métodos da classe “MIDlet” que cada MIDlet deve implementar. Uma MIDlet pode também utilizar métodos da classe “MIDlet” para obter acesso a serviços do seu ambiente e, para manter a portabilidade, deve apenas usar APIs definidos na especificação do MIDP. Um conjunto de MIDlets relacionadas, pode ser agrupado numa MIDlet suite. Todas as MIDlets pertencentes a uma suite são incluídas num package e posteriormente instaladas num aparelho como uma entidade única, podendo apenas ser removidas também em conjunto. As MIDlets numa suite partilham os recursos estáticos e de execução do seu ambiente, da seguinte forma: • Em runtime, se um aparelho suporta concorrência entre MIDlets, todas as MIDlets de uma suite correm na mesma Java VM partilhando as mesmas instâncias das classes Java e outros recursos carregados na Java VM. Entre outras coisas, isto quer dizer que pode haver partilha de dados entre MIDlets e que as primitivas de sincronização do Java podem ser usadas para proteger não só acessos concorrentes de uma MIDlet, mas também execução concorrente de MIDlets da mesma suite. • O armazenamento persistente de dados nestes aparelhos é gerido pela MIDlet ao nível da suite. As MIDlets podem aceder aos seus próprios dados persistentes, bem como aos dados persistentes de MIDlets da mesma suite. No entanto não é possível a uma MIDlet obter acesso a dados persistentes pertencentes a MIDlets de outras suites, porque o mecanismo utilizado para identificação dos dados inclui implicitamente a MIDlet suite. Isto é em parte para evitar conflitos de nome entre MIDlets de fontes distintas e, por outro lado, é uma medida de segurança para que os dados de uma MIDlet não possam ser lidos ou corrompidos por código importado de uma fonte não segura. Como exemplo de partilha de classes e dados entre MIDlets, vamos supor que uma MIDlet suite contém uma classe chamada “Counter”, destinada a contar o número de instâncias de MIDlets daquela suite que se encontram a correr num dado momento. 40 Java Counter public class Counter { private static int instances; public static synchronized void increment (){ instances ++; } public static synchronized void decrement (){ instances --; } public static int getInstances(){ return instances; } } Apenas uma única instância da classe será carregada na Java VM, independentemente da quantidade de MIDlets daquela suite que estão a correr na VM. Isto quer dizer que a mesma variável estática instances é usada para todas as MIDlets e, consequentemente, os métodos increment e decrement afectam o mesmo contador. O facto destes métodos estarem sincronizados protege a variável instances de acessos concorrentes por quaisquer threads em todas as MIDlets. 3.3.3.6. Segurança nas MIDlets Para o programador, é extremamente simples lidar com a segurança nas MIDlets, pelo simples facto de não haver praticamente nenhuma! O modelo de segurança usado no J2SE é poderoso e flexível mas muito dispendioso em termos de recursos de memória e requer uma certa quantidade de funcionalidades administrativas que estão muito para além do esperado, quando se fala em telemóveis. Devido a isto, nem o CLDC nem o MIDP incluem qualquer verificação de segurança nas chamadas aos APIs com a excepção dos métodos de “Runtime” e “System exit” que, por sua vez, não podem ser utilizados por uma MIDlet. Para um normal utilizador, isto pode querer dizer que uma MIDlet é mais insegura para o telemóvel do que uma applet para o browser, visto que a MIDlet não está constrangida ao mesmo ambiente limitado de programação imposto pelo browser a uma applet através do “SecurityManager”. Um utilizador deste tipo de aparelho, deve ter cuidado ao instalar MIDlets e, de preferência, deve aceitar software vindo apenas de fontes confiáveis. Infelizmente até há muito pouco tempo não havia maneira se saber ao certo quem está a fornecer a MIDlet ou se a MIDlet não foi corrompida durante a transferência. Mecanismos de autenticação que disponibilizam estas funcionalidades no J2SE (como chaves criptográficas ou certificados), fazem apenas parte da especificação MIDP 2.0. 41 Tecnologia Java aplicada a telemóveis A alternativa segura do protocolo HTTP (HTTPS) que poderá ajudar a aliviar este problema, está também incluída na versão 2.0 do MIDP, mas enquanto isso não acontecia, a segurança nas MIDlets ficava muito limitada. O facto de não ser permitido à API das MIDlets aceder a informação pessoal do telemóvel (como listas de telefone ou agenda) e não ser possível à MIDlet controlar directamente o aparelho, faz com que o problema da segurança seja um pouco menos preocupante. 3.3.3.7. MIDlet packaging Antes de instalados no aparelho, as MIDlets devem ser acomodadas em “pacotes” de informação, numa operação designada aqui por packaging. A subclasse “MIDlet” que funciona como ponto de entrada para a MIDlet assim como quaisquer outras classes necessárias (à excepção das classes do MIDP), imagens e outros ficheiros acedidos em tempo de execução, devem ser inseridos num único ficheiro JAR. A informação do packaging que informa o aparelho acerca do conteúdo do ficheiro JAR deve estar contida no ficheiro de manifesto do JAR. Informação muito similar a esta deve também estar contida num ficheiro denominado Java Aplication Descriptor (JAD) que é independente do JAR. Um ficheiro JAR pode conter mais do que uma MIDlet mas, neste caso, as MIDlets devem pertencer à mesma suite, por outras palavras, todas as MIDlets pertencentes à mesma suite devem ser acondicionadas no mesmo ficheiro JAR. Tanto o ficheiro de manifesto do JAR como o JAD, são ficheiros de texto simples que, em cada linha, têm informação do tipo: nome_do_atributo: valor_do_atributo O valor_do_atributo é separado do nome_do_atributo por dois pontos e, opcionalmente, por um espaço. Todos os atributos que têm alguma relevância para a instalação das MIDlets, devem ter nomes com o prefixo “MIDlet-”. Seguidamente irá ser mostrada uma lista de todos estes atributos, assim como uma breve descrição. Os valores das colunas JAR e JAD indicam se o atributo associado é obrigatório (O), facultativo (F) ou ignorado (I). 42 Java Nome do atributo JAR JAD MIDlet-Name O O MIDlet-Version O O MIDlet-Vendor O O MIDlet-n O I MicroEditionProfile O I MicroEditionConfiguration O I MIDletDescription F F MIDlet-Icon F F MIDlet-Info-URL F F MIDlet-Data-Size F F MIDlet-JAR-URL I O MIDlet-JAR-Size I O MIDlet-InstallNotify I F MIDlet-DeleteConfirm I F MIDlet-SpecificAttributes F F Valor e significado O nome da MIDlet suite contida no ficheiro JAR. Esta informação pode ser visualizada pelo utilizador. A versão da MIDlet suite contida no JAR, na forma 1.2.3 O nome de quem forneceu a MIDlet suite. Este atributo está sob a forma de texto e serve para visualização do utilizador. Atributos que descrevem as MIDlets da MIDlet suite. O n é substituído por um valor numérico a começar em 1 para identificar individualmente as MIDlets. A versão ou versões da especificação MIDP suportadas pelas MIDlets contidas na MIDlet suite. As versões são comparadas com as listadas na propriedade microedition.profiles do aparelho, para determinar a compatibilidade. A configuração J2ME necessária para as MIDlets desta suite. Este valor é comparado com a propriedade microedition.configuration do aparelho, para determinar a compatibilidade. A descrição da MIDlet suite para ser mostrada ao utilizador. Um ícone que pode ser usado para representar a MIDlet suite durante ou após a instalação. Este ícone deve ser um ficheiro do tipo PNG (Portable Network Graphics). O URL de um ficheiro que contenha informação adicional da MIDlet suite. O valor mínimo de memória de armazenamento persistente necessária para esta MIDlet suite. Este valor está especificado em bytes e refere-se ao espaço para dados usados pela MIDlet suite, e não para a sua instalação e gestão. Se não for dado nenhum valor, é assumido que a MIDlet suite não necessita de nenhum espaço persistente para dados. O URL do ficheiro JAR que contém a MIDlet ou MIDlet suite descrita por estes atributos. O tamanho do ficheiro JAR em bytes. O URL usado para assinalar o sucesso ou falha da instalação de uma MIDlet, feita a partir de um servidor remoto. A mensagem que aparecerá ao utilizador antes de uma MIDlet ser apagada do aparelho onde foi instalada. Os programadores podem limitar a configuração das MIDlets, incluindo atributos que podem ser recolhidos em tempo de execução. Tabela 3. 2 - Atributos do MIDlet packaging 43 Tecnologia Java aplicada a telemóveis Como pode ser observado, a maior parte destes atributos deve estar contida no ficheiro de manifesto que pertencente ao ficheiro JAR, e no ficheiro JAD, que é independente. Para se perceber a razão disto, convém perceber a razão da utilização destes dois ficheiros. O ficheiro de manifesto serve para indicar o nome e a versão da MIDlet suite ao aparelho, e especificar quais dos ficheiros class correspondem a MIDlets individuais. No entanto, para aceder a esta informação, o aparelho tem que obter o ficheiro JAR, extrair o manifesto e, só depois disto, pode obter os seus atributos. A informação obtida serve para o utilizador decidir se quer ou não instalar a MIDlet. Mas o ficheiro JAR que contém a MIDlet suite pode ser grande e demorar algum tempo a ser transferido numa rede lenta à qual normalmente os telemóveis têm acesso. Se apenas a informação relativa ao manifesto fosse transferida, iria ser poupado muito tempo na transferência. Para resolver esta questão, muita da informação contida no manifesto do ficheiro JAR, assim como alguma informação extra, foram duplicadas para o ficheiro JAD. Deste modo, em vez de ser transferido todo o ficheiro JAR, o MIDP primeiro vai buscar o ficheiro JAD que é muito mais pequeno e pode ser transferido rapidamente. É então mostrado o conteúdo do ficheiro ao utilizador que então decide se quer ou não descarregar o ficheiro JAR associado. De modo a ser completamente portável, um ficheiro JAD deve ser codificado usando o ISO-8859-1, pois todas as implementações do MIDP devem suportar este tipo de codificação de caracteres. Em execução uma MIDlet pode aceder a ficheiros do JAR usando o método “getResourcesAsStream()” do “java.lang.Class”. Qualquer ficheiro do JAR à excepção dos ficheiros class pode ser acedido desta forma. 3.3.3.8. Ciclo de vida e ambiente de execução das MIDlets Todas as MIDlets são derivadas de da classe abstracta base “javax.microedition.midlet.MIDlet”, que contém métodos chamados pela plataforma MIDP para controlar o ciclo de vida das MIDlets, assim como métodos utilizados pela própria MIDlet para alterar o seu estado. Uma MIDlet tem que ter um construtor público que não necessite de argumentos, e que pode ser criado pelo programador caso haja necessidade de efectuar alguma inicialização ou, quando não existe nenhum construtor explícito, um construtor vazio é criado automaticamente pelo compilador Java. Uma classe MIDlet pode ter por base este aspecto: 44 Java Classe MyMIDlet public class MyMidlet extends MIDlet { // constructor opcional MyMIDlet(){ } protected void startApp() throws MIDletStateChangedException{ } protected void pauseApp(){ } protected void destroyApp(Boolean unconditional) throws MIDletStateChangedException{ } } A qualquer altura uma MIDlet pode-se encontrar num dos seguintes três estados: parado, activo ou destruído. A figura seguinte demonstra como estes três estados se relacionam entre si. Figura 3. 9 - Ciclo de vida de uma MIDlet 45 Tecnologia Java aplicada a telemóveis Quando uma MIDlet é carregada, fica inicialmente parada e é nesta altura que são feitas as inicializações das suas classes e instâncias. Se é lançada alguma excepção pela MIDlet durante a execução do seu construtor, a MIDlet é destruída, terminando assim a sua execução. Caso contrário, a MIDlet poderá ser executada mais tarde. O seu estado muda de paused para active (activo) e é chamado o método “startApp()”. Este método é declarado do seguinte modo: protected void startApp()throws MIDletStateChangeException O facto deste método ser abstracto, quer dizer que tem que ser implementado na MIDlet, e o facto de ser protected implica que possa apenas ser chamado a partir da própria classe MIDlet ou de outras classes do package “javax.microedition.midlet”. Na implementação, os métodos referentes ao ciclo de vida da MIDlet são chamados a partir de uma classe deste package denominada “Scheduler”, mas não há nada na especificação do MIDP que obrigue ao uso desta classe. É muito usual os programadores de MIDlets redefinirem o método “startApp()” como público, que é uma opção segura mas desnecessária pois as implementações do fabricante devem continuar a funcionar mesmo que sejam métodos declarados como protected. O método “startApp()” pode iniciar com sucesso, permitindo assim que a MIDlet possa correr, ou pode informar a plataforma MIDP de que a MIDlet não será corrida a este ponto, o que pode ser causado pelos seguintes motivos: • Se o método “startApp()” detecta uma condição de erro que o impede de compilar, mas que pode mais tarde deixar de existir, deve ser lançada a excepção “MIDletStateChangeException”. Esta acção coloca a MIDP no estado parado para que possa mais tarde ser feita uma nova tentativa para recomeçar; • Se o método “startApp()” detecta uma condição de erro cuja recuperação seja improvável, deve ser chamado o método “notifyDestroyed()”; • Por fim, a MIDlet pode lançar uma excepção diferente de “MIDletStateChangeException” deliberadamente, porque foi lançada por um método invocado, e o método “startApp()” não a apanha. Neste caso é assumido que ocorreu um erro fatal e a MIDlet é destruída, com a invocação do método “destroyApp()”; Se não ocorrer nenhum destes casos, a MIDlet encontrar-se-á no estado activo e irá correr até que seja parada ou destruída. Depois de completado o método “StartApp()”, a MIDlet retorna e não existe nenhum método ao qual possa ser passado o controlo da aplicação. Normalmente a MIDlet tem um interface de utilizador que executa código como resultado de eventos gerados pelas teclas do aparelho. As MIDlets podem também iniciar threads em background para correr código que não dependa do interface de utilizador, ou podem utilizar um temporizador (timer) para executar tarefas periodicamente. Caso seja utilizado algum destes métodos, é importante uma gestão adequada dos threads de background ou temporizador, quando a MIDlet é parada ou destruída. 46 Java A qualquer altura, a plataforma MIDP pode parar a MIDlet. Num telemóvel isto pode acontecer quando é detectada uma chamada e o ecrã tem que ser libertado para que a chamada possa ser atendida. Para parar uma MIDlet é chamado o método “pauseApp()”: protected abstract void pauseApp(); Tal como acontece com o “startApp()”, o MIDP tem que ter uma implementação para este método. A acção apropriada para a mudança deste estado depende da própria MIDlet mas, geralmente, são libertados todos os recursos e guardado o seu estado corrente para que mais tarde, quando reactivada a MIDlet, o seu estado possa ser carregado. As principais consequências da passagem ao estado parado, é que a MIDlet deixa de ter acesso ao ecrã, os threads criados não são terminados e os temporizadores continuam activos. A MIDlet pode optar por terminar threads ou temporizadores quando parada, mas não é obrigada a isso. Se a plataforma decide reactivar uma MIDlet parada, depois de acabada uma chamada por exemplo, o método “startApp()” é invocado novamente para indicar à MIDlet que esta recuperou o acesso ao ecrã. Por isso, o método “startApp()” deve ser cuidadosamente programado e, se for caso disso, deve mesmo ser distinguida a primeira vez que é corrida a MIDlet das outras chamadas ao método (quando a MIDlet está simplesmente parada), de forma a evitar que os mesmos recursos sejam alocados várias vezes. Claro que isso depende da maneira como foi escrita a MIDlet. Se de cada vez que for parada, a MIDlet libertar todos os seus recursos, é necessário que estes sejam novamente alocados tal como da primeira vez, quando a MIDlet for reiniciada. No entanto, uma MIDlet bem programada irá retomar ao seu estado anterior, em vez de voltar a mostrar o seu ecrã inicial. O facto do método “startApp()” poder ser chamado mais do que uma vez durante o ciclo de vida de uma MIDlet levanta a questão da inicialização ser feita no método ou no construtor. Neste caso, o programador é livre de escolher o local que achar mais indicado para alocar os recursos e preparar o estado da MIDlet. No geral, os recursos libertados no “pauseApp()” devem ser alocados no “startApp()”. Outros recursos podem ser alocados quer no “startApp()” quer no construtor, tendo em atenção que os recursos alocados no “startApp()” não devem ser novamente alocados no ciclo de vida da MIDlet. Uma diferença importante entre o método “startApp()” e o construtor é que, segundo a especificação MIDP, a MIDlet só tem garantido o acesso ao objecto “Display”, que corresponde ao ecrã, a partir do momento em que o “startApp()” é invocado pela primeira vez. Tendo em atenção o que é referido na especificação, qualquer inicialização que envolva objectos do “Display”, não pode ser efectuada no construtor. Uma MIDlet pode recusar a passagem do seu estado parado para activo, lançando a excepção “MIDletStateChangeException” quando o método “startApp()” é chamado. 47 Tecnologia Java aplicada a telemóveis Quando a plataforma quer terminar a MIDlet, chama o método “destroyApp()”: public abstract void destroyApp(boolean unconditional) throws MIDletStateChangeException; No método “destroyApp()”, a MIDlet deve libertar todos os recursos alocados, terminar threads que estejam a correr em background e parar os temporizadores activos. Quando uma MIDlet termina deste modo, o argumento “unconditional” tem o valor true para indicar que a MIDlet não pode impedir a continuação deste processo. Em algumas circunstâncias, pode ser útil dar a opção de não terminar o processo à MIDlet, por exemplo, por causa de dados que ainda não foram guardados. Neste caso, o método “destroyApp()” pode ser invocado com o argumento false, e assim a MIDlet pode indicar se quer continuar, lançando a excepção “MIDletStateChangeException”. O código apresentado a seguir, demonstra como esta técnica pode ser implementada: MIDlet destroy try{ // Chama o destroyApp para libertar os recursos destroyApp(false); // Tenta destruir a MIDlet notifyDestroyed(); }catch(MIDletStateChangeException ex){ // A MIDlet não quer fechar } Este código pode ser usado para responder a um botão de saída no interface de utilizador da MIDlet. Logo de início é invocado o método "destroyApp()” da MIDlet directamente, para que os recursos sejam libertados. Se a MIDlet não se encontra num estado apropriado para terminar e é chamado o “destroyApp()” com o argumento false, deve ser lançada a excepção “MIDletStateChangeException”. O código deve então apanhar a excepção lançada e não fazer nada. Por outro lado, se a MIDlet está preparada para terminar, deve prosseguir com o método “destroyApp()” normalmente, sendo então chamado o método “notifyDestroyed()” da MIDlet que diz à plataforma MIDP que a MIDlet quer terminar. Este exemplo também ilustra o uso do método “notifyDestroyed()” que é utilizado por uma MIDlet para terminar voluntariamente. È importante perceber o relacionamento entre os métodos “destroyApp()” e “notifyDestroyed()” e quando são usados: 48 Java • • Quando a MIDlet está a ser terminada pela plataforma, muito provavelmente a pedido do utilizador, o método “destroyApp()” é chamado com o argumento true e a MIDlet é destruída quando o método acaba a sua execução. Neste caso não é necessário que a MIDlet invoque o método ”notifyDestroyed()”; Quando a própria MIDlet quer terminar, normalmente porque finalizou a sua execução ou porque o utilizador premiu uma tecla de saída, tem que invocar o método ”notifyDestroyed()” que indica à plataforma que a MIDlet deve ser destruída. Neste caso a plataforma não chama o método ”destroyApp()” da MIDlet, assumindo que essa MIDlet já está preparada para ser terminada. A maioria das MIDlets chama o seu próprio método ”destroyApp()” para fazer uma limpeza antes da invocação do ”notifyDestroyed()”. Note-se que chamar o ”notifyDestroyed()” é a única maneira de uma MIDlet terminar voluntariamente. As MIDlets não conseguem terminar invocando métodos de saída do sistema ou de execução, pois será lançada uma excepção de segurança (SecurityException). Existem mais dois métodos que podem ser usados pela MIDlet de forma a influenciar o seu ciclo de vida: public final void notifyPaused(); public final void resumeRequest(); O método ”notifyPaused()” informa a plataforma que a MIDlet deseja transitar para o estado parado. Isto tem o mesmo efeito da invocação do método ”pauseApp()” pela plataforma. Quando a MIDlet chama ”notifyPaused()”, a plataforma não invoca o método ”pauseApp()”, da mesma forma que também não chama o método ”destroyApp()” em resposta ao ”notifyDestroyed()”, porque assume que a MIDlet já se preparou para ser parada. Normalmente a MIDlet precede a invocação do ”notifyPaused()” com uma chamada ao ”pauseApp()” para que sejam tomadas as medidas apropriadas à paragem. O método ”resumeRequest()” é o contrário do ”notifyPaused()”. Este método informa a plataforma de que a MIDlet parada deseja retornar ao seu estado activo. Posteriormente a plataforma pode retomar ao seu estado activo, chamando o método ”startApp()”. O método ”resumeRequest()” é tipicamente chamado por um thread em background ou por um temporizador que fica activo enquanto a MIDlet está parada. 49 Tecnologia Java aplicada a telemóveis 50 4. Alternativas ao J2ME Já muito se falou acerca do mercado dos telemóveis e das aplicações desenvolvidas para esta plataforma, assim como das tecnologias inerentes a esta programação. Até agora foi abordado o Java como a tecnologia principal no que toca a desenvolvimento de aplicações para pequenas plataformas móveis. No entanto, e como pode ser observado no segundo capítulo deste documento, existem também outras tecnologias suportadas por telemóveis e usadas por programadores para desenvolver aplicações robustas e fiáveis, tirando o melhor partido das vantagens que cada linguagem tem para oferecer. Embora já tenham sido referidas muitas das potencialidades do Java, é preciso ter em atenção que grande maioria das aplicações desenvolvidas para telemóveis são jogos e, o Java, não foi originalmente desenvolvido para este tipo específico de aplicações. Quando comparado com algumas plataformas específicas para jogos, a versão 1.0 do MIDP demonstra ter algumas limitações o que torna muito difícil a programação de jogos tecnicamente mais desenvolvidos. O lançamento da versão 2.0 do MIDP veio alterar este cenário aumentando significativamente a potencialidade do J2ME para este tipo de aplicações. O MIDP 2.0 fornece: • Novas funcionalidades ao nível do interface de utilizador como o controlo do tamanho e layout do ecrã; • Um melhor suporte de multimédia permitindo ao programador sequências audio no formato WAV e sequências de vídeo; • Uma API específica para o desenvolvimento de jogos que simplifica a programação e permite um melhor controlo a nível gráfico e de performance; • Conectividade expandida, com o suporte de HTTPS, datagramas, sockets e comunicação por porta paralela; • Uma arquitectura push que permite que as MIDlets possam ser registadas antes de activadas, quando um aparelho recebe informação do servidor; • A funcionalidade Over-The-Air (OTA) que permite controlar a instalação, remoção ou actualização dinâmica de aplicações no telemóvel; • Um modelo de segurança robusto que protege a rede, as aplicações e a informação do telemóvel; O MIDP veio assim equilibrar os pratos da balança que começavam a pesar mais para o lado de outras tecnologias, desenvolvidas objectivamente para o desenvolvimento de jogos. Mais informações acerca do MIDP 2.0, podem ser encontradas em http://java.sun.com/products/midp/. Neste capítulo irá ser feita uma pequena abordagem a outras tecnologias existentes no mercado, vocacionadas para este tipo de programação. Tecnologia Java aplicada a telemóveis 4.1. Execution Engine (ExEn) O Execution Engine (também conhecido como ExEn), foi desenvolvido pela In-Fusio para combater as limitações impostas pelo MIDP 1.0 do J2ME, no desenvolvimento de jogos. Inicialmente, a In-Fusio tentou ultrapassar essas limitações, trabalhando em conjunto com a SUN, chegando mesmo a apresentar propostas para uma API específica para jogos, para ser incluída no MIDP 2.0. O ExEn é uma linguagem simples, poderosa e está-se a tornar bastante popular para os programadores de jogos. Visto que o ExEn é baseado em Java, nota-se cada vez mais uma aproximação entre o ExEn e o J2ME, aliás, a versão 2 do ExEn, estará em conformidade com o MIDP e CLDC do Java, em questões como interface de utilizador, armazenamento persistente, rede e modelo de aplicação. A In-Fusio promete até que, num futuro próximo, haverá compatibilidade entre o ExEn e a API de jogos do MIDP 2.0. Este motor, assenta também no conceito de Virtual Machine e, neste campo, existem algumas Figura 4. 1 - Sagem myG-5 com suporte ExEn melhorias. Esta VM consegue ser até 30 vezes mais rápida do que uma VM genérica, e necessita de muito pouca memória. Apesar disto, em termos de gráficos e processamento, o ExEn fica um pouco aquém das potencialidades de algumas outras tecnologias existentes. Uma razão importante pela qual muitos programadores escolhem ExEn para programar jogos, é o seu modelo de negócio. Este modelo está dividido em dois níveis: standard e premium. No nível standard (livre de encargos), está incluído o SDK, um emulador, suporte técnico on-line e, mais tarde, a possibilidade de uma transição para o nível premium. Os programadores que atingem este nível passam a ter os seus jogos comercializados pela In-Fusio que os promove directamente nas operadoras que possuem telemóveis que suportam esta tecnologia. As perspectivas de crescimento do Execution Engine são bastante boas. O modelo de negócio muito atractivo para programadores independentes, e o lançamento do ExEn versão 2 com melhorias a nível tecnológico vão motivar o desenvolvimento de jogos para esta plataforma. Em termos de suporte, embora não dê sequer para comparar com o J2SE, o ExEn não está assim tão mau e vão aparecendo cada vez mais telemóveis que suportam este motor. Espera-se que, com a compatibilidade com o MIDP 2.0, o ExEn aumente a sua popularidade. Todas as informações acerca do ExEn, assim como alguns jogos, podem ser encontrados em http://www.in-fusio.com . 52 Alternativas ao J2ME 4.2. Mophun O Mophun é descrito pelos seus criadores da Synergix como uma “consola de jogos baseada em software”. Embora o desenvolvimento desta plataforma tenha começado no final de 1999, a sua implantação no mercado só se fez notar em novembro de 2002. A sua implementação tardia, aliada ao facto de só existirem três aparelhos que suportam esta tecnologia (Sony Ericsson T300, T310 e T610), levou a que muitos programadores desistissem da ideia de desenvolver aplicações para Mophun. Também as previsões de mercado um pouco irrealistas feitas pelos próprios criadores do Mophun, que punham esta tecnologia a competir na Europa directamente com o líder de mercado (J2ME) em 2003, deram a sugestão de que algo estava mal com esta plataforma e assustaram as operadoras e fabricantes de telemóveis. Tecnicamente falando, o Mophun é muito bom. Testes efectuados por organizações independentes demonstram que o Mophun chega a ter uma performance até 150 vezes maior em comparação com o J2ME. A Figura 4. 2 - Sony Ericsson Synergix acrescenta também que em alguns aparelhos, T610 com suporte Mophun parte do código da VM é traduzido directamente para código nativo, sendo possível atingir até 90% da capacidade total do aparelho. Outras características técnicas são muito similares ás apresentadas pelo ExEn. Tal como acontece com o J2ME e o ExEn, o Mophun é distribuído livremente. Em alguns aspectos, o modelo de negócio apresentado pela Synergix é parecido com o da In-Fusio: depois de desenvolvido, o jogo é certificado, distribuído e comercializado pela Synergix. No entanto, o facto do mercado não ser muito alargado leva a que muitos programadores optem por uma plataforma teoricamente mais fraca mas mais apelativa, como é o caso do ExEn. O futuro do Mophun é ainda incerto. Só agora é que a Synergix está a conseguir arranjar mais suporte para a sua plataforma. O recente lançamento de um motor 3D para jogos Mophun baseado no sistema operativo Symbian vai alargar em muito o suporte desta tecnologia (para alguns telemóveis Nokia incluindo o N-Gage) e é um ponto a favor que irá influenciar positivamente o seu desenvolvimento. Note-se também que a Synergix lançou recentemente uma versão beta de uma API destinada ao desenvolvimento de jogos em 3D (Mophun 3D) que também traz algumas melhorias a nível sonoro (inclusão do formato WAV) e das librarias 2D. Os aspectos tecnológicos desta plataforma são bastante bons e podem tornar o Mophun num líder de mercado. Agora, tudo depende do seu suporte, aceitação por parte dos programadores e evolução da concorrência (MIDP 2.0, ExEn 2, ...). Outras informações sobre esta plataforma podem ser obtidas em http://www.mophun.com. 53 Tecnologia Java aplicada a telemóveis 4.3. Wireless Graphics Engine (WGE) O WGE é a solução lançada pela TTPCom. Embora inicialmente, o WGE fosse apontado como o principal candidato à liderança de mercado no que diz respeito a plataformas de programação para jogos, a falta de suporte por parte dos programadores e fabricantes de telemóveis afectou em muito estas previsões. O WGE é um motor de jogos desenhado para servir de base a aplicações em C++ e Java. O WGE não contém uma Virtual Machine e executa o código compilado. Assim sendo, os jogos e aplicações correm mais rápido e requerem menos memória. O WGE também disponibiliza métodos seguros para executar e descarregar aplicações. É impossível negar que o WGE, de um ponto de vista puramente tecnológico, tem tudo para ganhar. Embora seja um pouco mais lento do que o Mophun, o WGE, entre outras coisas, possui APIs que tornam a programação 2D e 3D muito mais simples (já com funcionalidades pré-desenvolvidas, como detecção de colisões), permite um acesso simplificado a funções de rede e garante um bom suporte sonoro. Tal como acontece com os seus concorrentes directos, o download do SDK é livre de encargos, e o modelo de negocio da TTPCom tenta atrair os programadores, Figura 4. 3 - Innostream ajudando na venda e distribuição dos jogos. I-1000 com suporte Infelizmente, a falta de suporte por parte dos WGE principais fabricantes de telemóveis, acabou por limitar o sucesso do WGE. Uma grande parte das grandes software houses evitou esta plataforma, o que levou a que pequenas empresas e programadores individuais acabassem por seguir o mesmo caminho. O resultado está à vista: existem apenas pouco mais de 30 jogos disponíveis (o que não é praticamente nada, comparando com uns milhares de jogos disponíveis para J2ME), e muito poucos telemóveis a suportar WGE (para já, apenas 1....). Embora por um lado, a falta de interesse das grandes empresas seja benéfica para os pequenos programadores, fazendo com que um bom jogo seja mais facilmente aceite no mercado, por outro lado, existe um número muito reduzido de consumidores, o que irá diminuir os lucros resultantes da comercialização de jogos. Considerando a forte competição e a fragmentação de mercado que se tem vindo a observar, se a TTPCom não conseguir atrair algumas software houses, vai ser muito difícil obter o apoio dos principais fabricantes de telemóveis. Mas sem o apoio dos fabricantes, também não se consegue atrair software houses... Se a TTPCom não conseguir quebrar este ciclo num futuro próximo, pode-se adivinhar o fim desta plataforma que até demonstra ter algumas potencialidades. O site onde podem ser obtidas todas as informações acerca do WGE é o http://www.9dots.net/index.html. 54 Alternativas ao J2ME 4.4. Binary Runtime Environment for Wireless (BREW) Esta é a proposta da Qualcomm como sistema para o desenvolvimento de aplicações para telemóveis. O BREW é uma plataforma de execução de aplicações, que podem ser desenvolvidas em Java, C, C++, XML, Flash, etc., e que demonstra ser muito versátil não só para jogos, mas também para outros tipos de aplicações. Esta plataforma é mais rápida em comparação com o J2ME, pois não utiliza o conceito de Virtual Machine, correndo ao nível do firmware, apoiada no chipset CDMA (Code Division Multiple Access), também desenvolvido pela Qualcomm. Por outro lado, existe uma limitação de portabilidade, causada pela dependência do CDMA. O BREW fica dependente deste chipset e, assim sendo, é mais difícil alargar esta tecnologia a novos telemóveis. Também a distribuição de programas do BREW é um pouco diferente do habitual. O BDS (BREW Distribuition System) permite que os utilizadores descarreguem aplicações BREW para os seus telemóveis. É através deste sistema que são tratados todos os assuntos relativos à distribuição e cobrança, assim como pagamentos a programadores. No Figura 4. 4 - Samsung SCH-A530 com entanto, todas as aplicações BREW têm que ser certificadas suporte BREW pela Qualcomm, antes de descarregadas para um telemóvel. Se por um lado, esta certificação serve para garantir a segurança para o utilizador e, ao mesmo tempo, assegurar o reconhecimento dos programadores, por outro lado alguns programadores podem ver este sistema como um entrave à distribuição livre de aplicações. Apesar das vantagens a nível tecnológico apresentadas pelo BREW, esta tecnologia possui algumas limitações de memória que se podem revelar bastante problemáticas. A ausência de um Garbage Collector para gestão de memória vai agravar esta situação. Além disso, nota-se ainda alguma falta de documentação para os programadores que optam por desenvolver aplicações para esta plataforma. O BREW e o J2ME são parecidos em muitos aspectos, e talvez por isso, e para aumentar a popularidade do BREW, a Qualcomm lançou uma implementação da Virtual Machine do J2ME. Deste modo, embora com alguns requisitos extra de memória e processamento, torna-se possível correr aplicações J2ME sobre BREW. Esta tecnologia, embora não tenha a popularidade doutras plataformas, tem já alguns seguidores e um número razoável de suporte quer ao nível de software, quer a nível fabricantes de telemóveis, e o lançamento da VM para o J2ME de certo que será mais uma vantagem. Qualquer informação acerca do BREW, pode ser encontrada no site oficial da Qualcomm: http://www.qualcomm.com/brew. 55 Tecnologia Java aplicada a telemóveis 4.5. Symbian OS O Symbian OS é um sistema operativo destinado a plataformas móveis mais avançadas e, no caso dos telemóveis, só os modelos topo de gama que possuem mais capacidade de memória e processamento é que contêm Symbian. Embora a linguagem nativa do Symbian seja o C++, esta plataforma também suporta Java e Visual Basic. A grande vantagem do Symbian é a capacidade de desenvolvimento de aplicações mais complexas, tirando partido de sistemas tecnologicamente mais avançados. O Symbian permite ao programador um controlo total do telemóvel, pois tem acesso ao código nativo da máquina. Deste modo, é possível utilizar directamente uma câmara digital incorporada, bluetooth, infra vermelhos, ou até mesmo fazer chamadas telefónicas. Isto pode ser muito atractivo para os programadores mas, existem também algumas questões ao nível da segurança. Ao contrario do que acontece com o J2ME, no Symbian não existe um ambiente isolado para execução de Figura 4. 5 - Nokia aplicações e, por isso mesmo, uma aplicação vinda de uma 3650 com Symbian OS v6.1 fonte não segura, pode maliciosamente danificar o aparelho, interferindo com a sua memória, espaço de armazenamento ou dispositivos associados. Outra desvantagem é a questão da portabilidade. Devido ao facto de ser possível o acesso a funcionalidades específicas do hardware do telemóvel e à grande diversidade das tecnologias móveis existentes, é muito comum ser necessário reprogramar algumas partes do sistema operativo Symbian para que este possa funcionar correctamente noutros aparelhos. Embora com mais capacidades e mais rápida, a linguagem C++ torna-se mais difícil de programar do que o Java. As aplicações para esta plataforma, tendem a ser maiores, necessitar de mais memória e poder de processamento, e demoram mais tempo a ser desenvolvidas. No caso particular do Symbian, as aplicações devem ter uma especial atenção à gestão de memória para que sejam mais robustas e fiáveis. Também o custo associado ao desenvolvimento destas aplicações tende a ser mais elevado. Existe já um número razoável de telemóveis com suporte Symbian, alguns dos quais, de fabricantes bastante conceituados, como é o caso da Nokia (3650, 7650, ...). Uma grande parte dos telemóveis com suporte Symbian, também suporta J2ME. Usualmente, as aplicações desenvolvidas para Symbian são aplicações que necessitam de mais poder de processamento e memória, o que dificulta a sua programação em J2ME (aplicações em 3D, por exemplo). O Symbian está actualmente em crescimento e terá certamente uma crescente importância com a evolução tecnológica que se tem vindo a notar. A sua inclusão em telemóveis como o N-Gage da Nokia, revela o seu estatuto de “linguagem com potencial” visto que os jogos comercializados em cartucho para esta consola, serão programados em C++. O site oficial é http://www.symbian.com. 56 Alternativas ao J2ME Estas são algumas das alternativas ao J2ME existentes actualmente no mercado. Pode-se prever que, num futuro próximo, mais plataformas destinadas aos telefones móveis aparecerão no mercado, lançadas por grandes empresas. Mesmo a Microsoft prometeu já entrar na corrida com o seu Stinger, destinado possivelmente à gama mais alta de telemóveis. Neste já grande mercado dos telemóveis, é preciso ter em atenção o tipo de aplicações que têm maior importância – Jogos. Uma boa plataforma de programação de aplicações para este tipo de aparelhos, tem que ter um bom suporte para Jogos, visto que a grande maioria dos programadores se interessa mais por esse tipo de aplicações e, ao mesmo tempo, os consumidores querem passar o seu tempo livre a jogar. Os jogos são por isso aplicações mais vendáveis e, consequentemente, de grande importância actualmente. Outro ponto de grande importância é o suporte disponível para as plataformas existentes. Existem muito boas plataformas no mercado que , por uma ou por outra razão, não tiveram o suporte dos programadores ou dos fabricantes (veja-se o caso do WGE) e, só por causa disso, podem não ter o sucesso merecido. Nesta guerra das plataformas para telemóveis, o J2ME vai muito à frente, principalmente por causa do elevado número de telemóveis que suportam esta tecnologia e enorme quantidade de software (jogos) existentes para download. Os programadores tendem a escolher uma plataforma que, embora mais fraca do que algumas outras concorrentes, tem um suporte muito mais elevado o que, logicamente, é uma potencial razão para o aumento das vendas e lucros. Por outro lado, os fabricantes têm vantagens em incluir nos seus telemóveis uma plataforma que é utilizada pela maioria dos programadores. É um ciclo vicioso actualmente favorável ao J2ME. Algumas outras plataformas tentam sobreviver neste meio e optam por suportar software desenvolvido para o J2ME, o que acaba por beneficiar programadores, fabricantes e consumidores. No futuro, tudo depende da evolução tecnológica de cada plataforma e da sua aceitação no mercado. Para já, o J2ME tem grandes vantagens a seu favor conseguidas não só pela grande portabilidade e suporte por parte da grande maioria dos telemóveis existentes e marcas lideres de mercado, mas também pelo recente lançamento do MIDP 2.0 que relança o J2ME na competição com outras plataformas teoricamente mais avançadas. Também a inclusão desta plataforma, no N-Gage que se anuncia já como a consola portátil da Nokia, vai motivar muitos programadores e leva a supor que esta plataforma continuará a evoluir sempre com o intuito de acompanhar outras tecnologias concorrentes. Pode-se portanto concluir que, embora não seja a mais evoluída, a plataforma J2ME é de facto a mais utilizada e suportada, merecendo por isso uma maior atenção por parte dos programadores de telemóveis. 57 Tecnologia Java aplicada a telemóveis 58 5. Questões fundamentais ao desenvolvimento para telemóveis Os telemóveis são plataformas onde podem ser corridos diversos tipos de programas, mas são muito diferentes dos habituais computadores pessoais. Um programador que tencione desenvolver uma aplicação destinada a este tipo de plataforma móvel, deve ter em consideração diversos aspectos que são característicos dos telemóveis e, na maior parte dos casos, são muito limitativos para as próprias aplicações. 5.1. Memória • • Espaço para aplicações – Estes aparelhos têm uma memória muito reduzida, pelo que as aplicações devem ocupar pouco espaço e, por isso, todas as funcionalidades que se considerem desnecessárias devem ser retiradas. Também se deve ter um cuidado especial ao guardar informação referente à aplicação, como opções do utilizador, estado da aplicação ou pontuações. Memória de runtime – A memória disponível para correr aplicações é também muito reduzida. De modo a minimizar a utilização deste tipo de memória, deve ser minimizada a utilização de objectos complexos e feita reutilização de código (variáveis, objectos, etc.). A declaração e inicialização de objectos que não são estritamente necessários irá resultar num desperdício de memória. Os objectos devem ser alocados apenas à medida que são necessários e, logo que possível, devem ser libertados, colocando as suas referências a null. Embora a função do Garbage Collector seja gerir a memória convenientemente, muitas vezes pode ser mais eficaz que um programador faça essa gestão directamente. Excepções ocupam memória, pelo que devem ser evitadas. 5.2. Processador • • • Programas simplificados – Estas plataformas têm um baixo poder de processamento. As aplicações devem ser simples, de forma a ficarem mais rápidas e robustas. Funcionalidades adicionais devem ser separadas ou convertidas em aplicações secundárias para reduzir o processamento extra. Variáveis locais – É mais rápido aceder a classes locais do que a membros de classes. Concatenação de strings – A concatenação de strings diminui a performance e aumenta o consumo de memória da aplicação e, portanto, deve ser evitada. Tecnologia Java aplicada a telemóveis • • • Threads e sincronização – Qualquer operação que dure mais do que um décimo de segundo, requer um thread para a sua realização. Evitar a sincronização entre threads pode aumentar a performance. MVC – Pode ser usado o Model View Controller para separar a lógica, do código responsável pela apresentação. Design – A aplicação deve ser cuidadosamente desenhada e codificada de forma a não ter redundâncias de código e ciclos mais pequenos (e se possível poucos). O modo de programar influência muito a performance (tempo de processamento) e o tamanho da aplicação. 5.3. Display • • • 60 Cores – Deve-se ter em atenção o número de cores a utilizar para uma aplicação, visto que variam muito entre os diferentes tipos de telemóveis existentes. Actualmente são suportadas entre 2 a 56.536 cores. No caso de programação para aparelhos a cores, embora o uso das 56.536 cores seja mais apelativo, é aconselhável o uso de 4.096 cores para uma maior compatibilidade. Resolução – Tal como acontece com as cores, são suportadas diversas resoluções entre os telemóveis. É preciso ter em atenção a gama de telemóveis à qual se destina a aplicação e, mediante isso, escolher a resolução adequada. Se é pretendida uma maior compatibilidade, o facto de actualmente não existir nenhuma resolução standard, vai dificultar essa tarefa. No caso de se permitir que uma aplicação esteja adequada a várias resoluções distintas, é preciso ter cuidado com a memória utilizada e processamento. Provavelmente é melhor desenvolver varias aplicações distintas, adaptadas à resolução de cada aparelho. Ecrã – Outro aspecto a ter em atenção é o ecrã. Apesar de existirem muitas resoluções diferentes, o ecrã continua a ser muito pequeno (um ecrã grande tem 208x320 pixels), logo, suportam pouca quantidade de informação. No caso de jogos ou outras aplicações com um ambiente gráfico mais avançado, é necessário ter uma especial atenção à informação que aparece no ecrã ao mesmo tempo, e se essa informação é perceptível para o utilizador. Note-se que o próprio formato do ecrã difere entre as várias resoluções. Existem ecrãs rectangulares verticais (176x208 – Nokia 3650), rectangulares horizontais (101x80 – Siemens SL55) ou quadrados (128x128 – Nokia 5100). Questões fundamentais ao desenvolvimento para telemóveis 5.4. Som • • Tom – Caso a aplicação necessite de suporte audio, é preciso ver qual a capacidade do aparelho ou aparelhos neste campo. Os telemóveis mais antigos estão limitados a apenas alguns tons sonoros num único canal e, os mais recentes suportam tons polifónicos que utilizam entre 16, 32 ou mais canais distintos. O aumento da qualidade sonora de uma aplicação pode resultar na diminuição da sua compatibilidade. Formatos externos – Existem alguns modelos de telemóveis que suportam formatos audio externos como o WAV, MIDI ou outros, o que pode facilitar a composição e instalação de som em aplicações, porém, a questão da compatibilidade mantém-se. Os aparelhos mais antigos não suportam estes formatos. 5.5. Input • • Tipo de input – A maioria dos telemóveis, como dispositivo de input apenas suporta o seu teclado, que é comum a todos. O teclado é constituído por 9 teclas numeradas de 0 a 9, uma tecla “#”, uma tecla “*” e pelo menos uma tecla de selecção. Hoje em dia, existem já muitos telemóveis com teclas direccionais (cima, baixo, esquerda, direita) que também podem ser utilizados para aplicações. Mais uma vez, por razões de compatibilidade, é necessário ter em atenção a gama de telemóveis a que se destina a aplicação e o teclado que estes possuem. Teclado – Um aspecto importante acerca do teclado, é o facto de, na grande maioria dos telemóveis, não ser suportado que mais do que uma tecla seja pressionada ao mesmo tempo. Quando isto acontece, apenas é enviado o código referente à primeira tecla pressionada, ignorando a segunda. 5.6. Segurança • • Sandbox – Quando importados para um telemóvel, o programas correm num ambiente isolado denominado sandbox por razões de segurança. Apesar de ser um bom mecanismo de defesa para o utilizador impedindo que possam ser causados danos no telemóvel, pode ser também um factor limitativo para o programador. No J2ME as aplicações não têm acesso ao sistema operativo do telemóvel nem ás suas funções base de código nativo. Falta de segurança – A falta de suporte de segurança por parte do J2ME sempre foi um factor importante. Embora de um modo geral, o ambiente sandbox seja o suficiente, o facto de algumas aplicações poderem não ser consideradas seguras, pode levar a que os utilizadores não as descarreguem para o telemóvel. 61 Tecnologia Java aplicada a telemóveis 5.7. Funcionalidade • • Funcionalidades do telemóvel – É sempre importante conhecer as funcionalidades contidas no telemóvel ou gama de telemóveis para os quais se pretende programar. Alguns modelos de telemóveis possuem funcionalidades interessantes como bluetooth, câmara digital, MP3, toque por vibração (muito utilizado em jogos), etc., que podem ser úteis para o desenvolvimento de uma determinada aplicação. Outro aspecto importante é saber como aceder ou até mesmo se é possível aceder a estas funcionalidades. Recepção de chamadas – É também importante ter em conta que a principal funcionalidade de um telemóvel é efectuar e receber chamadas. Quando é recebida uma chamada, o telemóvel interrompe a aplicação para que a chamada possa ser atendida e, estes casos têm que estar previstos pelo programador. É necessário guardar as informações do estado da aplicação para que, após finalizada a conversação, a aplicação possa ser retomada a partir do ponto onde foi interrompida. 5.8 – Instalação • • 62 Net – Na grande maioria dos casos, a instalação de aplicações é feita via internet através de um download de fontes que muitas vazes não são consideradas seguras. É importante disponibilizar toda a informação possível acerca da aplicação para que o consumidor (e possível comprador) se sinta seguro e faça o download da aplicação pretendida. Tamanho – Aplicações mais pequenas requerem um menor tempo de download e instalação e ocupam menos espaço no telemóvel. Isto pode ser um factor decisivo na escolha (ou não) de uma determinada aplicação por parte do utilizador. Aplicações muito grandes, demoram muito tempo a percorrer a rede ainda lenta, suportada pelos telemóveis e, ocupam demasiado espaço no telemóvel, por isso, geralmente o utilizador prefere duas aplicações pequenas a uma aplicação grande. 6. Ferramentas para o desenvolvimento de aplicações Para iniciar o desenvolvimento de aplicações destinadas a telemóveis, são necessárias algumas ferramentas que podem ser facilmente obtidas. Este tipo de programação requer as seguintes ferramentas: • J2SE SDK; • J2ME Wireless Toolkit; • Editor Java; Tudo o que é necessário para desenvolver aplicações em J2ME para telemóveis, encontra-se incluído nestas ferramentas, que irão ser abordadas em seguida mais pormenorizadamente. 6.1. J2SE SDK O Software Development Kit do J2SE, contém tudo o que é necessário para o desenvolvimento de aplicações em Java. Apesar de, no caso dos telemóveis ser utilizada a Micro Edition, todo o código desenvolvido e compilado continua a ser Java, pelo que são necessárias todas as funcionalidades base contidas no SDK do J2SE. Entre essas funcionalidades, estão presentes as seguintes: • Ferramentas de desenvolvimento – Ferramentas e utilidades cuja função é auxiliar o desenvolvimento, execução e debug, assim como alguns programas escritos em Java. • Ambiente de trabalho - Uma implementação do Java 2 Runtime Environment que inclui uma Virtual Machine, librarias e outros ficheiros de suporte à programação e execução de programas escritos em Java. • Librarias adicionais – Librarias adicionais e ficheiros de suporte para as ferramentas de desenvolvimento. • Applets e aplicações exemplo – Exemplos com código fonte, de programas desenvolvidos em Java. • Ficheiros “header” de C - Ficheiros “header” que suportam programação em código nativo com o Java Native Interface (JNI) e outras funcionalidades da plataforma Java 2. • Código fonte – Os ficheiros fonte Java para todas as classes que constituem a API do Java 2. O J2SE SDK é a base na qual se irá apoiar a programação em Java para telemóveis. Note-se que nas ferramentas de desenvolvimento já está incluída uma VM. No entanto, será mais correcto utilizar a VM que vem incluída no Wireless Toolkit (KVM), pois esta é específica para plataformas móveis, nomeadamente telemóveis. O download do J2SE SDK é gratuito e pode ser feito em http://java.sun.com/j2se/1.4.2/download.html (versão 1.4.2). Tecnologia Java aplicada a telemóveis 6.2. J2ME Wireless Toolkit O Wireless Toolkit é a ferramenta mais importante na programação para telemóveis e, por isso, será analisada mais pormenorizadamente. O WTK é uma emulação de um ambiente destinado ao desenvolvimento de aplicações para aparelhos baseados em CLDC que corram com o Mobile Information Device Profile (MIDP). Com a utilização deste toolkit, os programadores podem ter a certeza de que as aplicações desenvolvidas serão compatíveis com quaisquer implementações do CLDC/MIDP, e estarão optimizadas para correr em ambientes muito limitados, equiparáveis aos actuais telemóveis. O J2ME WTK inclui: • CLDC – Este toolkit inclui a especificação CLDC, destinada à programação para plataformas móveis mais limitadas. No CLDC, está incluída a KVM, que será a Virtual Machine utilizada para esta tipo de aplicações; • MIDP 2.0 - O WTK também inclui as especificações do MIDP 2.0 que, além das funcionalidades disponibilizadas pela primeira versão do MIDP, traz também algumas melhorias, tais como: o Uma API específica para jogos; o Melhorias nas capacidades audio; o Possibilidade de criação de componentes personalizados para forms; o Possibilidade de uso de arrays simples de inteiros, para manipulação de imagens; o Arquitectura de segurança melhorada, com suporte HTTPS; o MIDlets podem receber ligações da rede; • Mobile Media API – A MMAPI possibilita o uso de audio, vídeo e outros tipos de multimédia em aparelhos com recursos limitados. Esta funcionalidade aumenta consideravelmente a performance da aplicação, quando são manipulados dados mais “pesados” como é o caso de dados multimédia; • Wireless Messaging API – Esta API fornece acesso independente de plataforma a recursos de comunicação sem fios. Esta funcionalidade pode ser útil para aplicações que requeiram acesso a informação exterior, ou mesmo na instalação ou actualização de aplicações; • Emulador – O J2ME WTK inclui um emulador de um telemóvel que permite testar aplicações desenvolvidas em J2ME. Com este emulador é possível testar aplicações num ambiente bastante aproximado do real, sem ser necessário fazer o upload da aplicação para o telemóvel; • Monitorização – O WTK permite um melhor controlo da execução da aplicação e monitorização da sua performance. O J2ME WTK é portanto uma “caixa de ferramentas” muito útil para este tipo de programação, que pode ser facilmente instalado. Em alternativa, podem ser instalados os componentes necessários (CLDC, MIDP 2.0, KVM) separadamente. 64 Ferramentas para o desenvolvimento de aplicações Após a instalação do WTK, o programador tem acesso a uma série de funcionalidades que serão explicadas de seguida. Essas funcionalidades são: • Default Device Selection; • Documentation; • KToolbar; • OTA Provisioning; • Preferences; • Run MIDP Application ...; • Utilities; 6.2.1. Default Device Selection Se não for especificado o dispositivo a ser emulado, o Emulador usa o dispositivo default que é aqui indicado. Figura 6. 1 - Escolha do dispositivo default Aqui existem quatro opções de dispositivos a ser emulados: • Default Color Phone – Telemóvel genérico com ecrã a cores; • Default Gray Phone – Telemóvel genérico com ecrã a escala de cinza; • Media Control Skin – Telemóvel genérico com ecrã a cores e controlo para reprodução de audio e vídeo; • Qwerty Device – Dispositivo genérico que usa um teclado do estilo QWERTY; Muito provavelmente, o dispositivo escolhido por defeito será o telemóvel a cores (Default Color Phone). 6.2.2. Documentation Documentation não é mais do que um documento HTML que contém a documentação necessária para o WTK, assim como alguns links para mais informação útil acerca deste toolkit. Aqui pode ser encontrada toda a informação acerca do modo de funcionamento do J2ME WTK. 65 Tecnologia Java aplicada a telemóveis 6.2.3. KToolbar Este é o ponto de entrada para o WTK. A KToolbar é um ambiente de desenvolvimento mínimo, com um interface gráfico (GUI) para compilar e executar aplicações MIDP. A partir desta toolbar, podem ser feitas as seguintes operações: • Criar novos projectos ou abrir projectos já existentes; • Compilar, correr e fazer debug de MIDlets; • Optimizar aplicações MIDlet; • Agrupar projectos em packages; • Modificar atributos da MIDlet suite; Ao correr a KToolbar, o programador tem acesso à janela principal: Figura 6. 2 - Consola principal da KToolbar Como se pode observar, a navegação pela KToolbar é bastante simples. O menu file, contém as seguintes opções: • New Project ...; • Open Project...; • Save Console...; • Utilities...; • Exit; 66 Ferramentas para o desenvolvimento de aplicações New Project Esta opção permite a criação de um novo projecto. Ao seleccionar esta opção, aparecerá uma janela a pedir o nome do projecto e o nome da classe MIDlet principal. Figura 6. 3 - Criação de um novo projecto Depois de executada esta operação, irão aparecer na consola os locais indicados para colocar os ficheiros referentes ao projecto criado. O botão “New Project...” da janela principal, tem o mesmo efeito. Open Project Esta opção serve para abrir um projecto já existente. Ao seleccionar esta opção, aparecerá uma janela com a lista de todos os projectos existentes. Figura 6. 4 - Abrir um projecto existente O botão “Open Project...” da janela principal, tem o mesmo efeito. Save Console Esta opção permite ao programador guardar o conteúdo da consola num ficheiro de texto “txt”. 67 Tecnologia Java aplicada a telemóveis Utilities Ao seleccionar esta opção, é aberta uma janela onde se podem utilizar algumas funcionalidades referentes ao emulador. Figura 6. 5 - Consola de utilities • • • 68 Clean Database (Database) – O emulador simula um dispositivo cliente com capacidade de armazenamento local, mantendo para isso uma pequena base de dados no computador. Esta funcionalidade limpa a base de dados; Open Session (Memory Monitor) – O Memory Monitor mostra ao programador a quantidade de memória que está a ser usada em tempo de execução. O Open Session do Memory Monitor permite ao programador examinar a informação previamente guardada, acerca destes dados; Open Session (Network Monitor) – O Network Monitor monitoriza o tráfego de rede gerado pelas aplicações, e protocolos como HTTP, HTTPS, etc. Aqui pode ser acedida informação previamente guardada, acerca destes dados; Ferramentas para o desenvolvimento de aplicações • • • • Open Session (Profiler) – O Profiler recolhe dados do emulador durante a execução, como tempo de execução de métodos, número de chamadas ou relações hierárquicas. A análise destes dados pode servir para localizar potenciais problemas. O Open Session do Profiler permite ao programador aceder a esta informação. Open Console (WMA) – Abre a Wireless Messaging API; Sign MIDlet (Security) – Abre a consola Sign MIDlet Suite; Menage Certeficates (Security) – Abre o Certeficate Manager; Wireless Messaging API O WMA serve para testar aplicações que suportem o envio de mensagens SMS (Short Message Service) ou CBS (Cell Broadcast Service). Ao seleccionar esta opção, irá ser apresentada a seguinte consola: Figura 6. 6 - Consola WMA Os botões “Send SMS...” e “Send CBS” abrem janelas para o envio de mensagens do tipo SMS e CBS respectivamente. O botão “Clear” limpa a consola e o botão “Exit” fecha a consola. 69 Tecnologia Java aplicada a telemóveis Send SMS Figura 6. 7 - Envio de mensagem SMS Esta consola está dividida em duas pastas. A pasta “Text SMS“ destina-se ao envio de mensagens do tipo texto, enquanto a pasta “Binary SMS“ destina-se a ficheiros binários, como imagens, audio, etc.. O botão “Add Unlisted Client...” permite adicionar novos clientes à lista “To Selected Clients”, aos quais será enviada a mensagem. O campo de texto denominado “Port (Optional)”, é opcional e pode indicar um canal específico de comunicações através do qual será enviada a mensagem. Se nada for indicado, a mensagem será enviada directamente para o dispositivo cliente. O conteúdo da mensagem será especificado no campo “Message”. A pasta “Binary SMS”, em vez de um campo de texto para a mensagem, dá a possibilidade do programador escolher um ficheiro que será posteriormente enviado. 70 Ferramentas para o desenvolvimento de aplicações Send CBS Figura 6. 8 - Envio de mensagem CBS Tal como no caso anterior, existem duas pastas, uma destinada ao envio de mensagens de texto e outra o envio de ficheiros binários. Neste caso, a mesma mensagem será enviada em broadcast para todos os emuladores que estejam a correr. O programador terá que fornecer um identificador da mensagem que será especificado no campo “Message Identifier”, e o conteúdo da mensagem que, no caso da pasta “Text CBS” será texto inserido num campo de texto (análogo ao exemplo anterior) e, no caso da pasta “Binary CBS”, terá que ser escolhido um ficheiro a enviar. Para especificar o ficheiro, pode ser escrita a sua localização no campo “Send the contents of this file:” ou pode ser escolhido directamente, premindo o botão “Browse”. O botão “Send” envia a mensagem e o botão “Cancel” fecha a consola. 71 Tecnologia Java aplicada a telemóveis Sign MIDlet Suite O WTK permite o uso de certificados para aumentar a segurança e autenticar quem envia a aplicação. Nesta consola, pode-se assinar aplicações (MIDlets) desenvolvidas, com chaves publicas e privadas afim de aumentar a segurança e confiança dos possíveis utilizadores. A consola tem o seguinte aspecto: Figura 6. 9 - Assinatura da MIDlet suite Do lado esquerdo, a “Alias List” contém uma lista das chaves disponíveis e, do lado direito são mostrados os conteúdos da chave seleccionada. O botão “Sign MIDlet Suite...” permite assinar uma MIDlet que será escolhida pelo programador. O par de chaves atribuído pode ser novo (criado através do botão “New Key Pair...” ) ou importado. No caso da criação de um novo par de chaves, é pedida alguma informação como nome de identificação (Alias), nome do servidor (Dname:C) e nome da Figura 6. 10 - Novo par de chaves organização (O). O menu “Action” contém as mesmas opções já referidas, acrescidas da opção “Delete Selection” que permite apagar um determinado par de chaves, e da opção “Exit” que fecha esta consola. 72 Ferramentas para o desenvolvimento de aplicações Certeficate Manager Os certificados são usados para verificar a confiança da rede e das MIDlets assinadas. Se for usado um protocolo de segurança como o HTTPS ou SSL para acesso a um site, o certificado desse site é verificado para comprovar a sua validade, e o certificado da MIDlet também é verificado afim de comprovar se tem permissão para aceder a esse site. Os certificados podem ser geridos na seguinte consola: Figura 6. 11 - Gestor de certificados Do lado esquerdo na “Certificate List” pode-se ver uma lista dos certificados existentes e, à direita, aparecerão os detalhes acerca do certificado seleccionado. Uma lista de certificados é guardada num determinado “Keystore”. Caso se pretenda obter um certificado guardado, pode-se abrir uma keystore através do botão “Open Keystore...”. Os certificados também podem ser importados de uma “Certificate Authority”, através do botão “Import Certificate...”. O menu “File” contém as opções “Open Keystore...” e “Exit” que permite sair da consola. O menu “Action”, em adição à opção “Import Certificate...”, contém as opções “Import J2SE Certificate” que permite importar certificados da keystore do J2SE, e “Delete Selection” que permite apagar um determinado certificado seleccionado. 73 Tecnologia Java aplicada a telemóveis No menu “Edit” da KToolbar podem ser encontradas algumas opções referentes às configurações desta ferramenta de trabalho. Este menu contém apenas duas opções: • Preferences...; • Clear Console; Preferences Esta opção permite realizar algumas configurações da KToolbar. Ao escolher “preferences”, aparecerá uma consola com várias pastas referentes a diferentes áreas de configuração. Esta consola tem o seguinte aspecto: Figura 6. 12 - Configuração de rede No caso do programador pretender que uma aplicação aceda à rede apenas através de um proxy, por exemplo, se o servidor tiver uma firewall, é necessário definir o endereço e a respectiva porta desse proxy, no campo “HTTP”. Para especificar a informação do proxy para uma ligação HTTPS, deverá ser definido o nome do servidor HTTPS e a sua porta no campo “Security”. Na área “Http Version” é possível escolher a versão do HTTP que se está a utilizar. Note-se que a especificação MIDP requer a versão 1.1 do HTTP. 74 Ferramentas para o desenvolvimento de aplicações Figura 6. 13 - Performance Esta pasta contém as configurações relativas à performance. A barra “Graphics primitives latency” deixa especificar o tempo em milisegundos entre o pedido efectuado e a apresentação do gráfico no ecrã. O “Display refresh” especifica a maneira como os gráficos serão apresentados. Existem três modos de display: • Double Buffer – O gráfico é renderizado numa área fora do ecrã e só depois é mostrado; • Immediate – O gráfico é renderizado directamente no ecrã; • Periodic – Deixa definir a frequência com que o ecrã é renovado, em frames por segundo. Quando se testa uma MIDlet no emulador, não se consegue obter uma ideia real da velocidade de execução da aplicação. Num telemóvel, a aplicação será bastante mais lenta. Contudo, é possível tentar aproximar a velocidade simulada à velocidade real, definindo uma velocidade mais lenta para a VM. Isto pode ser feito na barra “Enable VM speed emulation”. Do mesmo modo se pode proceder quanto à velocidade de transmissão de dados numa rede. Se uma aplicação requer ligação a uma rede, é conveniente testar a performance dessa aplicação quando utilizar uma rede mais lenta, equiparada com as capacidades de um telemóvel. A velocidade de transmissão de dados na rede em bits/seg pode ser definida em “Enable network throughput emulation”. 75 Tecnologia Java aplicada a telemóveis Figura 6. 14 - Monitorização Na pasta “Monitor” Podem ser escolhidas algumas opções de monitorização para uma MIDlet. Na área “Memory Monitor” estão contidas algumas opções relativas à monitorização da memória em uso. “Enable Memory Monitor” permite que, em tempo de execução, seja mostrada uma janela que demonstra a utilização de memória pela aplicação e o “Excessive GC Mode” permite determinar a quantidade de memória necessária. Na janela de monitorização de memória, pode ser guardada a informação para que, mais tarde, possa ser consultada. A área “Network Monitor” é referente à monitorização de transmissão de dados em rede. Aqui, quando escolhida a opção “Enable Network Monitoring”, é mostrada uma janela em tempo de execução, que demonstra o tráfego na rede. Esta informação também pode ser guardada. Em “Profiler” pode ser escolhida a opção “Enable Profiling” que, depois de corrida a MIDlet, mostra uma consola que explicita dados referentes à execução da aplicação, tais como tempo de execução de métodos ou número de chamadas efectuadas. De modo a permitir fazer uma análise mais cuidada, é possível guardar esta informação. Por fim, em “Trace” podem ser escolhidas algumas opções referentes à monitorização de código. 76 Ferramentas para o desenvolvimento de aplicações A consola pode demonstrar o que se passa a nível do garbage collector, carregamento de classes, excepções ocorridas ou chamadas a métodos. Isto pode ser considerado uma forma muito simples de debug que facilita a detecção de erros de código por parte do programador. Figura 6. 15 - Armazenamento A pasta “Storage” contém algumas definições acerca da memória utilizada. Pode ser especificada a directoria para armazenamento no campo “Storage Root Directory”. Nessa directoria será criada uma pequena base de dados com a informação armazenada. Aqui pode também ser definida a memória de pilha a ser utilizada com as MIDlets e a capacidade máxima de armazenamento, em “Heap Size” e “Storage Size” respectivamente. Por defeito, a memória de pilha está definida para 500 KB mas pode variar entre 32 KB e 64 MB. Figura 6. 16 - Disponibilidade de APIs Caso o dispositivo para onde se pretende desenvolver uma aplicação não suporte MMAPI ou WMA, pode-se retirar essa opção nesta pasta. Deste modo, assegura-se que a aplicação não faz uso destas APIs e corre sem problemas no aparelho ao qual é destinada. 77 Tecnologia Java aplicada a telemóveis Figura 6. 17 - WMA Na pasta WMA existem algumas configurações referentes ao Wireless Messaging API. A qualquer momento, pode ser útil partir do princípio que o próximo emulador contém um número de telefone específico, afim de testar aplicações que envolvam trocas de mensagens por exemplo. Esse número pode ser definido em “Phone Number of Next Emulator”. Visto que se está a trabalhar num emulador, também não existe número para um centro de mensagens, pelo que pode ser simulado. Esse número pode ser definido em “SMSC Phone Number”. Também para aproximar este ambiente da realidade, é possível simular a perda de pacotes de mensagens ou o atraso entre o envio de uma mensagem e a sua recepção (“Random Message Fragment Loss” e “Message Fragment Delivery Delay (ms)” respectivamente). Figura 6. 18 - MMedia Na pasta “MMedia” podem ser especificados os formatos (WAV, MIDI ou Vídeo) e outras funcionalidades (misturas de audio, gravação audio, captura vídeo e tons MIDI) que podem ser suportadas pelo aparelho ao qual se destina a aplicação. 78 Ferramentas para o desenvolvimento de aplicações Deste modo, garante-se que uma aplicação que não utilize estas funcionalidades, é compatível com o telemóvel ao qual se destina. Figura 6. 19 - Segurança A pasta “Security” permite definir o nível de confiança que o possuidor de um certificado tem que ter para aceder a uma API protegida, bem como o seu nível de acesso a essa API. No “Security Domain” podem ser definidos quatro tipos de domínios de segurança: • Untrusted – Uma MIDlet para a qual a origem e a integridade do ficheiro JAR não são de confiança para o aparelho; • Trusted – Uma MIDlet com um ficheiro JAR assinado e com um certificado que pode ser verificado pelo aparelho; • Minimum – Um domínio de segurança em que todas as permissões a APIs protegidas são negadas; • Maximum - Um domínio de segurança em que todas as permissões a APIs protegidas são concedidas; Clear Console A opção “Clear Console” limpa a consola. Tem o mesmo efeito que o botão “Clear Console”. Após a escolha de um projecto, o menu “Project” fica activo, assim como os botões “Settings”, “Build” e “Run”. No menu “Project” existem as seguintes opções: • Build; • Clean; • Run; • Package o Create Package; o Create Obfuscated Package; • Sign; • Run via OTA; • Debug; • Settings; 79 Tecnologia Java aplicada a telemóveis Build A opção “Build” compila e pré-verifica o código desenvolvido. Clean A opção “Clean” apaga todos os ficheiros temporários e ficheiros class da directoria corrente do projecto. Run Esta opção corre o código compilado. Se não for compilado previamente, esta opção chama primeiro a opção “Build”. Quando corrido o código, é chamado automaticamente o emulador (telemóvel) com o programa desenvolvido a correr no ecrã. Package Esta opção cria um ficheiro JAR pronto a ser instalado num aparelho. Neste caso, as classes são compiladas sem qualquer informação de debug para reduzir o tamanho do ficheiro. Dentro desta opção existem dois métodos de criação de ficheiros JAR: • “Create Package” – Cria um ficheiro JAR “normal”. • “Create Obfuscated Package” – Utiliza métodos externos para criar um ficheiro JAR mais pequeno. Sign Abre a consola “Sign MIDlet Suite”. Run via OTA Ao escolher esta opção, é possível correr uma aplicação como se fosse descarregada da internet. Logo de início é corrido o emulador com uma aplicação de gestão de aplicações, a partir da qual é possível instalar a aplicação desenvolvida. Deste modo, é possível simular todo o ambiente móvel para o qual se está a programar, mesmo na fase de download e instalação de uma aplicação via internet. Debug Quando é escolhida esta opção, é pedido o valor da porta TCP/IP que pode ser usada por um debugger externo. Em seguida, é corrida a aplicação em modo debug (com o emulador) e fica à espera da ligação de um debugger externo para que possa prosseguir com a aplicação. Deste modo, é feia uma ligação entre o emulador e um debugger externo, fornecido com a aplicação de desenvolvimento Java. 80 Ferramentas para o desenvolvimento de aplicações Settings A opção “Settings” permite modificar os atributos da MIDlet. Figura 6. 20 - Atributos requeridos A pasta “Required” permite alterar ou definir os atributos obrigatórios para a MIDlet. No exemplo, foi aberto o projecto “Games” que contém os atributos descritos acima. Figura 6. 21 - Atributos opcionais A pasta “Optional” destina-se aos atributos opcionais da MIDlet. Figura 6. 22 - Atributos definidos pelo utilizador Aqui são estão os atributos definidos pelo utilizador. Note-se que estes atributos podem ser adicionados ou removidos. 81 Tecnologia Java aplicada a telemóveis Figura 6. 23 - Atributos das MIDlets Estes atributos referem-se ao posicionamento das MIDlets no menu principal de escolha. Neste caso, os atributos podem ser adicionados, alterados ou eliminados, podendo também a sua ordem ser alterada. Figura 6. 24 - Push registry Nesta pasta é configurado o uso de “push registry” com a MIDlet desenvolvida. Este mecanismo permite que uma MIDlet seja lançada automaticamente sem qualquer interacção do utilizador e, para que isso seja possível, é necessário que a MIDlet esteja registada no “push registry”. Aqui, o campo “Key” é gerado automaticamente à medida que se adicionam registos. O “Connection URL” é uma string que identifica o protocolo de ligação e a porta associada, o atributo “Class” é referente ao nome da classe a que pertence a MIDlet e o campo “Allowed Sender” refere-se a uma entidade com permissões para lançar esta MIDlet. Cada MIDlet pode ter vários registos e, cada um destes registos pode ser adicionado, alterado ou removido. 82 Ferramentas para o desenvolvimento de aplicações Figura 6. 25 - Permissões Para funcionar correctamente, pode ser necessário que uma MIDlet suite aceda a APIs protegidas e, para isso, é necessário obter permissão. Para esse efeito, podem ser editados os atributos “MIDlet Permissions” e “MIDlet Permissions opt” (optional) na pasta “Permissions”. Para adicionar as permissões, basta clicar no botão “Add” e escolher as APIs a que se pretende dar permissão, entre as que estão listadas. Também é possível remover permissões, bastando para isso seleccionar a permissão que se pretende remover, e clicar no botão “Remove”. A opção “Settings” também pode ser acedida através do botão “Settings” da KToolbar. O menu “Help” apenas contém uma breve referência aos termos de licença desta aplicação. 83 Tecnologia Java aplicada a telemóveis 6.2.4. OTA Provisioning O “OTA Provisioning” fornece um outro tipo de emulação do ambiente em que corre uma aplicação. O simulador é o mesmo. A única diferença é que a aplicação não poderá correr logo directamente no emulador. Neste caso, não é simulado somente o ambiente de execução, mas sim o modo de funcionamento de um telemóvel que não contém a aplicação que se pretende testar. Assim, além da execução da aplicação, pode ser também testado o seu download e a sua instalação. Em vez de mostrar logo a aplicação, o simulador corre um interface para gestão de aplicações (já existente na maioria dos telemóveis que suportam Java), a partir do qual se terá que descarregar e instalar a aplicação a ser testada. A intenção é tornar o ambiente de execução o mais real possível, não deixando ao acaso nenhuma das partes do desenvolvimento de toda a aplicação. Esta funcionalidade pode também ser acedida a partir da KToolbar através do menu “Project”, seleccionando a opção “Run via OTA”. 6.2.5. Preferences Figura 6. 26 - Emulador OTA Este atalho permite ao programador personalizar as configurações da KToolbar, tal como referenciado anteriormente. Estas configurações também podem ser acedidas através do menu “Edit” da KToolbar, seleccionando a opção “Preferences...”. 6.2.6. Run MIDP Application... Esta é uma maneira fácil e rápida de correr uma aplicação MIDP que já se encontre desenvolvida. Aqui é pedido apenas o nome do ficheiro JAD referente à aplicação, que contém algumas informações necessárias, e é corrida a aplicação no emulador. Caso a aplicação não contenha um ficheiro JAD associado, este pode ser construído a partir das informações contidas no ficheiro de manifesto do JAR. 84 Ferramentas para o desenvolvimento de aplicações Por exemplo, vamos supor que temos uma aplicação com o nome “StreetFighter.JAR” e não contém o ficheiro JAD associado. O seu ficheiro de manifesto seria o seguinte: MANIFEST.MF Manifest-Version: 1.0 MicroEdition-Configuration: CLDC-1.0 MIDlet-Data-Size: 0 MIDlet-Version: 1.0 Created-By: 1.3.1 (Sun Microsystems Inc.) MIDlet-Vendor: JShape Software MicroEdition-Profile: MIDP-1.0 MIDlet-1: msf, , msf MIDlet-Name: msf O ficheiro JAD daí resultante seria o seguinte: StreetFighter.JAD MIDlet-Name: msf MIDlet-Vendor: JShape Software MIDlet-Version: 1.0 MIDlet-Jar-URL: mstreetfighter.jar MIDlet-Jar-Size: 34843 Em que: • • • • • MIDlet-Name corresponde ao nome da MIDlet e pode ser retirado do ficheiro de manifesto; MIDlet-Vendor corresponde ao fabricante, e pode também ser retirado do ficheiro de manifesto; MIDlet-Version corresponde à versão da MIDlet, e também consta do ficheiro de manifesto; MIDlet-Jar-URL corresponde ao nome e localização do ficheiro JAR associado. Este parâmetro não está no ficheiro de manifesto mas pode ser facilmente preenchido; MIDlet-Jar-Size corresponde ao tamanho do ficheiro JAR. Embora também não esteja no ficheiro de manifesto, esta informação é muito fácil de obter. Depois de escolhido o ficheiro JAD, é lançado o emulador com a aplicação a correr. 85 Tecnologia Java aplicada a telemóveis 6.2.7. Utilities Aqui podem ser utilizadas algumas funcionalidades relativas ao emulador tal como foi já referido. Outro modo de aceder a esta consola, é através do menu “File” da KToolbar, seleccionando a opção “Utilities”. A versão 2.0 do J2ME Wireless Toolkit é gratuita e pode ser obtida no site da Sun em http://java.sun.com/products/j2mewtoolkit/download-2_0.html. 6.3. Editor Java Para finalizar, é necessário um editor Java com uma boa ferramenta de debug e um ambiente de trabalho apropriado. A escolha de um editor é mais a nível pessoal. Cada programador escolhe o editor com que está mais familiarizado, ou que se adapta melhor à sua forma de trabalhar. Existem inúmeras ferramentas deste tipo. Aqui estão alguns exemplos: • Ultra Edit - http://www.ultraedit.com; • Eclipse - http://www.eclipse.org; • Sun One Studio http://developer.java.sun.com/developer/earlyAccess/j2meconwizard; • JBuilder - http://www.borland.com/jbuilder; A Sun recomenda o Sun One Studio, garantindo que esta ferramenta tem uma óptima interligação com o Wireless Toolkit. 86 7. Desenvolvimento Antes de iniciar o ciclo de desenvolvimento, é necessário criar uma estrutura de directórios que suporte a construção da MIDlet suite. Note-se que a MIDlet suite é um conjunto de MIDlets que partilham os mesmos recursos. Vamos supor que será desenvolvida uma aplicação com o nome HelloWorld. Em primeiro lugar, será criado um novo projecto através do WTK: Figura 7. 1 - Criação de um novo projecto Após clicado o botão “Create Project”, será criada uma nova estrutura de directórios dentro da directoria “WTK20/apps” (directoria base da instalação do WTK. Aí será criada uma directoria com o nome da aplicação que se pretende desenvolver (neste caso “HelloWorld”) e, dentro desta, serão criadas as seguintes sub-directorias: • bin; • classes; • lib; • res; • src; Após concluída com sucesso a criação, aparecerá a janela de “Settings” para que seja inserida mais informação acerca da MIDlet. Alguma informação aparecerá por defeito: Figura 7. 2 - Janela de settings Tecnologia Java aplicada a telemóveis Depois de concluídas estas operações, aparecerá na consola principal do WTK a seguinte informação: Figura 7. 3 - Consola principal após a criação de um projecto Esta informação refere-se à estrutura de directórios criada e indica o local onde devem ser colocados os ficheiros referentes ao projecto: • Ficheiros de código HelloWorld/src; • Outros ficheiros necessários à aplicação HelloWorld/res; • Librarias HelloWorld/lib; Agora já é possível passar à codificação de aplicações (MIDlets). O desenvolvimento de código será feito à parte, num editor de texto ou editor Java, e os ficheiros com código (ficheiros JAVA) serão colocados na directoria “src” do respectivo projecto. Toda a fase de compilação e pré-verificação será feita no WTK, bastando para isso utilizar a função “Build”. Em seguida, o código pode ser testado directamente no emulador, utilizando a função “Run”. No caso de se pretender utilizar a(s) MIDlet(s) desenvolvida(s) num telemóvel, é necessário realizar mais algumas operações: • Criar um ficheiro de manifesto (MF) – O ficheiro de manifesto do JAR contém informação importante acerca da aplicação desenvolvida e deve ser criado antes da criação do JAR. Para criar este ficheiro basta editar um ficheiro de texto e proceder segundo as regras já enunciadas. • Criar um package (JAR) – É possível compactar o código desenvolvido num ficheiro JAR, para que possa ser descarregado para um telemóvel, a partir da função “Package/Create Package” do menu “Project “do WTK. • Criar um ficheiro descritor (JAD) – Este ficheiro é muito parecido com o ficheiro MF e serve para fornecer informação da aplicação a um possível utilizador sem que este tenha que descarregar toda a aplicação. Este ficheiro também pode ser criado apenas com a edição de um ficheiro de texto. • Instalação – Por fim, para que uma aplicação possa ser instalada num telemóvel, é necessário que seja inserida num sistema próprio para disponibilizar aplicações, para que depois essa aplicação possa ser descarregada para o telemóvel. 88 Desenvolvimento 7.1. Hello World Para dar uma ideia melhor da programação de uma MIDlet, será demonstrado o código de uma aplicação muito simples: “Hello World”. Hello World import import import import javax.microedition.lcdui.Display; javax.microedition.lcdui.Displayable; javax.microedition.lcdui.Form; javax.microedition.midlet.MIDlet; /*Cria o programa "Hello world" no J2ME MIDP. Note-se que a classe tem que ser publica para que a aplicação de gestão de software do dispositivo a possa instanciar.*/ public class HelloWorld extends MIDlet { //Este componente é mostrado no ecrã. private Form form; //Display. Este objecto controla todos os componentes do display. private Display display; /*É necessário um constructor público, sem argumentos, mesmo que não seja utilizado.*/ public HelloWorld() { super(); } public void destroyApp(boolean destroy) { form = null; notifyDestroyed(); } public void pauseApp() { } public void startApp() { //Cria um novo form para ser mostrado. form = new Form("Hello, World"); // Acrescenta uma string ao form. String msg = "My first MIDlet!"; form.append(msg); //Agora é mostrado o form criado acima. display = Display.getDisplay(this); display.setCurrent(form); } } 89 Tecnologia Java aplicada a telemóveis Esta pequena aplicação, apenas mostra uma frase no ecrã. Depois de pré-verificado e compilado, o código é corrido e obtém-se o seguinte resultado: Figura 7. 4 - Aplicação Hello World no telemóvel Aqui aparece o nome da aplicação desenvolvida, pronta a ser chamada. Para correr a MIDlet no telemóvel, basta premir o botão “Launch”. Seria então obtido o seguinte ecrã: Figura 7. 5 - Resultado da aplicação Hello World A frase “My first MIDlet” aparecerá no ecrã do telemóvel. Este primeiro exemplo serve de base para iniciar o desenvolvimento de aplicações com esta tecnologia. 90 Desenvolvimento 7.2. Princípios básicos Existem alguns princípios básicos que de devem ter em conta quando se inicia o desenvolvimento de uma aplicação deste género. Em primeiro lugar, é útil relembrar as funcionalidades que estão ao alcance do programador. Logo de início é possível constatar que se está a trabalhar com uma API relativamente pequena e compacta, constituída por sete packages: • java.io – Contém classes relativas a dados que, entre outras coisas, são úteis para fazer leituras de fontes externas como imagens ou sons; • java.lang – Inclui as classes base do Java, derivadas da API do J2SE. Aqui estão as classes mais importantes e a classe Math com funcionalidades reduzidas; • java.util – Este package é derivado do java.util do J2SE, e contém algumas classes de grande utilidade como Random, Vector, Hashtable e TimerTask; • java.microedition.io – Este package contém todas as classes e interfaces relativos a funcionalidades de rede; • java.microedition.lcdui – Este é o package mais poderoso. Aqui estão contidas as classes para operações de alto e baixo nível. Os componentes de alto nível incluem Forms, Lists, TextFields e Commands, e são todos importantes para controlar o input e a navegação do utilizador. Entre os objectos de baixo nível estão o Canvas, Graphics e Image que disponibilizam acções típicas de aplicações com interface gráfico (como jogos), tais como desenhar no ecrã e apanhar instruções do utilizador; • java.microedition.midlet – Este package define o ponto de entrada e saída para as aplicações MIDP (MIDlets). Aqui está contida a classe MIDlet que é usada pelo AMS (Application Management Software) para controlar o ciclo de vida ou o estado da MIDlet. Todas as MIDlets desenvolvidas têm que ter uma classe que seja uma extensão da classe MIDlet para permitir ao AMS começar e terminar a aplicação; • java.microedition.rms – O package rms fornece mecanismos para guardar dados de um modo persistente. É muito útil para guardar dados referentes às aplicações, como pontuações ou estados das aplicações. Os elementos básicos de armazenamento são referidos como registos (records) que podem ser lidos através da classe RecordStore; Tal como mencionado anteriormente, a base e ponto de entrada da aplicação, é efectivamente a classe ”MIDlet”. Também foi mencionado que o AMS é o software do dispositivo encarregue de gerir o ciclo de vida das aplicações. Quando um utilizador decide abrir a sua lista de aplicações e iniciar um programa, o AMS vai criar uma nova instância da classe principal, que é uma extensão da classe ”MIDlet”. Para fazer isto, o AMS vai utilizar o construtor sem argumentos da classe ”MIDlet”. 91 Tecnologia Java aplicada a telemóveis Depois disto, se não ocorrer nenhum erro ou excepção, vai ser chamado o método ”startApp()” da nova instância da MIDlet. A MIDlet fica então no estado “Activo” e é aqui que se obtém controlo da aplicação e pode começar a correr. Um factor de grande importância para aplicações do tipo “jogo” é o Canvas, que define todos os métodos importantes para desenhar no ecrã e capturar instruções do utilizador. A classe “Canvas”, é uma extensão de uma classe chamada “Displayable” que é uma base indispensável para que objectos como Lists ou Forms possam ser colocados no ecrã. Nesta classe são definidos alguns métodos muito importantes, que serão bastante utilizados na interacção do utilizador com o jogo ou aplicação: • keyPressed( int keyCode ) – Este método indica se uma tecla está a ser pressionada. A tecla pressionada pode ser identificada através do parâmetro int do método; • paint( Graphics g ) – Este método é chamado pela Virtual Machine para mostrar objectos no ecrã. O parâmetro ”Graphics” é o objecto que será renderizado no Canvas. Note-se que o paint nunca deve ser chamado manualmente; • keyReleased( int keyCode ) – funciona do mesmo modo que o keyPressed, mas é activado quando uma tecla é solta; Um esquema mais geral das classes existentes e disponíveis para o programador, pode ser visto na imagem que se segue: Figura 7. 6 - Esquema de classes 92 Desenvolvimento Limites a ter em consideração Uma ultima coisa que se deve fazer antes de se proceder ao desenvolvimento da MIDlet, é relembrar algumas das limitações da plataforma para onde se está a programar. Algumas das considerações mais importantes são as seguintes: • • • • • • Não acreditar no mito que diz que o MIDP não suporta imagens transparentes. A maior parte dos dispositivos e emuladores suporta imagens transparentes e mesmo alguns telemóveis Nokia suportam transparências com a variável alpha; O MIDP não suporta operações com virgula flutuante, e por isso, não suporta tipos de dados como Double ou Float; O número de cores mais comuns para telemóveis é 4096; A maior parte dos dispositivos não suporta que várias teclas sejam premidas simultaneamente; Deve-se ter cuidado com o tamanho das aplicações. Para telemóveis com ecrã a cores, uma aplicação não deve exceder os 64 KB para manter a compatibilidade; Deve-se tentar reduzir ao máximo o número de classes da aplicação. Cada classe aumentará o espaço ocupado pela aplicação e o seu consumo de memória; Note-se que o lançamento do MIDP 2.0 veio reduzir consideravelmente a lista de limitações do J2ME. Com a versão 2.0 deste perfil, foram lançadas inúmeras funcionalidades (algumas já referidas), nomeadamente a nível gráfico e de manipulação de imagens, que vieram facilitar o desenvolvimento de aplicações que requeiram um maior detalhe a nível visual, como é o caso dos jogos. Posto isto, pode-se proceder com o desenvolvimento de uma aplicação em J2ME que, neste caso, será um pequeno jogo. Foi escolhido um jogo para este exemplo por diversas razões. Em primeiro lugar, é o tipo de aplicação mais comum nesta tecnologia. Pode-se dizer que mais de 80% das aplicações desenvolvidas para telemóveis (não só em J2ME) são jogos, e são estes que dominam actualmente o mercado e as preferências dos programadores. Em segundo lugar, o desenvolvimento deste tipo de aplicação é mais atractivo para a maioria dos programadores. O tema é mais apelativo e toda a lógica da aplicação é de fácil compreensão. Por último, é este tipo de aplicações que tira melhor partido de todas as funcionalidades oferecidas pelos dispositivos. Um jogo requer sempre uma grande componente de interacção com o utilizador, bons recursos sonoros e uma apresentação visual mais cuidada. Tal como já acontece nos PCs, são os jogos que vão explorar ao máximo as capacidades ao nível do hardware disponibilizadas pelos dispositivos. 93 Tecnologia Java aplicada a telemóveis 7.3. Desenvolvimento de uma MIDlet Para criar a MIDlet, será utilizado o J2ME Wireless Toolkit com todas as suas ferramentas. Como já foi referenciado, a ferramenta mais importante é a KToolbar que será utilizada para criar e gerir os projectos MIDlet. Em primeiro lugar, tal como foi feito com o “HelloWorld”, será criado um novo projecto na KToolbar, com a opção “New Project...”: Figura 7. 7 - Criação do projecto MyGame O projecto criado tem o nome “MyGame” e a classe principal da MIDlet chamar-se-á “Startup”. Agora é necessário definir alguns atributos referentes à MIDlet criada. Figura 7. 8 - Definição dos atributos da MIDlet MyGame Estes são os atributos principais da MIDlet. Esta informação é obrigatória e, para facilitar a operação, já são sugeridos alguns valores para estes atributos. 94 Desenvolvimento Os atributos aqui apresentados correspondem ao seguinte: • MIDlet-Jar-Size – Este é um atributo do JAD, que deve reflectir o número exacto de bytes que ocupa o ficheiro JAR. Se a criação do ficheiro JAR for feita através da KToolbar, este valor é tratado automaticamente. Note-se que, se o valor não corresponder à realidade, não será possível instalar a MIDlet; • MIDlet-Jar-URL – Este atributo corresponde ao URL do ficheiro JAR. Normalmente basta indicar o nome do ficheiro; • MIDlet-Name – O nome da MIDlet que aparecerá na lista de MIDlets do telemóvel; • MIDlet-Vendor – O nome do programador ou da empresa que desenvolveu a MIDlet; • MIDlet-Version – A versão corrente da MIDlet; • MicroEdition-Configuration – A configuração usada pela MIDlet; • MicroEdition-Profile – O perfil usado pela MIDlet Quando completado o processo de criação de um novo projecto, aparecerá na consola a seguinte informação: Figura 7. 9 - Resultado da criação do projecto MyGame Isto quer dizer que a KToolbar criou a estrutura de directórios para o projecto. Os projectos da KToolbar são colocados na sua própria directoria, dentro de “apps”. Agora, o código fonte criado para esta aplicação deve ser colocado em “src”, dentro da directoria do projecto. 95 Tecnologia Java aplicada a telemóveis Criação de uma MIDlet básica Para começar, será criado uma MIDlet muito simples. Na pasta “src” será criado o ficheiro “Startup.java” que contém a classe principal da MIDlet. A classe Startup é uma extensão de “javax.microedition.midlet.MIDlet”, que possui três métodos abstractos que necessitam de ser implementados. Estes métodos são responsáveis pelo controlo do ciclo de vida das MIDlets. O código fonte contido no ficheiro “Startup.java”, é o seguinte: Startup.java import javax.microedition.midlet.*; public class Startup extends MIDlet { /*Constructor utilizado pelo AMS para criar uma instância da classe MIDlet principal.*/ public Startup() { // Imprime uma mensagem na consola quando o Startup é criado. System.out.println("Constructor: Startup()"); } /*O startApp() é chamado pelo AMS depois de criar com sucesso a instância da classe MIDlet. O startApp() faz com que a MIDlet transite para o estado Activo.*/ protected void startApp() throws MIDletStateChangeException { // Imprime uma mensagem na consola quando o Startup é chamado. System.out.println("startApp()"); } /*O destroyApp() é chamado pelo AMS quando a MIDlet é destruida (terminada).*/ protected void destroyApp( boolean unconditional ) MIDletStateChangeException { } throws /*O pauseApp() é chamado pelo AMS quando a MIDlet é parada. Note-se que este não é um pause típico de um jogo, mas sim um pause que funciona no ambiente da própria aplicação. O exemplo mais comum acontece quando é recebida uma chamada e a aplicação tem que ser interrompida. Aqui são tomadas as devidas precauções para salvaguardar o estado e a integridade da aplicação.*/ protected void pauseApp() { } } 96 Desenvolvimento Compilação, pré-verificação e execução Para compilar o código fonte do projecto (actualmente apenas o “Startup.java” basta escolher a opção “Build”. O que a KToolbar faz agora, é compilar o código com as APIs do MIDP e do CLDC (com todas as librarias contidas na pasta “lib” do emulador seleccionado) para uma pasta chamada “tmpclasses”. O comando executado é muito similar ao seguinte: Javac –d tmpclasses –bootclasspath %wtk%\lib\midpapi.zip – classpath tmpclasses;classes src\*.java O próximo passo dado pela KToolbar é fazer a pré-verificação dos ficheiros “class” e colocá-los na pasta “classes” do projecto. Os ficheiros “class” devem ser pré-verificados antes de executados num dispositivo MIDP. O comando executado é o seguinte: preverify clases –classpath %wtk%\lib\midpapi.zip tmpclasses –d O “preverify.exe” é uma ferramenta disponibilizada pelo WTK e encontrase na pasta “bin”. Agora que a MIDlet foi compilada e pré-verificada, pode ser corrida através da opção “Run”. Visto que para já, a única coisa que a MIDlet faz é imprimir duas linhas de texto na consola, não se vai observar nada no emulador. No entanto, a consola deverá mostrar o seguinte: Figura 7. 10 - Execução do MyGame Isto demonstra que a classe “Startup” foi criada pelo construtor e, depois disso, foi chamado o “startApp()”. Embora não contenha muita funcionalidade, esta MIDlet é importante para começar e ter uma percepção de como as coisas funcionam. 97 Tecnologia Java aplicada a telemóveis Forms e Commands Forms e Commands, são componentes de alto nível do interface de utilizador, que podem ser úteis para construir menus e mostrar instruções do jogo no ecrã. A classe “Form” é uma subclasse de “Displayable”, o que quer dizer que pode ser mostrada directamente no ecrã do dispositivo. O Displayable do dispositivo pode ser utilizado com a ajuda da classe “Display”. Para obter uma referência para o objecto “Display”, pode ser chamado o método estático “getDisplay()” na classe “Display”. O método leva um parâmetro que é uma referência para uma instância da classe “MIDlet”: Display display = Display.getDisplay( midletInstance ); Agora pode ser atribuído o “display” a qualquer objecto que seja uma extensão de “Displayable” chamando: display.setCurrent( nextDisplayable ); Sabendo isto, pode-se proceder à construção de um form que será posteriormente mostrado. Em primeiro lugar é necessário criar o form. A maneira mais fácil para isto é criar um form vazio com um título: Form basicForm = new Form( “Form Title” ); É então acrescentada uma string ao form, fazendo o seguinte: basicForm.append( “My Form” ); Agora é preciso mostrar o form: display.setCurrent( basicForm ); Agora basta inserir isto no método “StartApp()”, que é o primeiro método a ser chamado quando a MIDlet é executada. Visto que as classes “Form” e “Display” pertencem ao package ”javax.microedition.lcdui”, este deve ser importado no ficheiro de código. 98 Desenvolvimento Depois do código compilado e executado, obtém-se o seguinte resultado: Figura 7. 11 - Criação de um form Agora que se criou o form, irá ser criado um Command de modo a obter alguma interacção de alto nível com o utilizador. O Command irá permitir ao utilizador gerar um número aleatório, e mostra-lo no form criado. Antes de mais, convém saber que um Command é um componente que despoleta uma acção na MIDlet. Para capturar um evento despoletado quando um utilizador activa o Command, é necessário utilizar o interface “CommandListener”. Este interface define um método que é necessário implementar: commandAction( Command c, Dislayable d ); Quando o utilizador faz com que o Command seja despoletado, a implementação chama o método “commandAction” do “CommandListener” associado. O “CommandListener” é activado pelo método “setCommandListener()” no Displayable onde o Command foi adicionado. appendCommand = new Command( “Random”, Command.SCREEN, 0 ); O construtor “Command” leva três parâmetros: a string associada ao Command; o tipo de Command (indica à implementação qual o tipo de acção que este Command irá realizar o que, por vezes, afecta a localização do Command no ecrã); e a prioridade (ou ordem de display) associada ao Command . O Command será então adicionado ao Form (como o método “addCommand()” é herdado de Displayable, todos os Displayables podem ter Commands). basicForm.addCommand( appendCommand ); 99 Tecnologia Java aplicada a telemóveis Agora que o Command foi adicionado ao Form, o próximo passo é activar o CommandListener do Form. A classe “Startup” terá que implementar o CommandListener e ignorar o método “commandAction()”, para executar estas acções. basicForm.setCommandListener( this ); Visto que a intenção é gerar um número aleatório, é necessário acrescentar um gerador de números aleatórios à aplicação. Para isto, é necessário importar o “java.util.Random” e criar um novo gerador: generator = new Random( System.currentTimeMillis() ); Isto cria um gerador de números aleatórios que se irá basear no tempo actual do sistema, em milisegundos. Método commandAction public void commandAction( Command c, Displayable d ) { /*verifica se o evento commandAction é despoletado pelo appensCommand*/ if( c == appendCommand ) { /*adiciona uma string ao form, com um número aleatório entre 0 e 50.*/ basicForm.append("Random: " + ( Math.abs( generator.nextInt() ) %50 ) + "\n"); } } Agora basta compilar o código e executar. O resultado obtido será o seguinte: Figura 7. 12 - Geração de um número aleatório Neste caso, o número sorteado foi o 21!Esta foi uma breve introdução aos componentes de alto nível da API MIDP. Assim, de um modo simples, é possível obter input do utilizador e mostrar informação no ecrã. 100 Desenvolvimento Canvas O aspecto mais importante num jogo, é talvez a habilidade de desenhar coisas no ecrã, sejam estas os personagens, objectos ou cenário. Para fazer isto no MIDP, é necessário recorrer ao uso das classes “Canvas”, “Graphics” e “Image”. Estas classes são utilizadas para processamento gráfico de baixo nível. “Canvas” é uma classe abstracta e, por isso, deve conter uma subclasse para que possa ser utilizada. Será então criada uma nova classe denominada “GameScreen” que é uma extensão de Canvas. Como foi visto anteriormente, a classe “Canvas” define o método abstracto “paint( Graphics g )”. No entanto, na classe “GameScreen” criada, este método vai ser ignorado, o que vai permitir desenhar no objecto “Graphics” passado ao método “paint()” pela Virtual Machine. Isto deixa a classe “GameScreen” com o seguinte código: GameScreen import javax.microedition.lcdui.*; public class GameScreen extends Canvas { //Construtor para a classe GameScreen. public GameScreen() { } //Chamado quando o Canvas está a ser desenhado protected void paint( Graphics g ) { } } Agora que já foi criado o básico para desenhar no ecrã, será implementado o input para utilizador. A classe “Canvas” define três métodos que controlam eventos das teclas: “keyPressed()”, “keyReleased()”, “keyRepeated()”. O Canvas contém implementações vazias para estes métodos, por isso, cabe ao programador desenvolvê-los da maneira que achar mais adequada. Eventos das teclas // Chamado quando uma tecla é pressionada neste canvas protected void keyPressed( int keyCode ) { } // Chamado quando uma tecla é libertada neste canvas protected void keyReleased( int keyCode ) { } 101 Tecnologia Java aplicada a telemóveis Como pode ser observado, só foram implementados os eventos “keyPressed()”, “keyReleased()” e não o “keyRepeated()”. Não se deve confiar muito no evento “keyRepeated()”, pois a frequência da chamada a este método varia muito de aparelho para aparelho. De qualquer modo, este evento não é fiável para verificar se o utilizador está continuamente a pressionar uma tecla ou não. Agora já está tudo pronto para obter informação do utilizador e desenhar no ecrã, mas antes de continuar, é necessário certificar de que se sabe o modo como o Canvas será mostrado no ecrã. Para isso, a classe “Startup” feita anteriormente sofrerá algumas alterações. Agora, esta classe serve apenas como ponto de entrada à aplicação, e cria e mostra uma nova instância da classe “GameScreen”. Startup protected void startApp() throws MIDletStateChangeException { Display display = Display.getDisplay( this ); /*GameScreen é uma extensão de Canvas que, por sua vez, estende de Displayable para que possa ser mostrado ditrectamente no ecrã.*/ display.setCurrent( new GameScreen() ); } Um novo GameScreen está a ser criado e mostrado. Agora podem ser testados alguns métodos primitivos de desenho, disponibilizados pela classe “Graphics”. Definição de uma cor para o cenário //definir a cor actual do contexto gráfico para um azul escuro //0xRRGGBB g.setColor( 0x000088 ); /*desenhar um rectângulo preenchido, nas coordenadas 0(x), 0(y), com um comprimento e uma altura iguais aos do Canvas.*/ g.fillRect( 0, 0, this.getWidth(), this.getHeight() ); Ao definir a cor através do “setColor( int rgbColor )”, irão ser afectadas todas as operações de renderização subsequentes a este contexto gráfico. Deste modo, a chamada do “fillRect( x, y, width, height )” vai desenhar um rectângulo preenchido da cor seleccionada. Isto também introduz dois métodos de alguma importância, pertencentes à classe “Canvas”: “getWidth()” e “getHeight()”. Estes métodos são usados para obter o espaço total disponível para desenhar no canvas. Estes métodos são especialmente úteis quando se pretende desenvolver aplicações destinadas a diferentes aparelhos em que haja variação do tamanho dos ecrãs. 102 Desenvolvimento É aconselhável utilizar estes métodos em vez de forçar os valores do tamanho do ecrã, pois deste modo vai ser mais fácil portar a aplicação para outro telemóvel distinto. Do mesmo modo, também é aconselhável fazer com que todos os objectos desenhados no ecrã sejam relativos à altura e comprimento do Canvas. O aspecto final destas alterações é o seguinte: Figura 7. 13 - Primeira utilização do Canvas Input Só para se ter uma ideia do modo de manuseamento dos eventos associados às teclas, serão feitas algumas alterações ao programa anterior para que o rectângulo preenchido mude de cor conforme a tecla pressionada. Deste modo, o rectângulo terá as seguintes teclas associadas às cores: • Vermelho – Esquerda; • Verde – Direita; • Preto – Cima; • Branco – Baixo; • Azul – Fogo; Como já foi referenciado, um evento associado a uma tecla pressionada, é representado por um valor inteiro (int) que reflecte o código da tecla pressionada pelo utilizador. Este código pode ser tratado de duas maneiras diferentes: ou através do seu valor real (KEY_NUM0 a KEY_NUM9, KEY_STAR ou KEY_POUND que perfazem o teclado de um telemóvel tradicional); ou através do seu valor associado ao jogo (UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B, GAME_C, GAME_D). Mas porquê estas duas opções? Isto deve-se ao facto de existirem inúmeras configurações diferentes dos teclados dos telemóveis. Ao utilizar o valor das teclas através do seu valor de jogo associado, permite a identificação das teclas de um modo mais portável. 103 Tecnologia Java aplicada a telemóveis Para obter o código das teclas associado ao jogo, é utilizado o método “getGameAction( int keyCode )” da classe “Canvas”. Manuseamento de eventos das teclas //Chamado quando o Canvas é mostrado protected void paint( Graphics g ) { /*definir a cor actual do contexto gráfico para o valor RGB associado*/ g.setColor( colour ); /*desenha um rectângulo preenchido em x, y com as coordenadas 0,0 e com comprimento e altura do Canvas*/ g.fillRect( 0, 0, this.getWidth(), this.getHeight() ); } //Chamado quando uma tecla é pressionada no Canvas actual protected void keyPressed( int keyCode ) { //obtém o código da tecla associada ao jogo int gameAction = getGameAction( keyCode ); switch( gameAction ) { case LEFT: //Muda a cor actual para vermelho colour = 0xFF0000; break; case RIGHT: //Muda a cor actual para verde colour = 0x00FF00; break; case UP: //Muda a cor actual para preto colour = 0x000000; break; case DOWN: //Muda a cor actual para branco colour = 0xFFFFFF; break; case FIRE: //Muda a cor actual para azul colour = 0x0000FF; break; } /*como ainda não foi definido nenhum loop para o jogo, é necessário redesenhar o Canvas de cada vez que se prime uma tecla.*/ repaint(); } 104 Desenvolvimento O resultado obtido será então o seguinte: Figura 7. 14 - Tecla "cima" Figura 7.16 - Tecla "esquerda" Figura 7. ~15 – Tecla “baixo” Figura 7. 15 - Tecla "disparo" Figura 7. 14 - Tecla "direita" Ao olhar para a última linha do método “keyPressed()” vê-se uma chamada ao “repaint()” que serve para forçar o canvas a ser redesenhado. Normalmente isto não seria feito no método “keyPressed()” mas sim no fim do loop do jogo. 105 Tecnologia Java aplicada a telemóveis Loop A classe “Thread” será usada para reactivar a thread do jogo que irá ser utilizada para o loop principal. Existem dois modos diferentes de criar threads. Uma das hipóteses é criar uma subclasse de “Thread” e ignorar o método “run()” da classe “Thread”, mas como aqui não são possíveis múltiplas heranças (e a classe “GameScreen” já é uma extensão de “Canvas”) vai ser utilizado o segundo método. Assim, será implementado o interface “Runnable” e o seu método “run()”. Isto quer dizer que se pode criar um novo thread passando a instância da classe “GameScreen” (que implementa o “Runnable”) para o construtor do thread. Criação de um novo thread //Constructor para a classe GameScreen. public GameScreen() { //Cria um novo thread e começa-o imediatamente new Thread( this ).start(); } /*O método run() definido no interface Runnable, chamado pela Virtual Machine quando a thread é iniciada.*/ public void run() { } Agora, ao construir o GameScreen, vai ser criado e iniciado um novo thread que despoleta uma chamada ao método “run()”. É porém pretendido que o loop principal seja chamado em intervalos fixos de tempo e, para este exemplo, será estipulado o intervalo de 15 vezes por segundo (embora seja impossível definir com precisão um intervalo de tempo fixo que possa ser aplicado a todos os jogos, 15fps (frames per second) é um indicativo médio razoável para começar). Dentro do método “run()” está implementada a lógica de temporização para o loop. Lógica de temporização para o loop /*Método run() definido no interface Runnable, chamado pela Virtual Machine quando o thread é iniciado*/ public void run() { //definir o atraso do loop para 1/15 segundos int loopDelay = 1000 / 15; while( true ) { //apanhar o tempo no início do loop long loopStartTime = System.currentTimeMillis(); /*chamar a função tick() que funcionará como o bater do coração 106 Desenvolvimento para o jogo*/ tick(); //apanhar o tempo no final do loop long loopEndTime = System.currentTimeMillis(); //calcular a diferença do tempo entre o início e o fim do loop int loopTime = (int)(loopEndTime - loopStartTime); //se a diferença for maior do que a desejada if( loopTime < loopdelay ) { try { /*então o programa adormece durante o tempo suficiente para completar o desejado*/ thread.sleep( loopdelay - looptime ); } catch( exception e ) { } } } } public void tick() { } Para testar o loop, será feita uma pequena alteração ao programa anterior para que o cenário mude para uma cor aleatória em cada frame. Pode-se aproveitar a ocasião para posicionar o “repaint” no loop do jogo. Aplicação do loop // o loop chamado num intervalo fixo de tempo pelo thread do jogo public void tick() { //obter um número aleatório dentro dos limites das cores RRGGBB colour = generator.nextInt() & 0xFFFFFF; //fazer o repaint do canvas repaint(); /*força que cada repaint pendente tratado e bloqueia até ao retorno do paint()*/ serviceRepaints(); } Como resultado, a imagem de fundo do ecrã estará a variar constantemente entre diversas cores aleatoriamente. 107 Tecnologia Java aplicada a telemóveis Imagens As imagens no MIDP são extremamente fáceis de utilizar. O modo mais fácil é chamar o método estático “createImage( String name )” da classe “Image”. A string passada ao método, corresponde à localização da imagem no ficheiro JAR da MIDlet. Deste modo, a primeira coisa a fazer é criar uma imagem para ser posteriormente usada no jogo. O tipo de imagem suportada pelo MIDP é “PNG”. Ao usar a KToolbar, a única coisa que é preciso fazer é colocar o ficheiro de imagem na directoria “res” do projecto. Neste caso, será criada uma imagem com o nome “sprite.png” e será colocada na directoria correspondente. A imagem será a seguinte: Figura 7. 169 - Imagem PNG que será utilizada Normalmente as imagens devem ocupar o menos espaço possível e, para isso, existem vários truques possíveis. Para ganhar mais alguns bytes, a imagem pode ser optimizada por exemplo com o “XAT Image Optimizer” ou com o “PNGCrush” que são ferramentas que chegam a conseguir uma optimização de 30%. Note-se que, para imagens transparentes (aliás, como é o caso), é necessário que sejam PNGs de 24 bits. A criação da imagem é feita do seguinte modo: Criação de uma imagem try { myImage = Image.createImage("/sprite.png"); } catch( Exception e ) { e.printStackTrace(); } A criação de imagens demora tempo e ocupa muita memória, pelo que deve ser feita em áreas controladas da aplicação. Para desenhar uma imagem criada no ecrã, é usado o método “drawImage()” da classe “Graphics”. g.drawImage( myImage, x, y, Graphics.top | Graphics.left ); 108 Desenvolvimento O parâmetro “Graphics.top | Graphics.left” é chamado “âncora”. Aqui é definido como a imagem deve ser desenhada, relativamente às coordenadas x e y. A constante “Graphics.top” faz com que o topo da imagem esteja na coordenada y, e a constante “Graphics.left” faz com que a parte esquerda da imagem corresponda à coordenada x. Deste modo, se se pretende colocar a imagem no centro do ecrã, deve-se definir a “âncora” para os centros vertical e horizontal do ecrã. g.drawImage( myImage, this.getWidth()/2, this.getHeight()/2, Graphics.VCENTER | Graphics.HCENTER ); Depois do código compilado e corrido, será obtido o seguinte resultado: Figura 7. 20 - Utilização de imagens A imagem escolhida está colocada no centro do ecrã, os botões direccionais e o botão “select”, mudam a cor de fundo. Double Buffering Para evitar irregularidades quando alguma coisa está a ser desenhada no ecrã (imagem a piscar) têm que ser utilizadas as já conhecidas técnicas de “double buffering”, em que todos os objectos são renderizados fora do ecrã, e só depois mostrados. Algumas implementações fazem já o “double buffering” automaticamente. É possível verificar se um aparelho faz “double buffering” automaticamente, através do método “isDoubleBuffered()” do Canvas. A vantagem de se saber se o “double buffering” é ou não automático é que este é um procedimento que ocupa algum espaço e memória, pelo que é bom evitar quando possível. Pode-se facilmente adaptar o código aos dois casos possíveis. Enquanto são carregadas e criadas todas as imagens, pode também ser criado o buffer se necessário. 109 Tecnologia Java aplicada a telemóveis Teste de “double buffer” //Cria todas as imagens. É chamado na criação da classe GameScreen public void createImages() { try { //se o aparelho não faz double buffering automático if( !isDoubleBuffered() ) { //cria uma imagem for a do ecrã bufferImage = Image.createImage( getWidth(), getHeight() ); /* apanha o contexto Graphics onde pode ser renderizado a imagem do buffer */ buffer = bufferImage.getGraphics(); } myImage = Image.createImage("/sprite.png"); } catch( Exception e ) { e.printStackTrace(); } } É criada uma nova imagem vazia com a chamada de “Image.createImage(width, height)”. Esta imagem deve ter exactamente o mesmo tamanho da área visível do Canvas. No MIDP existem imagens mutáveis e imutáveis. A diferença é que as imagens imutáveis, criadas a partir de ficheiros, não podem ser modificadas depois de criadas. Uma imagem mutável, normalmente criada através da chamada de “Image.createImage(width, height)” pode ser modificada, obtendo o contexto “Graphics” onde será renderizada. Isto é feito chamando o “getGraphics()” da imagem, e foi este o procedimento para o segundo buffer. Com umas pequenas alterações ao método “paint()” podem ser tratados os aparelhos que não fazem “double buffering” automático. Double buffering // Chamado quando o Canvas vai ser mostrado protected void paint( Graphics g ) { //mantém uma referência para o contexto Graphics original Graphics original = g; // se o aparelho não faz double buffering automático if( !isDoubleBuffered() ) { /*muda a referência ao objecto g para o segundo buffer do contexto Graphics*/ g = buffer; } //Define a cor do contexto Graphics para a cor RRGGBB especificada 110 Desenvolvimento g.setColor( colour ); /*desenha um rectângulo a cheio em x, y com as coordenadas 0, 0 e uma altura e largura iguais ás do Canvas*/ g.fillRect( 0, 0, this.getWidth(), this.getHeight() ); //desenha uma imagem no centro do ecrã g.drawImage( myImage, this.getWidth()/2, this.getHeight()/2, Graphics.VCENTER | Graphics.HCENTER ); if( !isDoubleBuffered() ) { //desenha a imagem fora do ecrã no contexto Graphics original original.drawImage( bufferImage, 0, 0, Graphics.TOP | Graphics.LEFT ); } } Inicialmente, este procedimento pode parecer um pouco confuso mas, em resumo, foi feito o seguinte: em cima do método “paint()”, é mantida uma referência ao contexto “Graphics” original que é passado como parâmetro ao método. Em seguida, foi verificado se realmente era necessário fazer double buffering e, em caso afirmativo, é mudado o contexto “Graphics” referenciado pela variável “g”, para o contexto “Graphics” obtido a partir da imagem do buffer. No final do método “paint()” é novamente verificado se é necessário fazer double buffering e é desenhada a imagem do buffer no contexto “Graphics” guardado anteriormente. Para acabar, é adicionada alguma funcionalidade de movimentação à imagem, de forma a obter uma interacção mais interessante com o utilizador. Double buffering //Chamado quando uma tecla é pressionada no Canvas corrente protected void keyPressed( int keyCode ) { //apanha o código das teclas associadas ao jogo int gameAction = getGameAction( keyCode ); switch( gameAction ) { case LEFT: //move imagem para a esquerda imageDirection = LEFT; break; case RIGHT: // move imagem para a direita imageDirection = RIGHT; break; 111 Tecnologia Java aplicada a telemóveis case UP: // move imagem para cima imageDirection = UP; break; case DOWN: // move imagem para baixo imageDirection = DOWN; break; case FIRE: //muda o cenário para uma cor aleatória colour = generator.nextInt()&0xFFFFFF; break; } } //O loop principal do jogo, chamado num intervalo fixo de tempo public void tick() { int myImageSpeed = 4; switch( imageDirection ) { case LEFT: myImageX-=myImageSpeed; break; case RIGHT: myImageX+=myImageSpeed; break; case UP: myImageY-=myImageSpeed; break; case DOWN: myImageY+=myImageSpeed; break; } //faz o repaint do Canvas repaint(); /*força que cada repaint pendente tratado e bloqueia até ao retorno do paint()*/ serviceRepaints(); } 112 Desenvolvimento O resultado final será o seguinte: Figura 7. 21 - Movimentação da imagen no ecrã: "cima"+"esquerda" Figura 7. 22 - Movimentação da imagem no ecrã: "baixo"+"direita" A nave move-se em todas as direcções (cima, baixo, esquerda e direita), e a tecla de disparo faz com que o fundo mude para uma côr aleatória. O código completo desta aplicação, pode ser consultado em anexo. Instalação Agora que a aplicação está desenvolvida, é necessário que seja instalada num telemóvel. Existem muitos métodos para fazer isto. Normalmente os programadores recorrem ao uso de cabos serie ou USB, e software fornecido pelo fabricante, para transmitir dados directamente do computador para o telemóvel, ou transmissão via infravermelhos. Também é possível instalar a aplicação num servidor, para que depois possa ser descarregada para o telemóvel. Neste caso é necessário verificar se o servidor reconhece ficheiros JAR e JAD. Esta hipótese é normalmente denominada de “OTA Provisioning” (Over The Air Provisioning). A KToolbar permite testar a instalação de aplicações vis OTA. Para isso, basta abrir o projecto correspondente à aplicação que se pretende testar (neste caso, “MyGame”), e escolher a opção “Run via OTA” do menu “Project” da KToolbar. Isto corre automaticamente o servidor OTA da KToolbar, assim como o emulador. Aqui, o emulador não estará a correr a aplicação mas sim o seu AMS (Application Management Software). É a partir daqui que será simulada a instalação da aplicação. 113 Tecnologia Java aplicada a telemóveis Figura 7. 23 - Ecrã inicial do AMS No emulador, depois de premir a tecla correspondente a “Apps”, aparecerá o seguinte menu: Figura 7. 24 - Instalar a aplicação Como não existe nenhuma aplicação no telemóvel, a única hipótese é fazer a instalação de uma nova aplicação. O passo seguinte é premir o botão “Menu” e escolher a opção “Launch”. 114 Desenvolvimento Figura 7. 25 - Introdução da localização da aplicação Este ecrã pede a localização do jogo que se pretende instalar. Neste caso, o emulador sugere automaticamente o endereço do jogo, visto que ele próprio é o servidor. No caso de ser uma instalação num telemóvel, terá que ser especificado o endereço real de onde se encontra a aplicação. Para continuar a instalação, terá que ser escolhida a opção “Go” do “Menu”. Figura 7. 26 - Escolha da aplicação a instalar Agora é dada a opção do utilizador escolher a aplicação que pretende instalar. Para continuar terá que ser escolhida a opção “Install”. 115 Tecnologia Java aplicada a telemóveis Figura 7. 177 - Confirmação da instalação Este é o ecrã de confirmação. Aqui é mostrada alguma informação acerca da aplicação a instalar, e pedida a confirmação ao utilizador. Ao seleccionar a opção “Install” o jogo irá ser, finalmente, instalado. Figura 7. 28 - Execução do jogo Agora, como se pode constatar, o jogo está instalado no dispositivo. Para correr basta seleccionar a opção “Launch” do menu. Apesar disto, a verdadeira intenção deste tipo de aplicação, é ser instalada mesmo num telemóvel. Para isso, antes de ser descarregada via OTA, os ficheiros referentes ao jogo devem ser colocados num servidor público apropriado, que esteja acessível na internet. Para que seja possível o download de aplicações deste tipo, o servidor deve reconhecer os tipos de ficheiro associados (JAD e JAR). Deste modo, a extensão JAD deve estar mapeada com o tipo ”text/vnd.sun.j2me.appdescriptor” e a extensão JAR, deve estar mapeada com o tipo ”application/javaarchive”. Note-se que as versões 4.0 ou superior do servidor Tomcat já incluem estes mapeamentos nas suas configurações. Agora basta proceder como foi feito com o simulador e correr e jogar. 116 8. Conclusão A programação destinada a plataformas moveis está ainda a dar os seus primeiros passos. Por outro lado, os telemóveis estão a ganhar importância na vida das pessoas e a perder as suas muitas limitações. Hoje em dia, estão constantemente a surgir novos telemóveis com mais potencialidades e tecnologias mais capazes e com mais funcionalidades, que permitem o desenvolvimento de aplicações mais poderosas. Prevê-se que futuramente os telemóveis continuem a evoluir e, consequentemente, se tornem numa ferramenta indispensável no dia-a-dia, tanto a nível de trabalho, como de lazer. As pessoas vão cada vez mais depender destes pequenos aparelhos para realizar as mais diversas funções. Por isso, do ponto de vista dos programadores, é uma tecnologia que actualmente merece uma especial atenção. A programação destinada a este tipo de dispositivos ainda tem um longo caminho a percorrer, e cabe aos programadores explorar as capacidades das linguagens disponíveis e dos aparelhos. Esta é uma área na qual se pode apostar, devido ao crescimento que se tem vindo a observar nos últimos tempos e ás perspectivas futuras. As marcas de telemóveis estão a desenvolver aparelhos mais potentes e sofisticados, enquanto empresas como a Sun ou até a Microsof” desenvolvem novas linguagens de programação que consigam tirar melhor partido das tecnologias e permitir aos programadores obter melhores resultados. Também a introdução dos telemóveis no universo das consolas de jogos (Nokia N-Gage) eleva esta tecnologia a um outro nível. A maior parte dos consumidores de telemóveis topo de gama, são pessoas que se interessam por jogos e outros tipos de aplicações de lazer. Além disso, os jogos atraem muitos programadores amadores que desenvolvem aplicações e ajudam a expansão desta tecnologia conseguindo ganhar algum dinheiro com isso. O J2ME é actualmente a tecnologia mais utilizada pelos programadores e com mais suporte a nível de telemóveis, o que faz com que seja líder no desenvolvimento deste tipo de aplicações. Embora tenha uma forte concorrência, a Sun está empenhada em continuar com a evolução tecnologia J2ME que merece por isso muita atenção por parte dos programadores. Tecnologia Java aplicada a telemóveis 118 9. Bibliografia • Sun [Online] – Site de referência da linguagem Java da Sun Disponível na WWW: <java.sun.com>. • Nokia [Online] – Site oficial da Nokia Disponível na WWW: <www.nokia.com>. • Sony Ericsson [Online] – Site oficial da Sony Ericsson portuguesa Disponível na WWW: <www.sonyericsson.com/pt>. • Samsung [Online] – Site oficial da Samsung Disponível na WWW: <www.samsung.com>. • Panasonic [Online] – Site oficial da Panasonic Disponível na WWW: <www.panasonic.com/consumer_electronics/cellular/default.asp>. • Siemens [Online] – Site oficial de telemóveis Siemens Disponível na WWW: <www.siemens.com/index.jsp?sdc_p=dpo1071950fcls2mnt4u&sdc_sid= 22824419811>. • Motorola [Online] – Site oficial da Motorola Disponível na WWW: <www.motorola.com>. • Sagem [Online] – Site oficial da Sagem Disponível na WWW: <www.sagem.com/en>. • KObjects [Online] – Lista de dispositivos e suas características Disponível na WWW: <www.kobjects.org/devicedb>. • In-Fusio [Online] – Site oficial do ExEn Disponível na WWW: <www.developer.in-fusio.com>. • Synergenix [Online] – Site oficial do Mophun Disponível na WWW: <www.mophun.com>. • TTPCom [Online] – Site oficial da TTPCom Disponível na WWW: <www.ttpcom.com>. • 9Dots [Online] – Site oficial do WGE Disponível na WWW: <www.9dots.net>. • Symbian [Online] – Site oficial do Symbian Disponível na WWW: <www.symbian.com>. Tecnologia Java aplicada a telemóveis 120 • Ultra Edit [Online] – Site oficial do Ultra Edit (ferramenta de programação Java) Disponível na WWW: <www.ultraedit.com>. • Eclipse [Online] – Site oficial do Eclipse (ferramenta de programação Java) Disponível na WWW: <www.eclipse.org>. • JBuilder [Online] – Site oficial do JBuilder programação Java da Boreland) Disponível na WWW: <www.boreland.com/jbuilder>. • Midlet Org [Online] – Repositório de MIDlets e oportunidade de publicidade a jogos Disponível na WWW: <www.midlet.org>. • Billday [Online] – Recursos e informação de J2ME Disponível na WWW: <www.billday.com/j2me>. • MIDlet Review [Online] – Site de crítica a MIDlets Disponível na WWW: <www.midlet-review.com>. • Macrospace [Online] – Jogos comerciais da Macrospace Disponível na WWW: <games.macrospace.com>. • Microjava [Online] – Site de notícias tutoriais e artigos de J2ME Disponível na WWW: <www.microjava.com>. • IGN [Online] – Secção de jogos wireless da IGN Disponível na WWW: <wireless.ign.com>. • Qualcomm [Online] – Informação referente a Brew Disponível na WWW: <www.qualcomm.com/brew>. • Motocoder [Online] – Site de desenvolvimento da Motorolla Disponível na WWW: <www.motocoder.com>. • John W. Muchow – “Core J2ME Technology & MIDP”. Sun Microsystems, 2001. • “J2ME: Step by step”. IBM Developer Networks. • “MIDlet development with J2ME and MIDP”. IBM Developer Networks. • Michael Taylor – “J2ME IDE Comparison”. Developnet Consulting Limited, 2002. • Monica Pawla – “Essencials of Java Programing Language: A Hands-On Guide, Part 1”. Sun. (ferramenta de Anexo • Java Comunity Process [Online] – Site da comunidade Java Disponível na WWW: <jcp.org>. 121 Tecnologia Java aplicada a telemóveis 122 10. Anexo Código fonte referente ao jogo desenvolvido no capítulo 7 – “MyGame” Startup.java import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class Startup extends MIDlet { /*Constructor utilizado pelo AMS para crier uma instância da classe MIDlet principal*/ public Startup() { } /* O startApp() é chamado pelo AMS depois de criar com sucesso a instância da classe MIDlet. O startApp() faz com que a MIDlet transite para o estado Activo. */ protected void startApp() throws MIDletStateChangeException { Display display = Display.getDisplay( this ); /*GameScreen é uma extensão de Canvas que, por sua vez, estende de Displayable para que possa ser mostrado ditrectamente no ecrã.*/ display.setCurrent( new GameScreen() ); } /*O destroyApp() é chamado palo AMS quando a MIDlet é destruida (terminada).*/ protected void destroyApp( boolean unconditional ) throws MIDletStateChangeException { } /* O pauseApp() é chamado pelo AMS quando a MIDlet é parada. Note-se que este não é um pause típico de um jogo, mas sim um pause que funciona no ambiente da própria aplicação. O exemplo mais comum acontece quando é recebida uma chamada e a aplicação tem que ser interrompida. Aqui são tomadas as devidas precauções para salvaguardar o estado e a integridade da aplicação. */ protected void pauseApp() { } } Tecnologia Java aplicada a telemóveis GameScreen.java import javax.microedition.lcdui.*; import java.util.*; public class GameScreen extends Canvas implements Runnable { Random generator; Graphics buffer; Image myImage; Image bufferImage; int colour; int myImageX; int myImageY; int imageDirection; //Constructor para a classe GameScreen. public GameScreen() { //activa o gerador de números aleatórios generator = new Random( System.currentTimeMillis() ); //cria das imagens necessárias createImages(); /*Define a posição inicial da imagem para o centro do ecrã*/ myImageX = getWidth()/2; myImageY = getHeight()/2; //cria um novo thread e iniciar imediatamente new Thread( this ).start(); } /*Cria todas as imagens necessaries. É chamado na criação da classe GameScreen*/ public void createImages() { try { /*se o aparelho não suporta double buffering automático*/ if( !isDoubleBuffered() ) { //cria uma imagem for a do ecrã bufferImage = Image.createImage( getWidth(), getHeight() ); /*obtém um contexto Graphics onde pode ser renderizado a imagem do buffer*/ buffer = bufferImage.getGraphics(); } myImage = Image.createImage("/sprite.png"); } 124 Anexo catch( Exception e ) { e.printStackTrace(); } } /*método run()definido no interface Runnable. É chamado pela Virtual Machine quando o thread é iniciado*/ public void run() { while( true ) { //define o atraso do loop para 1/15 de segundo int loopDelay = 1000 / 15; //apanha o tempo no início do loop long loopStartTime = System.currentTimeMillis(); /*chama a função tick() que funcionará como o bater do coração para o jogo*/ tick(); //apanha o tempo no final do loop long loopEndTime = System.currentTimeMillis(); // calcula a diferença do tempo entre o início e o fim do loop int loopTime = (int)(loopEndTime loopStartTime); //se a diferença for maior do que a desejada if( loopTime < loopDelay ) { try { /*então o programa adormece durante o tempo suficiente para completar o desejado Thread.sleep( loopDelay loopTime ); } catch( Exception e ) { } } } } /*O loop chamado num intervalo fixo de tempo, pelo thread do jogo*/ public void tick() { int myImageSpeed = 4; switch( imageDirection ) { case LEFT: myImageX-=myImageSpeed; break; case RIGHT: myImageX+=myImageSpeed; break; 125 Tecnologia Java aplicada a telemóveis case UP: myImageY-=myImageSpeed; break; case DOWN: myImageY+=myImageSpeed; break; } //faz o repaint do Canvas repaint(); // força que cada repaint pendente tratado e bloqueia até ao retorno do paint() serviceRepaints(); } //Chamado quando o Canvas vai ser mostrado protected void paint( Graphics g ) { /*mantém uma referência para o contexto Graphics original*/ Graphics original = g; //se o aparelho não faz double buffering automático if( !isDoubleBuffered() ) { /*muda a referência ao objecto g para o segundo buffer do contexto Graphics*/ g = buffer; } //Define a cor do contexto Graphics para a cor RRGGBB especificada g.setColor( colour ); /*desenha um rectângulo a cheio em x, y com as coordenadas 0, 0 e uma altura e largura iguais ás do Canvas*/ g.fillRect( 0, 0, this.getWidth(), this.getHeight() ); //desenha uma imagem no centro do ecrã g.drawImage( myImage, myImageX, myImageY, Graphics.VCENTER | Graphics.HCENTER ); if( !isDoubleBuffered() ) { //desenha a imagem fora do ecrã no contexto Graphics original original.drawImage( bufferImage, 0, 0, Graphics.TOP | Graphics.LEFT ); } } // Chamado quando uma tecla é pressionada no Canvas corrente protected void keyPressed( int keyCode ) { // apanha o código das teclas associadas ao jogo int gameAction = getGameAction( keyCode ); switch( gameAction ) { case LEFT: //move a imagem para a esquerda imageDirection = LEFT; break; 126 Anexo case RIGHT: //move a imagem para a direita imageDirection = RIGHT; break; case UP: //move a imagem para cima imageDirection = UP; break; case DOWN: //move a imagem para baixo imageDirection = DOWN; break; case FIRE: //set muda o cenário para uma cor aleatória colour = generator.nextInt()&0xFFFFFF; break; } } //Chamado quando uma tecla é solta no Canvas actual protected void keyReleased( int keyCode ) { imageDirection = 0; } } 127 Tecnologia Java aplicada a telemóveis 128 11. Índice de figuras Figura 2.1 – Nokia N-Gage ............................................................................... 15 Figura 2.2 – Imagens de Dragon Island ............................................................ 16 Figura 2.3 – Imagens de XFinity ....................................................................... 16 Figura 2.4 – Imagens de Hurricane Space Fighters.......................................... 17 Figura 2.5 – Imagens de Crash Bandicoot........................................................ 17 Figura 2.6 – Imagens de Fantom Overdrive ..................................................... 17 Figura 3.1 – Esquema de funcionamento do Java............................................ 14 Figura 3.2 – Portabilidade do Java ................................................................... 14 Figura 3.3 – Constituintes do Java.................................................................... 23 Figura 3.4 – Diversas versões do Java ............................................................. 24 Figura 3.5 – Plataformas Java .......................................................................... 25 Figura 3.6 – Configurações e Perfis.................................................................. 30 Figura 3.7 – MIDP e MIDlets............................................................................. 44 Figura 3.8 – Keypad normal de um telemóvel .................................................. 46 Figura 3.9 – Ciclo de vida de uma MIDlet ......................................................... 53 Figura 4.1 – Sagem myG-5 com suporte ExEn................................................. 60 Figura 4.2 – Sony Ericsson T610 com suporte Mophun ................................... 61 Figura 4.3 – Innostream I-1000 com suporte WGE.......................................... 62 Figura 4.4 – Samsung SCH-A530 com suporte BREW .................................... 63 Figura 4.5 – Nokia 3650 com Symbian OS v6.1 ............................................... 64 Figura 6.1 – Escolha do dispositivo default....................................................... 65 Figura 6.2 – Consola principal da KToolbar ...................................................... 66 Figura 6.3 – Criação de um novo projecto ........................................................ 67 Figura 6.4 – Abrir um projecto existente ........................................................... 67 Figura 6.5 – Consola de utilities........................................................................ 68 Figura 6.6 – Consola WMA ............................................................................... 69 Figura 6.7 – Envio de mensagem SMS ............................................................ 70 Figura 6.8 – Envio de mensagem CBS ............................................................. 71 Figura 6.9 – Assinatura da MIDlet suite ............................................................ 72 Figura 6.11 – Gestor de certificados ................................................................. 73 Figura 6.12 – Configuração de rede ................................................................. 74 Figura 6.13 – Performance ............................................................................... 75 Figura 6.14 – Monitorização.............................................................................. 76 Figura 6.15 – Armazenamento.......................................................................... 77 Figura 6.16 – Disponibilidade de APIs .............................................................. 77 Figura 6.17 – WMA ........................................................................................... 78 Figura 6.18 – MMedia ....................................................................................... 78 Figura 6.19 – Segurança................................................................................... 79 Figura 6.20 – Atributos requeridos.................................................................... 81 Figura 6.21 – Atributos opcionais...................................................................... 81 Figura 6.22 – Atributos definidos pelo utilizador ............................................... 81 Figura 6.23 – Atributos das MIDlets .................................................................. 82 Figura 6.24 – Push registry ............................................................................... 82 Figura 6.25 – Permissões ................................................................................. 83 Figura 6.26 – Emulador OTA ............................................................................ 92 129 Tecnologia Java aplicada a telemóveis Figura 7.1 – Criação de um novo projecto ........................................................ 87 Figura 7.2 – Janela de settings ......................................................................... 87 Figura 7.3 – Consola principal após a criação de um projecto ......................... 88 Figura 7.4 – Aplicação Hello World no telemóvel.............................................. 90 Figura 7.5 – Resultado da aplicação Hello World ............................................. 90 Figura 7.6 – Esquema de classes..................................................................... 92 Figura 7.7 – Criação do projecto MyGame ....................................................... 94 Figura 7.8 – Definição dos atributos da MIDlet MyGame.................................. 94 Figura 7.9 – Resultado da criação do projecto MyGame .................................. 95 Figura 7.10 – Execução do MyGame................................................................ 97 Figura 7.11 – Criação de um form .................................................................... 99 Figura 7.12 – Geração de um número aleatório ............................................. 100 Figura 7.13 – Primeira utilização do Canvas .................................................. 103 Figura 7.14 – Tecla "cima" .............................................................................. 113 Figura 7.15 – Tecla "baixo" ............................................................................. 113 Figura 7.16 – Tecla "esquerda"....................................................................... 113 Figura 7.17 – Tecla "disparo" .......................................................................... 113 Figura 7.18 – Tecla "direita" ............................................................................ 113 Figura 7.19 – Imagem PNG que será utilizada ............................................... 108 Figura 7.20 – Utilização de imagens............................................................... 117 Figura 7.21 – Movimentação da imagem no ecrã: "cima"+"esquerda" ........... 121 Figura 7.22 – Movimentação da imagem no ecrã: "baixo"+"direita" ............... 121 Figura 7.23 – Ecrã inicial do AMS................................................................... 114 Figura 7.24 – Instalar a aplicação ................................................................... 114 Figura 7.25 – Introdução da localização da aplicação .................................... 115 Figura 7.26 – Escolha da aplicação a instalar ................................................ 115 Figura 7.27 – Confirmação da instalação ....................................................... 116 Figura 7.28 – Execução do jogo ..................................................................... 116 130 12. Índice de tabelas Tabela 2.1 – Toques polifónicos ....................................................................... 11 Tabela 2.2 – Captura de imagens/vídeo ........................................................... 12 Tabela 2.3 – Características do display ............................................................ 13 Tabela 2.4 – Capacidades de memória ............................................................ 14 Tabela 2.5 – Tecnologias suportadas ............................................................... 18 Tabela 3.1 – Propriedades do sistema ............................................................. 41 Tabela 3.2 – Atributos do MIDlet packaging ..................................................... 51 131