J2ME : Développement d`applications Java pour terminaux mobiles

Transcription

J2ME : Développement d`applications Java pour terminaux mobiles
Travail de diplôme
Roggo Jean-Christophe
J2ME
Développement d’applications Java pour
terminaux mobiles
-1-
Travail de diplôme
Roggo Jean-Christophe
1. J2ME et l’informatique des terminaux mobiles ............................5
1.1. Les applications embarquées .................................................................. 5
1.1.1. Typologie des applications...................................................................................... 6
1.2. J2ME et les systèmes embarqués............................................................. 7
1.2.1. Tour d’horizon de la technologie J2ME....................................................................... 8
1.2.1.1. Les machines virtuelles ......................................................................................9
1.2.1.2. Les configurations .......................................................................................... 11
1.2.1.3. Les profils .................................................................................................... 11
1.2.1.4. Les packages optionnels .................................................................................. 13
1.2.1.5. La pile JSR 185 JTWI (Java Technology for the Wireless Industry)................................. 16
1.2.1.6. Les autres API Java pour terminaux embarqués....................................................... 17
2. La configuration CLDC ......................................................19
2.1. Les limitations de CLDC ...................................................................... 19
2.1.1. Support de la virgule flottante ................................................................................ 19
2.1.2. Internationalisation des applications ....................................................................... 19
2.1.3. Support des propriétés d’environnement.................................................................. 21
2.1.4. Limitations diverses............................................................................................. 21
2.2. La sécurité dans CLDC ....................................................................... 22
2.2.1. Prévérification des fichiers de classe....................................................................... 22
2.2.2. Le modèle de sécurité Sandbox.............................................................................. 23
2.3. Les classes de CLDC ......................................................................... 23
2.3.1. Les classes héritées de J2SE ................................................................................. 23
2.3.2. Les classes spécifiques de CLDC ........................................................................... 24
3. Le profil MIDP ................................................................27
3.1. Le MIDlet ........................................................................................ 27
3.1.1. Cycle de vie d’un MIDlet........................................................................................ 27
3.1.2. L’accès aux attributs du fichier *.jar......................................................................... 29
3.2. L’interface utilisateur........................................................................... 30
3.2.1. Les principes de l’interface utilisateur MIDP .............................................................. 30
3.2.2. Les classes d’affichage ........................................................................................ 31
3.2.2.1. La classe Display ........................................................................................... 31
3.2.2.2. La classe Displayable ...................................................................................... 32
3.2.2.3. La classe Screen ........................................................................................... 32
3.2.2.4. La classe Canvas........................................................................................... 33
3.2.3. L’interface utilisateur de haut niveau ....................................................................... 34
3.2.3.1. L’interface Choice .......................................................................................... 35
3.2.3.2. La classe List................................................................................................ 36
3.2.3.3. La classe Item............................................................................................... 37
3.2.3.4. La classe Form.............................................................................................. 37
3.2.3.5. La classe ChoiceGroup .................................................................................... 38
3.2.3.6. La classe TextField ......................................................................................... 38
3.2.3.7. La classe DateField ........................................................................................ 39
3.2.3.8. La classe Gauge ............................................................................................ 40
3.2.3.9. La classe ImageItem ....................................................................................... 41
3.2.3.10. La classe StringItem ...................................................................................... 42
3.2.3.11. La classe TextBox ........................................................................................ 42
3.2.3.12. La classe Alert ............................................................................................. 42
3.2.3.13. La classe Ticker ........................................................................................... 44
-2-
Travail de diplôme
Roggo Jean-Christophe
3.2.4. La gestion des évènements ................................................................................... 44
3.2.4.1. La classe Command ....................................................................................... 44
3.2.4.2. L’interface commandListener ............................................................................. 45
3.2.4.3. L’interface ItemStateListener.............................................................................. 46
3.3. Le stockage persistant des données ........................................................ 47
3.3.1. Le package RMS ................................................................................................. 47
3.3.2. Le Record Store .................................................................................................. 47
3.3.2.1. La classe RecordStore..................................................................................... 48
3.3.2.2. L’interface RecordComparator............................................................................ 49
3.3.2.3. L’interface RecordFilter .................................................................................... 49
3.3.2.4. L’interface RecordEnumeration........................................................................... 49
3.3.2.5. L’interface RecordListener ................................................................................ 50
4. J2ME en pratique ............................................................51
4.1. Les outils ........................................................................................ 51
4.1.1. L’environnement de développement ........................................................................ 51
4.1.1.1. J2ME Wireless Toolkit 2.1................................................................................. 52
4.1.2. Le terminal mobile cible ........................................................................................ 55
4.1.2.1. Le terminal mobile Sony Ericsson t610.................................................................. 55
4.1.3. L’outil de transfert de l’application .......................................................................... 56
4.2. L’application CurrencyConverter............................................................. 57
4.2.1. Le client J2ME .................................................................................................... 58
4.2.2. Le serveur PHP ................................................................................................... 60
4.2.3. Le Web service ................................................................................................... 60
5. Conclusion ....................................................................61
-3-
Travail de diplôme
Roggo Jean-Christophe
Avant-propos
L’objectif de ce dossier est de présenter la technologie Java 2 Micro Edition
(J2ME). Cette technologie, proposée par Sun Microsystem, permet de développer
des applications pour les terminaux embarqués en utilisant le langage Java.
Les trois premières parties de la présente étude fournissent les notions
théoriques nécessaires à une compréhension approffondie de la technologie
J2ME. La dernière partie, quant à elle, présente un prototype réalisé au cours de
cette étude.
Un cd rom ainsi que trois documents contenant des exemples pratiques sont
annexés.
Le cd rom contient tous les fichiers et logiciels nécessaires pour mettre en œuvre
les différents exemples pratiques.
-4-
Travail de diplôme
Roggo Jean-Christophe
Cette première partie débute par une présentation du panorama des applications
pour terminaux embarqués. Vous trouverez ensuite une description de la
technologie J2ME et de la place qu’elle occupe dans le paysage de la mobilité.
1. J2ME et l’informatique des terminaux mobiles
1.1. Les applications embarquées
Un système embarqué (embedded system), est un système informatique
autonome interagissant en temps réel avec le monde physique de manière
généralement invisible. Il est constitué de un ou plusieurs processeurs
accompagnés de logiciels [DEL02].
Initialement réservés aux grands domaines technologiques classiques comme le
spatial, le nucléaire ou l’aéronautique, les systèmes embarqués apparaissent
désormais massivement à l’échelle de l’individu et envahissent tous les domaines
de sa vie privée et professionnelle : téléphones mobiles, assistants personnels,
cartes à puces, appareils multimédias, automobiles, domotique, surveillance
médicale, …
Le marché des systèmes embarqués est en pleine explosion, puisqu’il
représentait 40 milliards d’euros en 2002 et que sa croissance est d’environ 20%
par année (Durlacher Research). Les secteurs les plus porteurs sont le transport,
le multimédia, la téléphonie, la monétique, la transitique (logistique limitée aux
liaisons internes d’une entreprise) et la banque.
Les téléphones mobiles et assistants personnels contribuent de manière non
négligeable à la croissance du marché des terminaux embarqués. Selon un
rapport publié par la société d'étude britannique Canalys, le marché mondial des
terminaux mobiles (téléphones mobiles, PDA, Smartphones …) affiche une
croissance de 41 % pour le premier trimestre 2004 (par rapport au premier
trimestre 2003) [JNE04]. Le tableau présenté ci-dessous illustre ce phénomène
de croissance (source Canalys).
Le marché mondial des terminaux mobiles au 1er trimestre 2004
Constructeur
Ventes
(en millions d'unités)
Part de marché
Nokia
PalmOne
HP
RIM
Fijutsu
Motorola
Sony Ericsson
Sony
Dell
Siemens
Autres
1,67
0,99
0,57
0,37
0,36
0,31
0,26
0,20
0,16
0,08
0,90
28,2 %
16,8 %
9,7 %
6,4 %
6,1 %
5,3 %
4,4 %
3,4 %
2,7 %
1,5 %
15,5 %
Evolution des ventes (par
rapport au premier
trimestre 2003)
+85 %
-9 %
+29 %
+301 %
+507 %
+12 748 %
+19 %
-45 %
-3 %
+470 %
+10 %
Total
5,93
100 %
+41 %
-5-
Travail de diplôme
Roggo Jean-Christophe
1.1.1. Typologie des applications
Il est intéressant d’établir une typologie des applications destinées aux systèmes
embarqués en fonction des différentes architectures [DEL02] (cf Gartner Model):
ƒ
Les applications locales qui peuvent s’exécuter sur des terminaux sans
couverture réseau. Ce sont, par exemple, les jeux autonomes, les
calculatrices, les mémo pad, …
ƒ
Les applications fonctionnant en réseau peer-to-peer qui sont des
applications réseau terminal à terminal sans serveur. Ce sont , par
exemple, les applications de chat en direct, les jeux en réseau, …
ƒ
Les applications client-serveur (client léger) qui sont des applications
très légères dans lesquelles le terminal côté client a une logique
applicative limitée. Ce sont, par exemple, les applications qui mettent
en forme du contenu fourni par une application serveur.
ƒ
Les applications client-serveur intelligentes (client lourd) qui sont les
applications dans lesquelles le terminal côté client a plus de logique
applicative et de traitement local.
Le tableau ci-dessous présente les types de clients par catégorie d’application.
Catégorie d’application
Micronavigateur
(navigateur WAP)
J2ME
Application locale
Non
Oui
Réseau peer-to-peer
Non
Oui
Application client-serveur (client
léger)
Oui
Oui
Application client-serveur (client
lourd)
Non
Oui
[DEL02]
Notons que l’on peut également classer les applications par domaine : loisirs,
applications métier, applications PIM (Personal Information Manager), application
réseau, utilitaires, …
ƒ
Le domaine des loisirs comprend les jeux autonomes et en réseau.
ƒ
Les principales applications métier concernent le commerce
électronique, la banque, le CRM (Customer Relationship Management)
ainsi que la gestion des ressources.
ƒ
Les applications PIM comprennent les planificateurs, les répertoires
d’adresses …
ƒ
Les applications de connectivité comprennent les clients de messagerie,
les gestionnaires de SMS, …
ƒ
Le domaine des utilitaires comprend les calculatrices, les memos pad,
…
-6-
Travail de diplôme
Roggo Jean-Christophe
1.2. J2ME et les systèmes embarqués
En 1998, Sun Microsystems Laboratories lance le projet de recherche Spotless
dont le but est d’adapter le langage Java pour des systèmes limités en ressource
et de réaliser une machine virtuelle de petite taille assurant la portabilité. En Juin
1999, Sun présente la nouvelle plate-forme Java 2 Micro Edition (J2ME). Les
travaux de standardisation des composants du J2ME débutent en Octobre 1999
[WJS04].
J2ME fait partie de la plate-forme Java 2. Ci-dessous vous trouverez une
illustration qui situe la technologie J2ME au sein de la plate-forme Java 2.
[JSU04]
Comme l’illustre l’image ci-dessus, la technologie J2SE cible les ordinateurs
standards de bureau, la technologie J2EE est destinée aux serveurs et la
technologie J2ME est spécialement conçue pour le développement d’applications
sur des terminaux mobiles.
Sun Microsystems cible donc le marché avec une suite de technologies fondées
sur Java qui simplifient le déploiement pour les fabricants de terminaux, les
fournisseurs de services et les développeurs d’applications des produits client et
embarqués. J2ME s’adresse particulièrement aux terminaux embarqués, comme
les téléphones cellulaires, les assistants personnels (PDA), les décodeurs TV
numérique, les consoles de jeux, les terminaux de paiement, les systèmes
embarqués dans les véhicules, …
Ces terminaux sont soumis à certaines contraintes :
ƒ
Interface utilisateur limitée (clavier, écran tactile)
ƒ
Affichage limité (taille, couleur)
ƒ
Peu de mémoire
ƒ
Connectivité limitée
ƒ
Alimentation (batterie)
-7-
Travail de diplôme
Roggo Jean-Christophe
ƒ
Encombrement et poids faibles
ƒ
Résistance aux chocs
La présente étude se concentrera plus particulièrement sur les terminaux de type
téléphone cellulaire. Ces terminaux spécialisés, aux fonctionnalités limitées, sont
généralement dotés de processeurs 32 bits et d’une connectivité réseau.
1.2.1. Tour d’horizon de la technologie J2ME
J2ME offre un certain nombre d’avantages dans le domaine du développement
d’applications embarquées.
Le premier d’entre eux est la mise à disposition d’outils performants (J2ME
Wireless Toolkit) et faciles à utiliser garantissant un développement rapide des
applications. Ces outils permettent par exemple de minimiser l’utilisation du
terminal dans le cycle de développement en mettant à la disposition du
développeur un émulateur de terminal. L’émulateur reproduit fidèlement le
comportement d’un terminal, y compris ses performances et son aspect
physique. Notons qu’il est primordial que l’émulateur reproduise les mêmes
performances qu’un vrai terminal afin de développer des applications
parfaitement adaptées aux performances réelles du terminal et non pas à celle
de l’ordinateur de bureau effectuant l’émulation.
Les outils proposés permettent également un déploiement aisé des applications
grâce au mécanisme de packaging. Ces outils seront présentés dans la dernière
partie de ce dossier (cf 4).
Un autre avantage considérable de la technologie J2ME est qu’elle permet de
développer des applications adaptées aux capacités des terminaux en réutilisant
des sous-ensembles d’API existantes et en proposant des éléments optionnels.
J2ME est une technologie basée sur une architecture modulaire. Les briques de
base de la technologie J2ME sont la configuration, le profil et les packages
optionnels [DSU04].
Une configuration est une machine virtuelle ainsi qu’un ensemble minimal de
classes de base et d’API. Elle spécifie un environnement d’exécution généralisé
pour les terminaux embarqués et agit comme plate-forme Java sur le terminal.
Un profil est une spécification des API Java définie par l’industrie, utilisée par les
fabricants et les développeurs à destination de terminaux spécifiques.
Un package optionnel est, comme son nom l’indique, un package qui peut ne pas
être implémenté sur un terminal particulier.
Les machines virtuelles J2ME et les spécifications d’API de plate-formes
spécifiques sont développées en sollicitant les besoins d’entrée par l’initiative du
JCP (Java Community Process) de façon à s’assurer que les spécifications
répondent aux besoins spécifiques d’une famille ou d’une catégorie de terminaux
clients. Une fois une JSR (Java Specification Request) acceptée par l’initiative
JCP, la JSR, qui peut être proposée par Sun Microsystems ou par une autre
société, crée une machine virtuelle Java et une implémentation de référence API
pour la plate-forme J2ME cible.
-8-
Travail de diplôme
Roggo Jean-Christophe
Ci-dessous quelques exemples de JSR [DSU04]:
ƒ
JSR 30 pour CLDC (Connected Limited Device Configuration)
ƒ
JSR 36 pour CDC (Connected Device Configuration)
ƒ
JSR 37 pour MIDP (Mobile Information Device Profile)
ƒ
JSR 46 pour Foundation profile
ƒ
JSR 62 pour Personal profile
ƒ
JSR 66 pour RMI Profile
La technologie J2ME bénéficie des avantages liés aux autres technologies de la
plate-forme Java 2, à savoir :
ƒ
Write Once Run Anywhere (Ecrire Une fois et Exécuter Partout) : en
effet, la machine virtuelle Java permet la portabilité des applications.
Par exemple, un développeur n’aura pas besoin d’écrire et de maintenir
différentes versions d’une même application pour qu’elle puisse
s’exécuter sur un Nokia Communicator (EPOC Operating System), sur
un Compaq iPaq (Pocket PC Operating System) ou sur un PDA utilisant
Linux comme système d’exploitation.
ƒ
Sécurité : J2ME repose sur le modèle de sécurité Sandbox. Lorsqu’une
application est exécutée elle ne peut accéder aux ressources système
en dehors de la Sandbox ce qui limite les problèmes de virus. J2ME
bénéficie également de solutions de sécurité pour les transactions
électroniques comme SSL.
ƒ
Une riche interface graphique : J2ME comporte des API riches et
adaptées à chaque catégorie de terminaux mobiles.
1.2.1.1. Les machines virtuelles
La machine virtuelle Java (JVM) se trouve au centre de la technologie Java. Elle
permet aux applications écrites dans le langage de programmation Java d’être
portables sur différents environnements matériels et systèmes d’exploitation. La
machine virtuelle se situe entre l’application et la plate-forme utilisée,
convertissant le bytecode de l’application en code machine approprié au matériel
et système d’exploitation utilisé. La machine virtuelle assume également des
tâches relatives à la gestion de la mémoire du système.
Deux machines virtuelles sont proposées par J2ME, la KVM associée à la
configuration CLDC et la CVM associée à la configuration CDC [DSU04][DEL02].
ƒ
KVM (Kilo Virtual Machine) est une implémentation runtime
extrêmement légère de la machine virtuelle Java qui peut être utilisée
dans les terminaux disposant de peu de mémoire, comme les
téléphones cellulaires, les pagers bidirectionnels et les PDA. Cette
machine virtuelle fonctionne avec des processeurs 16 et 32 bits et un
total de mémoire d’environ 100 Ko.
ƒ
CVM (Convergence Virtual Machine) est une machine virtuelle Java
2 conçue pour les terminaux ayant besoin de l’ensemble des
-9-
Travail de diplôme
Roggo Jean-Christophe
fonctionnalités de la JVM mais avec des capacités plus réduites. CVM
est conçue pour répondre aux besoins du marché émergent des
terminaux embarqués de prochaine génération. Les terminaux utilisant
CVM sont généralement des terminaux compacts.
D’autres machines virtuelles pour l’embarqué sont proposées par différents
constructeurs comme la J9 (développée par IBM) associée à la configuration
CDC, la Monty (développée par Sun), la MicrochaiVM (développée par HP) et la
JBED (développée par la société suisse Esmertec) qui sont associées à la
configuration CLDC.
Ci-dessous vous trouverez un aperçu de l’offre en machines virtuelles
embarquées [MVE02].
Editeur
Machine
virtuelle
Apogee
Portage
optimisé des
JVM de Sun
JIT +
interpréteur,
optimiseur
JBED
Compilateur
FastBCC
(bytecode to
native)
Esmertec
Chai VM
Hewlett Packard
Microchai VM
Technologie Spécification
AOT, JIT,
adaptatif
AOT, JIT,
adaptatif
OS
Processeurs
PJava, CDC,
CLDC
LynxOS,
VxWorks
PowerPC, x86, …
CLDC/MIDP
PalmOS,
PocketPC, Linux,
Nucleus, JBED
Rtos
Core, CLDC/MIDP
J9
AOT, JIT,
adaptatif
Core,
CLDC/MIDP,
CDC/FP
Jeode
adaptatif
Personal Java
Jeode EVM
adaptatif
CDC/FP
Mobile
Foundation
adaptatif
CLDC/MIDP
Kada Systems
Mobile ROI
JIT +
interpréteur
CLDC/MIDP
NewMonics
Perc
AOT, JIT,
adaptatif
J2SE, J2ME/CDC
One Eighty
Software
Origin - J
propriétaire
PJava, JavaCard
Sun
Microsystems
Monty
adaptatif
CLDC/MIDP
Tao
Intent JTE
JIT sans
interpréteur
CLDC/MIDP
IBM Software
Group
Insignia
- 10 -
Windows CE,
PocketPC, QNX
Linux, PalmOS,
PocketPC
Linux, PalmOS,
PocketPC, QNX,
Ose
VxWorks,
Nucleus,
Windows CE,
Linux
Linux, VxWorks,
NT4
Nucleus, iTron,
PocketPC
PalmOS,
PocketPC, Wind,
Linux
VxWorks,
VxWorks AE,
Nucleus, Ose,
Linux
Origin
Arm 7/9
StrongArm,
Xscale, PXA
210/250,
PowerPC,
ColdFire, 68k
SA1100, SH3/4,
x86
x86, 68k,
PowerPC,
StrongArm, SH4,
Mips
Arm, Mips, SH3/4,
PowerPC
x86, Mips,
PowerPC
Arm, Omap
Arm, TI, Mips,
SH3/4
PowerPC, x86, …
Microcontrôleurs 8
bits H8, 8051,
68xx et 16 bits
Arm, Jazelle
PocketPC,
VxWorks,
SymbianOS
Arm, Omap, Risc
Travail de diplôme
Roggo Jean-Christophe
1.2.1.2. Les configurations
Comme nous l’avons cité précédemment, J2ME est une technologie basée sur
une architecture modulaire. La configuration occupe une place importante dans
cette architecture. Elle détermine une plate-forme minimale pour une catégorie
de terminaux ayant des caractéristiques analogues en mémoire totale et en
capacité de traitement. La configuration détermine une adjonction minimale ou
« le plus petit dénominateur commun » à la technologie Java. Toutes les
fonctionnalités inclues dans une configuration doivent être généralement
applicables à une grande variété d’appareils.
La technologie J2ME est constituée de deux configurations, CLDC (Connected
Limited Device Configuration), pour les terminaux légers à connexion limitée, et
CDC (Connected Device Configuration), pour les terminaux légers connectés.
ƒ
CLDC JSR 30 est disponible comme implémentation de référence de
CLDC. Cette configuration consiste en la machine virtuelle K (KVM) et
un ensemble de bibliothèques de classes noyau appropriées à
l’utilisation dans un profil de l’industrie, comme le profil spécifié par
l’implémentation de référence MIDP. Les terminaux concernés sont
dotés d’interfaces utilisateur simplifiées, de processeurs 16 ou 32 bits,
d’une capacité mémoire disponible pour la plate-forme Java de 128 Ko
à 512 Ko et de connexions réseau intermittentes à faible bande
passante.
ƒ
CDC JSR 36 est fondée sur la spécification de machine virtuelle
classique qui définit un environnement runtime complet. Cette
configuration est destinée aux terminaux disposant de ressources plus
conséquentes, à savoir : une interface utilisateur très diversifiée, une
capacité mémoire disponible pour la plate-forme Java dépassant en
tout cas les 512 Ko, un processeur 32 bits et une connexion réseau
permanente avec une large bande passante.
Notons qu’il existe une version révisée de CLDC 1.0 (JSR 30) : la version 1.1 de
CLDC (JSR 139). Cette version révisée de CLDC inclut des nouvelles
caractéristiques comme le support des nombres à virgule et l’emploi de
références faibles. CLDC 1.1 est « rétro-compatible » avec la version CLDC 1.0.
Une version révisée de CDC est en cours de développement et sera bientôt
disponible: CDC 1.1 (JSR 218).
[DEL02][DSU04][WJS04][JSU04]
1.2.1.3. Les profils
Le profil est également une pièce fondamentale de l’architecture modulaire de la
technologie J2ME. C’est une couche située au dessus de la configuration qui
correspond à une spécification d’API Java définie par l’industrie et utilisée par les
fabricants et les développeurs pour des terminaux spécifiques. La machine
virtuelle et les API de base spécifiées par une configuration ne suffisent pas pour
construire une application complète. Le profil ajoute des API plus spécifiques
- 11 -
Travail de diplôme
Roggo Jean-Christophe
pour la gestion du cycle de vie d’une application, l’interface graphique et le
stockage permanent.
Il existe deux familles de profils : ceux qui dépendent de la configuration CLDC et
ceux qui dépendent de la configuration CDC.
Ci-dessous vous trouverez une brève description des principaux profils existant
dans J2ME.
ƒ
MIDP est un profil qui nécessite l’implémentation de référence CLDC et
qui fournit des classes pour l’écriture d’applications qui tournent sur
des terminaux mobiles comme les téléphones cellulaires et les pagers
bidirectionnels. Le profil MIDP fournit une plate-forme standard pour les
petits terminaux mobiles aux ressources limitées. Ce profil est destiné
aux terminaux répondant aux caractéristiques suivantes :
-
512 Ko de mémoire totale (ROM + RAM) disponible pour le runtime
Java et ses bibliothèques ;
puissance et batterie limitée ;
connectivité à certains type de réseaux sans fil à faible bande
passante ;
interfaces utilisateur à différents niveaux de sophistication.
Il existe à l’heure actuelle deux versions de MIDP : MIDP 1.0 (JSR 37)
et MIDP 2.0 (JSR 118). MIDP 2.0 correspond à une version révisée de
la spécification MIDP 1.0 qui inclut des nouvelles caractéristiques
comme une interface graphique évoluée, des fonctionnalités pour les
jeux et le multimédia ainsi que des possibilités étendues en matière de
connectivité et de sécurité. Notons également que MIDP 2.0 est « rétro
– compatible » avec MIDP 1.0.
ƒ
PDAP JSR 75 est un profil associé à la configuration CLDC qui fournit
des API d’interface utilisateur et de stockage de données pour les petits
terminaux Handheld aux ressources limitées comme les PDA. Les
terminaux visés ont les caractéristiques suivantes :
-
ƒ
pas moins de 512 Ko et pas plus de 16 Mo de mémoire totale (ROM
+ RAM) disponible pour le runtime Java et les bibliothèques ;
puissance et batterie limitées ;
interface utilisateur de différents degrés de sophistication,
terminaux disposant d’un affichage d’une résolution supérieure à
20000 pixels, d’un dispositif de pointage et d’une entrée pour
caractères.
Foundation Profile JSR 46 est un profil associé à la configuration
CDC qui est destiné aux terminaux ayant besoin d’un support pour une
plate-forme Java avec un réseau riche mais qui ne nécessitent pas
d’interface utilisateur. Il fournit en outre un profil de base pour d’autres
profils qui auraient besoin de construire leurs propres fonctionnalités en
ajoutant, par exemple, une GUI (Graphical User Interface). Les
terminaux visés ont les caractéristiques suivantes :
-
1024 Ko de
applications);
ROM
(sans
compter
- 12 -
les
besoins
mémoire
des
Travail de diplôme
ƒ
Roggo Jean-Christophe
512 Ko de RAM (sans compter les besoins mémoire des
applications);
connectivité à certains types de réseaux ;
aucune interface graphique (à moins que les fonctionnalités
d’interface graphique soient fournies par un profil additionnel).
Personal Profile JSR 62 est un profil associé à la configuration CDC
qui est destiné aux terminaux nécessitant un haut niveau de
connectivité Internet et une fidélité Web. Ce profil est conçu pour pour
être compatible avec la spécification de l’environnement d’application
PersonalJava. Les caractéristiques des terminaux visés sont les
suivantes :
-
un minimum de 2.5 Mo de ROM (sans compter les besoins mémoire
des applications);
un minimum de 1 Mo de RAM (sans compter les besoins mémoire
des applications);
connectivité robuste à certains types de réseaux ;
interface graphique avec un haut degré de fidélité Web et la
possibilité d’exécuter des applets ;
support de l’implémentation complète de J2ME Foundation Profile et
de J2ME CDC.
[DEL02][DSU04][WJS04][JSU04]
1.2.1.4. Les packages optionnels
Le package optionnel est également un élément clé de l’architecture modulaire
de la technologie J2ME. Un package optionnel fournit des fonctionnalités qui ne
devraient pas être associées à une configuration ou à un profil particulier.
Bluetooth API JSR 82 est un exemple de package optionnel qui fournit une API
standard pour les connexions réseau sans fil Bluetooth. Ce package optionnel
pourrait être implémenté avec n’importe quelle combinaison de configurations et
de profils.
Ci-dessous vous trouverez une description des principaux packages optionnels
existant dans J2ME.
ƒ
BTAPI JSR 82 (Bluetooth API) fournit une API standard pour
l’intégration des terminaux mobiles dans un environnement Bluetooth.
Cette spécification inclut le support des protocoles Bluetooth suivants :
RFCOMM, OBEX et Service Discovery Protocol. D’autres protocoles
seront ajoutés dans des versions futures de ce package optionnel. Les
terminaux visés par cette spécification ont les caractéristiques
suivantes :
-
un minimum de 512 Ko de mémoire totale (ROM + RAM)
connexion réseau Bluetooth
- 13 -
Travail de diplôme
ƒ
Roggo Jean-Christophe
WMA JSR 120 (Wireless Messaging API) fournit une API standard pour
accéder aux fonctionnalités de communication d’un terminal mobile.
Les technologies concernées sont les suivantes :
-
SMS (Short Message Service)
USSD (Unstructured Supplementary Service Data)
CBS (Cell Broadcast Service)
Notons qu’il existe une spécification plus récente, WMA 2.0 JSR 205,
qui définit une interface pour l’envoi et la réception de MMS.
ƒ
PIM JSR 75 (Personal Information Management) est un package
optionnel offrant la possibilité d’accéder aux données natives résidant
dans les terminaux mobiles comme les PDA ou les téléphones mobiles.
Ce package permet par exemple d’accéder aux données contenues
dans l’agenda ou le répertoire d’adresses d’un PDA.
ƒ
MMAPI JSR 135 (Mobile Media API) définit une interface pour les
fonctionnalités multimédia des terminaux mobiles compatibles J2ME.
Ci-dessous vous trouverez une illustration clarifiant l’architecture décrite
précédemment suivie d’un tableau regroupant l’ensemble des JSR
(configurations, profils et packages optionnels) concernant J2ME [DSU04]:
- 14 -
Travail de diplôme
Roggo Jean-Christophe
Configurations
JSR 30
CLDC 1.0
Connected, Limited Device Configuration
JSR 139
CLDC 1.1
Connected, Limited Device Configuration 1.1
JSR 36
CDC
Connected Device Configuration
JSR 218
CDC 1.1
Connected Device Configuration 1.1
JSR 37
MIDP 1.0
Mobile Information Device Profile
JSR 118
MIDP 2.0
Mobile Information Device Profile 2.0
JSR 75
PDAP
PDA Profile
JSR 46
FP
Foundation Profile
JSR 219
FP 1.1
Foundation Profile 1.1
JSR 129
PBP
Personal Basis Profile
JSR 217
PBP 1.1
Personal Basis Profile 1.1
JSR 62
PP
Personal Profile
JSR 215
PP 1.1
Personal Profile 1.1
JSR 195
IMP
Information Module Profile
JSR 228
IMP-NG
Information Module Profile - Next Generation
Profils
Packages optionnels
JSR 75
PIM
PDA Optional Packages for the J2ME Platform
JSR 82
BTAPI
Java APIs for Bluetooth
JSR 120
WMA
Wireless Messaging API
JSR 205
WMA 2.0
Wireless Messaging API 2.0
JSR 135
MMAPI
Mobile Media API
JSR 164
JAIN SIMPLE Presence
JSR 165
JAIN SIMPLE Instant Messaging
JSR 172
JSR 177
J2ME Web Services
SATSA
JSR 179
Security and Trust Services API for J2ME
Location API for J2ME
JSR 180
SIP
SIP API for J2ME
JSR 184
3D
Mobile 3D Graphics API for J2ME
JSR 186
JAIN Presence
JSR 187
JAIN Instant Messaging
JSR 190
Event Tracking API for J2ME
JSR 209
Advanced Graphics and User Interface Optional Package for J2ME Platform
JSR 211
CHAPI
Content Handling API
JSR 213
Micro WSCI Framework for J2ME
JSR 214
Micro BPSS for J2ME Devices
JSR 226
Scalable 2D Vector Graphics API
JSR 229
Payment API
JSR 230
Data Sync API
JSR 232
Mobile Operational Management
JSR 234
Advanced Multimedia Supplements
JSR 238
Mobile Internationalization API
JSR 239
Java Bindings for OpenGL ES
JSR 246
Device Management API
- 15 -
Travail de diplôme
Roggo Jean-Christophe
1.2.1.5. La pile JSR 185 JTWI (Java Technology for the Wireless Industry)
Un terminal mobile compatible J2ME implémente une pile logicielle consistant
généralement en une configuration, un profil et des packages optionnels. La
première génération de téléphones mobiles compatibles J2ME implémente
généralement la pile logicielle suivante :
Beaucoup de fabricants de téléphones mobiles proposent leurs propres API pour
offrir des fonctionnalités étendues (généralement développées par l’intermédiaire
de JCP). Il en résulte un phénomène de fragmentation. Un développeur MIDP
désire savoir quelles API optionnelles sont disponibles pour des terminaux
particuliers. Il est possible de découvrir la présence d’API au runtime, mais cette
technique ajoute de la complexité au code. Il est également possible de
distribuer plusieurs versions d’une application mais ceci dérogerait au principe
fondamental des plate-formes Java, à savoir « write once and run everywhere ».
Le phénomène de fragmentation peut donc engendrer des problèmes de
portabilité.
D’autres problèmes peuvent également limiter la portabilité d’une application. En
effet, certains constructeurs fixent des limites pour la taille d’une application. Il
peut arriver qu’une application MIDP 1.0 développée en respectant strictement
les spécifications ne soit pas exécutable sur un terminal (MIDP 1.0 / CLDC 1.0).
Le constructeur du terminal en question a pu fixer une limite pour la taille du
fichier *.jar mais également une taille limite pour le heap (espace mémoire pour
l’exécution de l’application).
Le problème le plus délicat interférant sur la portabilité d’une application réside
cependant dans l’utilisation des threads. La spécification MIDP 1.0 inclut la classe
java.lang.Thread mais ne donne aucune indications sur le nombre de threads
supportés par une implémentation. Si une application comporte un nombre
importants de threads, elle risque de ne pas pouvoir s’exécuter correctement sur
certains terminaux.
Pour résoudre ces problèmes, une spécification particulière issue des travaux de
la JSR 185 et nommée Java Technology for the Wireless Industry (JTWI) a été
développée. Cette spécification impose aux périphériques qui la respectent de
mettre en œuvre CLDC 1.0 ou 1.1, MIDP 2.0 et WMA. Le support de MMAPI est
optionnel. La pile JSR 185 offre donc une vision claire au développeur des API
disponibles pour un terminal mobile compatible JTWI.
- 16 -
Travail de diplôme
Roggo Jean-Christophe
La spécification JSR 185 fournit tous les détails nécessaires pour garantir qu’une
application sera exécutable sur tous les terminaux implémentant cette pile
logicielle. Vous trouverez plus de détails sur la pile JSR 185 en consultant
l’adresse suivante :
http://developers.sun.com/techtopics/mobility/midp/articles/jtwi/
[DSU04][WJS04][JSU04]
1.2.1.6. Les autres API Java pour terminaux embarqués
Ces autres API Java ne font pas directement partie de J2ME mais il est tout de
même intéressant de les citer. Certaines sont destinées au contrôle du
téléphone, d’autres concernent la télévision numérique ou encore les cartes de
crédit.
ƒ
Java Phone API est une extension verticale de la plate-forme
PersonalJava. Cette API fournit un accès aux fonctionnalités spécifiques
des terminaux de téléphonie client. Elle permet notamment de
contrôler le téléphone, d’envoyer des messages à base de
datagrammes, d’obtenir des informations du carnet d’adresse et du
calendrier.
ƒ
Java TV API est une extension verticale de la plate-forme
PersonalJava destinée à la création d’applications interactives pour la
télévision numérique. Cette API permet la mise en œuvre de
transactions de commerce électronique, de publicité interactive ou
encore d’applications de banque à domicile.
ƒ
Java Card est destinée au développement pour cartes intelligentes.
Une carte intelligente est une carte de crédit dotée d’un circuit intégré
(CI). Le CI contient un microprocesseur et de la mémoire permettant à
la carte de stocker et traiter des informations. Java Card donne au
développeur la possibilité de standardiser une plate-forme de carte
commune. Cela signifie, par exemple, qu’un opérateur de téléphonie
sans fil GSM (Global System for Mobile communications) peut
facilement développer de nouveaux services susceptibles d’être
téléchargés de manière sélective sur la carte intelligente résidant dans
le téléphone.
ƒ
Connexion Jini est une technologie permettant aux services de
fonctionner dynamiquement et simplement avec d’autres services.
Dans une communauté Jini, le services disposent d’un code de
découverte et de recherche dont ils ont besoin pour fournir
immédiatement les services aux autres membres de la communauté.
Quand un nouveau service est mis à disposition sur le réseau, il n’est
pas nécessaire d’éditer des fichiers de configuration, d’arrêter et de
redémarrer des serveurs ou de configurer des passerelles. De plus, les
communautés Jini supportent les infrastructures redondantes ce qui
assure une disponibilité des services même en cas de pannes de
serveurs ou de problèmes liés au réseau.
- 17 -
Travail de diplôme
ƒ
Roggo Jean-Christophe
JES (Java Embedded Server) est destiné aux périphériques de
terminaison à large bande comme un modem DSL par exemple. Cette
technologie permet de transformer le périphérique en passerelle
résidentielle. Une passerelle résidentielle est un boîtier situé chez
l’utilisateur lui permettant de se connecter à Internet et d’accéder à
différents services. Les technologies JES et Connexion Jini sont liées.
En effet, Connexion Jini supporte des communautés de services
spontanément crées et JES est un framework permettant de générer
les services délivrés à Jini.
[DEL02][WJS04][JSU04]
- 18 -
Travail de diplôme
Roggo Jean-Christophe
Dans cette deuxième partie, vous trouverez une étude détaillée de la
configuration CLDC.
2. La configuration CLDC
Le rôle de CLDC (Connected Limited Device Configuration) est de définir une
plate-forme Java standard adaptées aux terminaux légers dotés de peu de
ressources. CLDC répond à la nécessité de faire tourner des applications sur une
grande variété de petits terminaux, allant des terminaux de communication sans
fil, comme les téléphones cellulaires et les pagers bidirectionnels, jusqu’aux
organiseurs personnels, aux terminaux de points de vente et aux équipements
domestiques.
CLDC est le plus petit commun dénominateur de la technologie Java applicable à
une grande variété de terminaux mobiles. Il garantit la portabilité et
l’interopérabilité du code au niveau des profils entre les différents types de
terminaux mobiles compatibles CLDC.
La configuration CLDC ne définit que les bases communes à l’ensemble des
terminaux : entrées-sorties, réseau, sécurité, internationalisation. En ce qui
concerne les fonctionnalités de plus haut niveau, c’est au profil spécifique du
terminal de les prendre en charge : gestion du cycle de vie de l’application,
interface utilisateur, gestion des évènements.
2.1. Les limitations de CLDC
La configuration CLDC est sujette à un certain nombre de limitations dont il faut
tenir compte lors de la conception et du développement d’une application.
2.1.1. Support de la virgule flottante
CLDC ne supporte pas les nombres à virgule flottante float ou double. Lors du
développement d’une application, il est donc impossible d’utiliser les types de
données float et double.
Cette limitation n’est cependant pas catastrophique puisqu’il existe un package,
MathFP, permettant de simuler les calculs en virgule flottante. Ce package est
disponible à l’adresse suivante :
http://home.rochester.rr.com/ohommes/MathFP
[DEL02][WJS04][JSU04]
2.1.2. Internationalisation des applications
CLDC ne supporte que de manière limitée l’internationalisation, qui consiste à
traduire les caractères UNICODE depuis et vers une séquence d’octets, d’une
part, et vers la localisation, d’autre part.
- 19 -
Travail de diplôme
Roggo Jean-Christophe
La conversion des caractères UNICODE est correctement assurée par l’utilisation
des classes java.io.InputStreamReader et java.io.OutputStreamWriter.
Cependant, les fonctionnalités de localisation ne sont pas spécifiées par CLDC.
Pour être distribuée dans le monde entier, une application doit être
internationalisée et localisée. Une application est dite internationalisée si elle
gère plusieurs encodages de caractères. Une application est dite localisée si elle
met en forme et interprète les dates, heures, zones horaires et monnaies selon
les règles locales de l’utilisateur, ou, pour être plus précis, selon les règles de sa
langue et de son pays.
Dans J2SE, la réalisation d’applications internationalisée et localisée est facilitée
grâce aux classes java.util.Calendar, java.util.Locale, java.text.Format
et java.io.Reader.
Dans J2ME CLDC, les choses se compliquent car ces classes ne sont pas toutes
présentes.
CLDC comprend les classes de J2SE suivantes :
ƒ java.io.DataInputStream
ƒ java.io.DataOutputStream
ƒ java.io.InputStreamReader
ƒ java.io.OutputStreamWriter
ƒ java.io.Reader
ƒ java.io.Writer
ƒ java.util.Calendar
ƒ java.util.Date
ƒ java.util.Timezone
Les classes InputStreamReader et OutputStreamWriter assurent la conversion
entre un flux d’octets et un flux de caractères UNICODE. Cette conversion est
effectuée en fonction du système d’encodage de caractères utilisé sur le
terminal.
Les classes Calendar, Date et TimeZone sont des sous-ensembles des classes
J2SE de même nom. Elles permettent d’intégrer le support de la zone horaire
locale de l’utilisateur. CLDC ne fournit rien de plus pour la localisation. C’est le
rôle des profils d’ajouter éventuellement des nouvelles fonctionnalités. Par
exemple, le profil MIDP prévoit l’implémentation d’une propriété système
microedition.locale, qui retourne la locale du terminal au format langue-pays.
Il est important de réaliser que la principale contrainte lorsque l’on développe
une application pour terminal mobile est l’espace mémoire (espace de stockage
et espace d’exécution). La première mesure à prendre consiste donc à ne pas
fournir qu’un seul fichier *.jar (JavaArchive) complet, qui prendrait en charge
toutes les situations, mais plutôt à créer un fichier *.jar pour chaque cas.
L’utilisateur téléchargera et installera la version de l’application pour son propre
cas. Si ce téléchargement est réalisé depuis un serveur Web via un servlet, par
exemple, ce dernier pourra même utiliser les en-têtes HTTP pour identifier la
locale utilisée et retourner le fichier *.jar approprié.
[DEL02][JSU04][API]
- 20 -
Travail de diplôme
Roggo Jean-Christophe
2.1.3. Support des propriétés d’environnement
La classe java.util.Properties existant au sein de J2SE n’est pas
implémentée dans la configuration CLDC. Toutefois, un jeu limité de propriétés
commençant par le mot-clé microedition peut être accédé en appelant la
méthode suivante :
System.getProperty(String key);
Le tableau ci-dessous dresse la liste de ces propriétés.
Clé
Description
Valeur
microedition.platform
microedition.encoding
microedition.configurations
microedition.profiles
Plate-frome ou terminal hôte
Encodage de caractères par défaut
Configuration et version J2ME
Nom des profils supportés
Par
Par
Par
Par
défaut
défaut
défaut
défaut
:
:
:
:
null
ISO8859_1
CLDC-1.0
null
[DEL02][JSU04][API]
2.1.4. Limitations diverses
La configuration CLDC est confrontées à plusieurs autres limitations notamment
concernant RMI (Remote Method Invocation), JNI (Java Native Interface) et les
threads.
ƒ
Pas de finalisation : CLDC ne propose pas de méthode de finalisation
des instances de classe Object.finalize(). Il n’est donc pas possible
de nettoyer un objet de la mémoire avant que le garbage collector le
fasse (le garbage collector nettoie l’instance de la mémoire au moment
où il constate que celle-ci n’est plus référencée).
ƒ
Limitations dans la gestion des erreurs : la palette de classes
d’erreur disponibles pour CLDC est limitée. La première raison à cela
est que la gestion de certaines erreurs est spécifique au terminal cible.
La deuxième raison est que le traitement des erreurs consomme
beaucoup de ressources et qu’il fallait l’adapter à des terminaux
disposant de peu de mémoire.
ƒ
Pas de JNI : JNI n’est pas implémenté dans CLDC, d’abord pour des
raisons de sécurité, ensuite parce que l’implémentation de JNI est trop
coûteuse en mémoire.
ƒ
Pas de chargeur de classe défini par l’utilisateur : pour des
raisons de sécurité le chargeur de classe intégré ne peut être surchargé
par l’utilisateur.
ƒ
Ni réflexion, ni RMI, ni sérialisation d’objet : la réflexion n’est pas
supportée, ce qui signifie que l’application ne peut pas inspecter le
contenu des classes, des objets ou des méthodes. Par conséquent,
toutes les fonctionnalités découlant de la réflexion comme RMI ou la
sérialisation d’objets ne sont pas supportées dans CLDC.
- 21 -
Travail de diplôme
Roggo Jean-Christophe
ƒ
Pas de groupe de threads ou de threads démons : le
multithreading est implémenté dans CLDC, mais les groupes de threads
ou les threads démons ne le sont pas. Les threads démons sont des
threads qui tournent en tâche de fond et proposent des services aux
autres threads.
ƒ
Pas de références faibles : les références faibles ne sont pas
autorisées dans CLDC. Une référence faible est un type de référence
vers un objet qui permet de déterminer si un objet est finalisé. Elle
permet de conserver une référence vers l’objet sans l’empêcher d’être
pris en compte par le garbage collector.
[DEL02][JSU04]
2.2. La sécurité dans CLDC
Les contraintes de taille mémoire ne permettent pas l’utilisation du modèle de
sécurité de J2SE dans J2ME. La prise en charge de la sécurité dans J2ME se
traduit par un mécanisme de prévérification des fichiers de classe puis par le
modèle de sécurité Sandbox.
2.2.1. Prévérification des fichiers de classe
Lorsqu’un fichier de classe est chargé, sa validité est vérifiée. Dans J2SE, cette
vérification est effectuée au moment de l’exécution (runtime) par la machine
virtuelle. Il est évident que les contraintes de taille mémoire auxquelles sont
confrontés les terminaux mobiles ne permettent pas d’implanter le même
mécanisme que dans J2SE.
CLCD définit donc un autre mécanisme de vérification des fichiers de classes.
Chaque méthode dans un fichier de classe Java téléchargé contient un nouvel
attribut. Cet attribut est ajouté au fichier de classe standard par un utilitaire
nommé prévérificateur (Preverifier). Le rôle de cet outil est d’analyser chaque
méthode se trouvant dans le fichier de classe. Cette prévérification est
généralement effectuée sur un ordinateur de bureau avant que le fichier de
classe soit téléchargé sur le terminal.
- 22 -
Travail de diplôme
Roggo Jean-Christophe
Comme l’illustre le schéma précédent, dans J2ME, une partie du travail de
vérification des fichiers de classes est effectuée sur la station de développement
de sorte à alléger la tâche du terminal cible.
Cette solution permet aux machines virtuelles Java compatibles CLDC de vérifier
les fichiers de classes beaucoup plus rapidement. Le mécanisme consomme un
minimum de mémoire tout en garantissant le même niveau de sécurité qu’avec
la solution standard déployée dans J2SE.
[DEL02][JSU04][DSU04]
2.2.2. Le modèle de sécurité Sandbox
Le principe du modèle de sécurité Sandbox Original est de considérer que le code
local est autorisé à avoir un accès total aux ressources vitales du système tandis
qu’un code téléchargé est suspect et ne peut accéder aux ressources fournies à
l’intérieur du Sandbox. Le Sandbox est donc une zone permettant d’exécuter en
toute sécurité un code qui aurait pu être dangereux pour le système.
Notons aussi que l’ensemble des fonctions natives accessibles à la machine
virtuelle est délimité. Le développeur ne peut pas télécharger de nouvelles
bibliothèques contenant des fonctionnalités natives, ni accéder à des fonctions
natives ne faisant pas partie des bibliothèques Java fournies par CLDC ou les
profils.
[DEL02][JSU04]
2.3. Les classes de CLDC
Cette section présente les classes disponibles au sein de la configuration CLDC.
CLDC comporte des classes héritées de J2SE et des classes spécifiques.
2.3.1. Les classes héritées de J2SE
Les classes héritées de J2SE existant au sein de CLDC proviennent des packages
java.lang, java.io et java.util. Le package java.lang contient les classes
sytème, les classes de type et les classes d’exception. Le package java.io
propose des classes de lecture-écriture des flux de base. Le package java.util,
quant à lui, fournit des classes utilitaires de base. Les classes reprises de J2SE
dans CLDC sont pour la plupart allégées (méthodes simplifiées ou supprimées)
de telle manière à ce qu’elles soient adaptées aux contraintes de taille mémoire.
Un certains nombre de packages sont inexistants dans CLDC, notamment :
java.lang.awt, java.lang.rmi, java.lang.security, et java.lang.sql.
Les classes contenues dans ces packages ne sont pas implémentées dans la
configuration CLDC en raison des limitations de la KVM et des contraintes de
taille mémoire auxquelles sont confrontés les terminaux mobiles compatibles
CLDC.
- 23 -
Travail de diplôme
Roggo Jean-Christophe
Le tableau ci-dessous recense les classes héritées de J2SE par CLDC.
Type
Package
Classes
Classes système
java.lang
Object, Class, Runtime, System, Thread,
Runnable, String, StringBuffer, Throwable
Classes de type de
données
java.lang
Boolean, Byte, Short, Integer, Long, Character
Classes d’exception
java.lang
Classes d’erreur
Classes de collection
Classes de calendrier et
d’horloge
Classes d’exception
java.lang
java.util
Exception,
ClassNotFoundException,IllegalAccessException,
InstantiationException, InterruptedException,
RuntimeException, ArithmeticException,
ArrayStoreException, ClassCastException,
IllegalArgumentException,
IllegalThreadStateException,
NumberFormatException,
IllegalMonitorStateException,
IndexOutOfBoundsException,
ArrayIndexOutOfBoundsException,
StringIndexOutOfBoundsException,
NegativeArraySizeException,
NullPointerException, SecurityException
Error, VirtualMachineError, OutOfMemoryError
Vector, Stack, Hashtable, Enumeration
java.util
Calendar, Date, Timezone
java.util
Classes d’exception
java.io
Classes d’entrées-sorties
java.io
Classes utilitaires
java.util, java.lang
EmptyStackException, NoSuchElementException
EOFException, IOException,
InterruptedException,
UnsupportedEncodingException,
UTFDataFormatException
InputStream, OutputStream,
ByteArrayInputStream, ByteArrayOutputStream,
DataInput, DataOutput, DataInputStream,
DataOutputStream, Reader, Writer,
InputStreamReader, OutputStreamWriter,
PrintStream
Java.util.Random, java.lang.Math
[DEL02][API]
2.3.2. Les classes spécifiques de CLDC
En ce qui concerne les entrées-sorties et la connectivité réseau, la configuration
CLDC n’hérite pas de la totalité des classes contenues dans le package java.io
de J2SE. De nouvelles classes ont été définies et regroupées sous le nom de GCF
(Generic Connection Framework) dans le package javax.microedition.io.
Ces classes spécifiques à la configuration CLDC sont les suivantes :
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
Connection
HttpConnection
ConnectionNotFoundException
Connector
ContentConnection
Datagram
DatagramConnection
InputConnection
OutputConnection
- 24 -
Travail de diplôme
ƒ
ƒ
Roggo Jean-Christophe
StreamConnection
StreamConnectionNotifier
Comme son nom l’indique, CLDC (Connected Limited Device Configuration) est
conçue pour les terminaux pouvant se connecter au monde extérieur, que ce soit
par liaison série, infrarouge ou sans fil. C’est l’objet du GCF (Generic Connection
Framework), qui regroupe un ensemble de classes et d’interfaces modélisant des
types différents de connexions, allant de la simple connexion unidirectionnelle à
une connexion datagramme. Le GCF repose sur la notion d’abstraction de la
même manière que JDBC pour les accès aux bases de données.
Toutes les connexions sont crées avec une même méthode statique dans une
classe appelée javax.microedition.Connector. L’instruction permettant
d’ouvrir une connexion aura la forme suivante :
Connector.open(“<protocole>:<adresse>;<paramètres>”);
CLDC ne définit pas d’implémentation de protocole. Ce sont les profils qui doivent
implémenter certains des protocoles proposés par les spécifications de CLDC.
Les différents protocoles que CLDC propose sont listés dans le tableau cidessous.
Protocole
Valeur
Exemple
HTTP
Socket
Port de communication
série
Datagramme
Fichier
Système de fichiers
réseau
http
Socket
Connector.open(“http://www.ruchat.ch”) ;
Connector.open(“socket://222.223.223.222:1111”);
comm
Connector.open(“comm.:0; baudrate=9600”);
datagram
file
Connector.open(“datagram://222.223.223.222”);
Connector.open(“file:config.dat”);
nfs
Connector.open(“nfs:/netinnovations.fr/config.dat”);
Le GCF définit huit types de connexions toutes représentées sous la forme
d’interfaces de connexion définies dans le package javax.microedition.io.
Le tableau ci-dessous recense ces connexions.
Interface
ContentConnection
StreamConnectionNotifier
InputConnexion
OutputConnection
DatagramConnection
Connection
StreamConnection
HttpConnection
Description
Permet une communication HTTP de base. Ne supporte
que l’encodage de caractères, le type MIME et la taille.
Permet une communication avec un client via une
connexion par socket côté serveur.
Gère une connexion en entrée.
Gère une connexion en sortie.
Permet de communiquer avec une connexion
datagramme (UDP p.ex)
Objet de connexion de base.
Permet une communication basée sur les sockets.
Permet de communiquer avec le protocole HTTP 1.1.
- 25 -
Travail de diplôme
Roggo Jean-Christophe
Ces différentes interfaces de connexions sont organisées selon la hiérarchie
présentée dans le schéma ci-dessous.
«interface»
Connection
«interface»
StreamConnectionNotifier
«interface»
InputConnection
«interface»
OutputConnection
«interface»
DatagramConnection
«interface»
StreamConnection
«interface»
ContentConnection
«interface»
HttpConnection
Vous trouverez un exemple de mise en œuvre du composant HttpConnection
dans l’annexe n°3.
Pour plus de détails concernant la configuration CLDC consultez la référence
suivante :
http://jcp.org/aboutJava/communityprocess/final/jsr030/index.html
[DEL02][API]
- 26 -
Travail de diplôme
Roggo Jean-Christophe
Dans cette troisième partie, vous trouverez les éléments théoriques nécessaires
pour entreprendre un développement MIDP (Mobile Information Device Profile).
3. Le profil MIDP
Un MIDlet est une application développée pour MIDP. C’est en quelque sorte un
applet destiné à un terminal mobile MIDP et non pas à un navigateur Web. Le
cycle de vie du développement d’une application pour MIDP est constitué des
étapes suivantes :
ƒ
Ecriture de l’application avec les API de MIDP.
ƒ
Compilation et prévérification de l’application.
ƒ
Test de l’application avec un émulateur.
ƒ
Packaging de l’application.
ƒ
Test de l’application packagée sur le terminal mobile.
Nous reviendrons plus en détails sur ces différentes étapes dans la partie
pratique de ce dossier.
3.1. Le MIDlet
3.1.1. Cycle de vie d’un MIDlet
Toutes les applications développées pour le profil MIDP doivent dériver de la
classe abstraite MIDlet contenue dans le package javax.microedition.midlet.
La classe MIDlet gère le cycle de vie de l’application. Un MIDlet peut se
retrouver dans quatre états différents :
ƒ
chargé (loaded)
ƒ
actif (active)
ƒ
suspendu (paused)
ƒ
détruit (destroyed)
Lorsqu’un MIDlet est chargé sur un terminal et que le constructeur est appelé
son état est chargé (loaded). C’est état précède l’état actif (active) découlant de
l’appel de la méthode startApp() par le gestionnaire d’application. Le
gestionnaire d’application est un logiciel dépendant du terminal mobile. Il est
implémenté par le fabricant du terminal. Ce gestionnaire gère l’installation,
l’exécution et le retrait des MIDlets sur le terminal. Il fournit généralement un
mécanisme de gestion des erreurs. Après l’appel de la méthode startApp() le
MIDlet se retrouve dans l’état actif jusqu’à ce que le gestionnaire appelle la
méthode pauseApp() ou destroyApp() : pauseApp() suspend le MIDlet tandis
que destroyApp(boolean unconditional) termine l’exécution du MIDlet.
- 27 -
Travail de diplôme
Roggo Jean-Christophe
Les trois méthodes permettant de gérer le cycle de vie d’un MIDlet sont des
méthodes abstraites et doivent obligatoirement être redéfinies. Le squelette
d’une application pour le profil MIDP sera donc le suivant :
import javax.microedition.midlet.* ;
public class Test extends MIDlet {
public Test() {
}
public void startApp() {
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
La figure ci-dessous donne un aperçu du cycle de vie d’un MIDlet.
La méthode pauseApp() permet de libérer les ressources qui ne sont pas
nécessaires lorsque l’application est suspendue. Un MIDlet exécuté sur un
téléphone mobile sera par exemple suspendu au moment ou l’utilisateur reçoit
un appel téléphonique. Le MIDlet devra alors libérer les ressources jusqu’à la
reprise de son exécution.
La méthode destroyApp(boolean unconditional) prend un paramètre de type
booléen en entrée. Si ce paramètre est false, le MIDlet peut refuser qu’on
termine son exécution en lançant l’exception MIDletStateChangeException.
- 28 -
Travail de diplôme
Roggo Jean-Christophe
La méthode resumeRequest() permet au MIDlet d’indiquer son intention de
passer à l’état actif.
Lorsqu’un MIDlet décide de se mettre dans l’état suspendu, il doit informer le
gestionnaire d’application en appelant la méthode notifyPaused(). Le
gestionnaire d’application doit également être informé de la fin de l’exécution
d’un MIDlet en appelant la méthode notifyDestoyed().
[DEL02][JSU04]
3.1.2. L’accès aux attributs du fichier *.jar
Le moyen le plus simple pour distribuer une application MIDP est d’utiliser le
format de fichier archive *.jar. Un certain nombre de fichiers sont regroupés
dans un fichier archive *.jar. Ce sont les fichiers de classes, les fichiers de
ressources (des images au format *.png par exemple) et le fichier décrivant le
contenu du fichier *.jar lui-même. Ce dernier fichier se nomme manifest.mf.
Le tableau ci-dessous dresse la liste des attributs pouvant être définis dans le
fichier manifest.mf.
Attributs
Description
MIDlet-Name
MIDlet-Version
MIDlet-Vendor
MIDlet-Icon
MIDlet-Description
Nom du package MIDlet
Numéro de version du MIDlet
Auteur du MIDlet
Icône associée au MIDlet (image au format *.png)
Description du MIDlet
URL pouvant fournir des informations supplémentaires
sur le MIDlet et/ou le vendeur
Contient trois informations : le nom du MIDlet, l’icône
de ce MIDlet, le nom de la classe chargée par le
gestionnaire d’applications
URL du fichier *.jar
Taille du fichier *.jar (en octets)
Nombre minimum d’octets nécessaires pour le
stockage de données persistantes
Profil J2ME imposé par le MIDlet
Configuration J2ME imposée par le MIDlet
MIDlet-Info-URL
MIDlet-<n>
MIDlet-Jar-URL
MIDlet-Jar-Size
MIDlet-Data-Size
MicroEdition-Profile
MicroEdition-Configuration
Seuls les attributs MIDlet-Name, MIDlet-Version, MIDlet-Vendor, MIDlet-<n>,
MicroEdition-Profile et MicroEdition-Configuration sont obligatoires.
Un MIDlet peut accéder aux attributs contenus dans le fichier manifest.mf grâce
à la méthode javax.microedition.midlet.MIDlet.getAppProperty(String
key). Pour obtenir des informations sur l’auteur du MIDlet on utilisera la
méthode de cette manière :
String infoAuteur = getAppProperty(“MIDlet-Vendor”);
[DEL02][API]
- 29 -
Travail de diplôme
Roggo Jean-Christophe
3.2. L’interface utilisateur
Comme nous l’avons vu dans la deuxième partie de ce dossier, la configuration
CLDC ne fournit pas les classes nécessaires au développement d’une interface
utilisateur. C’est le rôle du profil de fournir ces classes. Cette section présente les
API proposées par le profil MIDP pour le développement d’une interface
utilisateur.
L’interface utilisateur des terminaux mobiles est sujette à des contraintes
différentes de celles d’un ordinateur de bureau (taille de l’affichage restreinte,
pas de souris …). C’est pourquoi les API d’interface utilisateur fournies par MIDP
ne s’appuient pas sur les API de J2SE comme AWT (Abstract Window Toolkit) ou
Swing.
3.2.1. Les principes de l’interface utilisateur MIDP
L’interface utilisateur MIDP est constituée de deux API, l’une de haut niveau et
l’autre de bas niveau.
La première API a un haut niveau d’abstraction, qui assure un non moins haut
niveau de portabilité. Cette API offre peu de contrôle sur l’apparence visuelle
(forme, couleur, police de caractères) des composants.
La seconde API a un faible niveau d’abstraction. Elle offre un contrôle précis du
positionnement et de la gestion des éléments graphiques. Elle permet également
d’accéder aux événements de saisie. Les MIDlets qui accèdent à l’API de bas
niveau ne garantissent pas la portabilité car cette API fournit des fonctionnalités
spécifiques aux terminaux, comme la taille de l’écran ou l’utilisation d’un système
de pointage.
L’interface utilisateur repose sur la notion d’écran, ou Screen, un objet qui
encapsule les composants graphiques du terminal. Un seul écran peut être visible
à la fois et l’utilisateur navigue parmi les composants de cet écran. On distingue
trois types d’écran :
ƒ
Ecran comprenant des composants complexes, comme les composants
List ou TextBox. Sa structure est prédéfinie, et l’application ne peut y
ajouter d’autres composants.
ƒ
Ecran comprenant un composant formulaire Form. L’application peut
ajouter du texte, une image et des composants liés au formulaire.
ƒ
Ecran utilisé avec l’API de bas niveau, comme les sous-classes de la
classe Canvas.
La classe Display est le gestionnaire d’affichage utilisé par le MIDlet. Elle fournit
entre autres les méthodes nécessaires pour connaître les capacités d’affichage du
terminal. Pour rendre visible un écran, il suffit d’appeler la méthode
setCurrent(Displayable nextDisplayable) de la classe Display.
Un certain nombre de règles sont à respecter lors du développement d’une
interface graphique avec le profil MIDP :
ƒ
Concevoir des interfaces utilisateur simples et faciles à utiliser.
ƒ
Utiliser l’API de haut niveau pour garantir au maximum la portabilité.
- 30 -
Travail de diplôme
Roggo Jean-Christophe
ƒ
L’application ne doit pas dépendre d’une taille d’écran particulière, elle
doit demander au terminal la taille de l’affichage et s’adapter à cette
contrainte.
ƒ
La saisie d’information pouvant être pénible, il faut privilégier les listes
de choix dans lesquelles l’utilisateur est invité à faire une sélection.
ƒ
Eviter l’utilisation de bibliothèques de classes tierces comme kAWT, qui
est une version allégée de AWT adaptée à la KVM.
[DEL02][JSU04][API]
3.2.2. Les classes d’affichage
Les briques de base de l’interface utilisateur MIDP sont les calsses Displayable,
Display,
Screen
et
Canvas
contenus
dans
le
package
javax.microedition.lcdui.
La figure ci-dessous présente la hiérarchie des classes de l’interface utilisateur
MIDP.
[DEL02][API]
3.2.2.1. La classe Display
La classe Display correspond au gestionnaire d’affichage. Elle permet de lire les
propriétés du terminal et de demander l’affichage des objets sur le terminal. Il ne
peut y avoir qu’une seule instance de Display par MIDlet. Cette unique instance
peut être obtenue à n’importe quel moment durant l’exécution du MIDlet en
appelant la méthode suivante :
- 31 -
Travail de diplôme
Roggo Jean-Christophe
static Display getDisplay(MIDlet m)
A un gestionnaire d’affichage peut correspondre plusieurs objets affichables
(Displayable). Pour obtenir l’objet Displayable courant, la méthode suivante
doit être appelée :
Displayable getCurrent()
Le tableau ci-dessous regroupe l’ensemble des méthodes de la classe Display.
Méthode
Description
Displayable getCurrent()
Retourne une référence à l’objet Displayable courant
Spécifie un nouvel objet Displayable, en précisant
éventuellement une alerte qui sera affichée avant que
l’objet nextDisplayable soit affiché.
Indique si le terminal supporte les couleurs.
Retourne le nombre de couleurs supportées.
Retourne l’objet Display, unique pour ce MIDlet.
Appelle l’objet spécifié dès la fin du cycle repaint
(lors de l’utilisation de l’interface utilisateur bas
niveau).
void setCurrent(Displayable nextDisplayable)
void setCurrent(Alert alert, Displayable
nextDisplayable)
boolean isColor()
int numColors()
static Display getDisplay(MIDlet m)
void CallSerially(Runnable r)
[DEL02][API]
3.2.2.2. La classe Displayable
La classe abstraite Displayable modélise un objet qui peut être affiché à l’écran.
Cette classe est la super classe commune des classes abstraites Screen (API
haut niveau) et Canvas (API bas niveau).
Le tableau ci-dessous liste les méthodes de la classe Displayable.
Méthodes
Description
void addCommand(Command cmd)
void removeCommand(Command cmd)
boolean isShown()
void setCommandListener(CommandListener l)
Ticker getTicker()
void setTicker(Ticker ticker)
Ajoute et retire une commande.
Indique si l’objet Displayable est visible ou non.
Met en place un listener.
Permet d’associer un ticker à l’objet affichable.
[DEL02][API]
3.2.2.3. La classe Screen
La classe abstraite Screen dérive de la classe Displayable. Elle correspond à la
brique principale de l’API d’interface utilisateur de haut niveau. Le contenu de
l’affichage et l’interaction avec l’utilisateur sont définis par les sous-classes de
Screen. Le contenu affiché est rafraîchi automatiquement (nul besoin d’appeler
une méthode spécifique). Il est d’ailleurs recommandé qu’une application ne
change le contenu affiché que lorsque celui-ci n’est pas visible (pendant qu’un
autre objet Displayable est en cours d’affichage par exemple). Changer le
- 32 -
Travail de diplôme
Roggo Jean-Christophe
contenu d’un objet Screen lorsqu’il est visible peut poser des problèmes de
performances sur certains terminaux.
La classe Screen hérite naturellement de toutes les méthodes de sa super classe
Displayable.
[DEL02][API]
3.2.2.4. La classe Canvas
La classe abstraite Canvas est la sous-classe de Displayable qui correspond à la
brique principale de l’API d’interface utilisateur bas niveau. Lorsqu’on étend la
classe Canvas, il faut impérativement implémenter la méthode abstraite
paint(). Par défaut, les implémentations des méthodes de gestion des
évènements sont vides. On ne surchargera donc que les méthodes utilisées. De
manière générale, on utilise la classe Canvas pour accéder aux évènements de
bas niveau et les gérer. Il est également possible de gérer les évènements de
haut niveau en ajoutant des commandes au Canvas grâce aux méthodes
addCommand(Command cmd) et setCommandListener(CommandListener l)
héritées de la super-classe Displayable. Les tableaux ci-dessous dressent la
liste des méthodes et des champs de la classe Canvas.
Méthodes
Description
protected Canvas()
Constructeur de la classe Canvas
Détecte la touche pressée. La première retourne le
nom de la touche, la deuxième l’action de jeu associée
à la touche actionnée et la troisième l’opération
inverse, à savoir le code de la touche associée à
l’action de jeu spécifiée.
String getKeyName(int keyCode)
int getGameAction(int keyCode)
int getKeyCode(int gameAction)
protected void keyPressed(int keyCode)
protected void keyReleased(int keyCode)
protected void keyRepeated(int keyCode)
boolean hasRepeatEvents()
Gère les touches pressées, relâchées et actionnées de
manière répétitive.
Indique si l’événement keyRepeated est supporté.
Indique si un système de pointage est disponible sur le
terminal.
Indique si le terminal supporte les évènements de
déplacement du pointeur.
boolean hasPointerEvents()
boolean hasPointerMotionEvents()
protected void pointerDragged(int x, int y)
protected void pointerPressed(int x, int y)
protected void pointerReleased(int x, int y)
int getHeigth()
int getWidth()
Gère les événements de déplacement, de pression et
de relâchement du pointeur.
Retourne la dimension de la zone Displayable.
boolean isDoubleBuffered()
Indique si les graphiques sont gérés avec un doubletampon.
void repaint()
void repaint(int x, int y, int width, int
heigth)
Retrace le contenu du Canvas dans sa totalité ou
partiellement.
Evidemment, la classe Canvas hérite de toutes les méthodes de sa super-classe
Displayable.
Champ
Description
DOWN
FIRE
GAME_A
Touche pour descendre
Touche pour faire feu
Touche A
- 33 -
Travail de diplôme
GAME_B
GAME_C
GAME_D
KEY_NUM0
KEY_NUM1
KEY_NUM2
KEY_NUM3
KEY_NUM4
KEY_NUM5
KEY_NUM6
KEY_NUM7
KEY_NUM8
KEY_NUM9
KEY_POUND
KEY_STAR
LEFT
RIGHT
UP
Roggo Jean-Christophe
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
Touche
B
C
D
numérique 0
numérique 1
numérique 2
numérique 3
numérique 4
numérique 5
numérique 6
numérique 7
numérique 8
numérique 9
dièse (#)
étoile (*)
pour aller à gauche
pour aller à droite
pour aller en haut
[DEL02][API]
Ce dossier n’abordera pas plus en détail l’API d’interface utilisateur de bas
niveau. La section suivante traite de l’interface utilisateur de haut niveau de
manière détaillée. Notons que seules les classes et méthodes du profil MIDP 1.0
sont décrites dans la section suivante. Des classes et méthodes supplémentaires
ont été ajoutées dans la version 2.0 de MIDP (cf documentation fournie avec
l’outil J2ME Wireless Toolkit 2.1).
3.2.3. L’interface utilisateur de haut niveau
L’API de haut niveau permet d’utiliser des composants d’interface utilisateur,
mais aucun accès direct à l’écran ni aux événements de saisies n’est possible.
C’est l’implémentation MIDP qui décide de la manière de représenter les
composants et du mécanisme de gestion des saisies de l’utilisateur.
Notons qu’il est possible d’utiliser l’API de haut niveau et l’API de bas niveau
dans un même MIDlet mais pas simultanément. Par exemple, les jeux qui
utilisent l’API de bas niveau pour contrôler l’écran peuvent également utiliser
l’API de haut niveau pour l’affichage des meilleurs scores.
Les composants proposés par l’API de haut niveau MIDP sont regroupés au sein
du package javax.microedition.lcdui.
Les deux tableaux ci-dessous recensent les classes et interfaces de l’API
d’interface utilisateur de haut niveau contenues dans le package
javax.microedition.lcdui.
Interface
Choice
CommandListener
ItemStateListener
Description
Définit la sélection d’un élément d’un groupe de choix
prédéfini.
Permet de gérer les évènements de haut niveau.
Permet de gérer les évènements de changement
interne aux éléments interactifs (dans un composant
Form)
Classe
Description
Alert
AlertType
Permet l’affichage d’un message d’alerte.
Fournit une indication sur la nature de l’alerte.
- 34 -
Travail de diplôme
Roggo Jean-Christophe
Implémente un groupe d’éléments Choice. Utilisé dans
un Form.
Implémente une commande. Ne contient pas les
actions déclenchées par l’activation de la commande.
Implémente un champ de date et heure. Utilisé dans
un Form.
Implémente un formulaire. C’est un conteneur pour un
ensemble d’éléments disparates (image, texte …)
Implémente une jauge graphique.
Implémente une image graphique.
Permet de spécifier la disposition d’une Image dans un
formulaire ou dans une alerte.
Super-classe de tous les composants pouvant être
ajoutés à un Form ou à une Alert.
Implémente une liste de choix (menu).
Implémente un élément associable à un composant
Form et contenant une chaîne de caractères non
modifiable.
Implémente une zone de saisie.
Implémente une zone de saisie associable à un
composant Form.
Implémente un composant permettant de faire défiler
du texte en continu sur l’écran.
ChoiceGroup
Command
DateField
Form
Gauge
Image
ImageItem
Item
List
StringItem
TextBox
TextField
Ticker
[DEL02][API]
Vous trouverez dans l’annexe n°1 un exemple récapitulatif complet dans lequel la
plupart de ces classes sont utilisées.
3.2.3.1. L’interface Choice
L’interface Choice définit les caractéristiques d’une liste de choix. Les classes
ChoiceGroup et List implémentent cette interface. Les méthodes et les champs
définis dans l’interface Choice sont recensés dans les tableaux ci-dessous
[DEL02][API].
Méthode
Description
int append(String stringPart, Image imagePart)
void insert(int elementNum, String stringPart,
Image imagePart)
void delete(int elementNum)
int getSelectedFlags(boolean[]
selectedArray_return)
void setSelectedFlags(boolean[] selectedArray)
int size()
String getString(int elementNum)
Image getImage(int elementNum)
void set(int elementNum, String stringPart,
Image imagePart)
void setSelectedIndex(int elementNum, boolean
selected)
int getSelectedIndex()
boolean isSelected(int elementNum)
Champ
EXCLUSIVE
IMPLICIT
MULTIPLE
Ajoute un élément et son image associée en fin de
liste.
Insère un élément et son image associée juste avant
l’élément spécifié.
Supprime l’élément spécifié de la liste.
Lit et modifie le status de selection des elements de la
liste.
Retourne le nombre d’éléments de la liste.
Lit le texte et l’image associée de chaque élément de
la liste.
Modifie un élément de la liste.
Sélectionne ou désélectionne un élément de la liste.
Retourne le numéro de l’élément sélectionné.
Indique si l’élément est sélectionné ou on.
Description
L’utilisateur ne peut sélectionner qu’un seul élément à
la fois.
L’élément qui possède le focus est sélectionné quand
une commande est activée.
L’utilisateur peut sélectionner plusieurs éléments.
- 35 -
Travail de diplôme
Roggo Jean-Christophe
3.2.3.2. La classe List
La classe List implémente l’interface Choice et étend la classe abstraite Screen.
Elle permet de créer et de manipuler une liste de choix. On utilisera volontiers
cette classe pour implémenter un menu. La classe List implémente l’ensemble
des méthodes de l’interface Choice (cf tableaux de la sectiion 3.2.3.1) et
propose en outre les deux constructeurs et le champ décrits dans les tableaux cidessous [DEL02][API].
Méthode
Description
List(String title, int listType)
List(String title, int listType, String[]
stringElements, Image[] imageElements)
Constructeurs de la classe List. Le premier crée une
liste en spécifiant son titre et son type. Le second
crée une liste en spécifiant en plus les éléments
textuels et graphique la constituant.
Champ
Description
SELECT_COMMAND
C’est une commande spéciale que commandAction
peut utiliser pour savoir que l’utilisateur a sélectionné
un élément dans une liste IMPLICIT.
Les champs EXCLUSIVE, IMPLICIT et MULTIPLE sont hérités de l’interface
javax.microedition.lcdui.Choice. Ces champs spécifie le type de liste. Si le
type de liste est EXCLUSIVE, l’utilisateur ne peut sélectionner qu’un seul élément
à la fois. Si le type de liste est IMPLICIT, l’élément qui possède le focus est
sélectionné lorsqu’une commande est activée. Si le type de liste est MULTIPLE,
l’utilisateur peut sélectionner plusieurs éléments à la fois.
Ci-dessous vous trouverez une illustration du composant List implémentant le
menu principal du MIDlet testGUI (cf annexe n° 1).
- 36 -
Travail de diplôme
Roggo Jean-Christophe
3.2.3.3. La classe Item
La classe abstraite Item est la super classe de tous les composants pouvant être
associés à un formulaire (cf 3.2.3.4). Elle comprend les méthodes présentées
dans le tableau ci-dessous [DEL02][API].
Méthode
Description
String getLabel()
void setLabel(String label)
Permet de lire et de modifier l’étiquette associée à
l’élément.
3.2.3.4. La classe Form
La classe Form dérive de la classe abstraite Screen. Elle permet d’utiliser un
formulaire auxquel peut être associé un ensemble d’éléments disparates (image,
texte, champ de texte, liste de choix …) dérivant tous de la classe abstraite Item
(cf 3.2.3.3). Les méthodes de cette classe sont présentées dans le tableau cidessous [DEL02][API].
Méthode
Description
Form(String title)
Form(String title, Item[] items)
Constructeurs permettant de créer un formulaire en
spécifiant son titre uniquement ou en spécifiant son
titre et ses éléments associés.
int append(Item item)
int append(Image img)
int append(String str)
Permet d’ajouter un élément de type Item, une image
ou du texte.
void insert(int itemNum, Item item)
void delete(int itemNum)
Item get(int itemNum)
void set(int itemNum, Item item)
int size()
void setItemStateListener(ItemStateListener
iListener)
Permet d’insérer un élément de type Item dans le
formulaire à la place spécifiée.
Permet de supprimer du formulaire l’élément spécifié.
Permet de lire et de modifier les éléments du
formulaire.
Retourne le nombre d’éléments contenus dans le
formulaire.
Permet de mettre en place un listener pour le
formulaire.
La classe Form hérite évidemment de toutes les méthodes implémentées dans la
classe abstraite Screen.
Ci-dessous vous trouverez une illustration du composant Form mis en œuvre
dans l’application testGUI (cf annexe n° 1).
- 37 -
Travail de diplôme
Roggo Jean-Christophe
3.2.3.5. La classe ChoiceGroup
La classe ChoiceGroup implémente l’interface Choice et hérite de la classe
abstraite Item (cf 3.2.3.3). Le composant ChoiceGroup doit être associé à un
formulaire (cf 3.2.3.4). Cette classe permet d’utiliser une liste de choix au sein
d’un formulaire. Elle implémente l’ensemble des méthodes de l’interface Choice
(cf 3.2.3.1) et propose en outre les deux constructeurs présentés dans le tableau
ci-dessous [DEL02][API].
Méthode
ChoiceGroup(String label, int choiceType)
ChoiceGroup(String label, int choiceType,
String[] stringElements, Image[]
imageElements)
Description
Permet de créer une liste de choix en précisant
l’intitulé et le type (EXCLUSIVE, IMPLICIT, MULTIPLE).
Permet de créer une liste de choix en fournissant les
éléments de cette liste en paramètre sous forme de
tableaux.
La classe ChoiceGroup hérite naturellement des méthodes de la classe Item.
Ci-dessous vous trouverez une illustration du composant ChoiceGroup mis en
œuvre dans l’application testGUI (cf annexe n° 1).
3.2.3.6. La classe TextField
La classe TextField dérive de la classe Item (cf 3.2.3.3). Cela signifie donc que
ce composant doit être associé à un formulaire (cf 3.2.3.4). Cette classe permet
d’utiliser un champ de texte au sein d’un formulaire. Les méthodes de la classe
TextField sont répertoriées dans le tableau ci-dessous.
Méthode
TextField(String label, String text, int
maxSize, int constraints)
String getString()
void setString(String text)
int size()
int getConstraints()
void setConstraints(int constraints)
int getMaxSize()
int setMaxSize(int maxSize)
Description
Constructeur permettant de créer un champ de texte
en spécifiant l’intitulé, le contenu, la taille maximale et
les contraintes de saisie.
Permet de lire et de modifier le contenu du champ de
texte.
Retourne le nombre de caractères contenus dans le
champ de texte.
Permet de lire et de modifier les contraintes de saisie.
Permet de lire et de modifier le nombre de caractères
maximal pouvant être contenus dans le champ.
- 38 -
Travail de diplôme
int getCaretPosition()
void insert(char[] data, int offset, int
length, int position)
void insert(String src, int position)
void setChars(char[] data, int offset, int
length)
void delete(int offset, int length)
int getChars(char[] data)
Roggo Jean-Christophe
Retourne la position du curseur dans le champ de
texte.
Permet d’insèrer un tableau de caractères ou une
chaîne de caractère dans le champ de texte à la
position spécifiée.
Permet de remplacer une partie du contenu du champ
de texte par le tableau de caractères spécifié.
Permet de supprimer une partie du contenu du champ
de texte.
Permet de copier le contenu du champ de texte dans
un tableau de caractères.
Les méthodes héritées de la classe Item sont également disponibles.
La classe TextField comprend un certain nombre de constantes permettant de
spécifier des contraintes de saisie. Le tableau ci-dessous contient une description
pour chacune de ces constantes.
Champ
Description
ANY
CONSTRAINT_MASK
EMAILADDR
NUMERIC
L’utilisateur peut saisir n’importe quel texte.
Masque de saisie.
L’utilisateur doit saisir une adresse e-mail.
L’utilisateur doit saisir un nombre entier.
Les caractères saisis ne sont pas visibles à l’écran
(pour la saisie d’un mot de passe).
L’utilisateur doit saisir un numéro de téléphone.
L’utilisateur doit saisir une URL.
PASSWORD
PHONENUMBER
URL
[DEL02][API]
Ci-dessous vous trouverez une illustration du composant TextField mis en
œuvre dans l’application testGUI (cf annexe n° 1).
3.2.3.7. La classe DateField
La classe DateField dérive de la classe Item (cf 3.2.3.3). Cette classe permet
d’utiliser un champ de date et d’heure au sein d’un formulaire (cf 3.2.3.4). Le
tableau suivant contient une description pour chacune des méthodes de la classe
DateField [DEL02][API].
- 39 -
Travail de diplôme
Roggo Jean-Christophe
Méthode
Description
DateField(String label, int mode, TimeZone
timeZone)
DateField(String label, int mode)
Date getDate()
Void setDate(Date date)
int getInputMode()
void setInputMode(int mode)
Constructeurs permettant de créer un champ de date
en spécifiant la localisation ou pas.
Permet de lire et de modifier la valeur du champ de
date.
Permet de lire et de modifier le mode du champ de
date.
Les méthodes héritées de la classe Item sont également disponibles.
La classe DateField comprend trois constantes permettant de spécifier le mode
du champ. Le mode indique la nature de l’information que l’utilisateur peut saisir.
Le tableau ci-dessous contient une description pour chacun de ces modes
[DEL02][API].
Champ
Description
DATE
TIME
DATE_TIME
L’utilisateur ne peut saisir qu’une date.
L’utilisateur ne peut saisir qu’une heure.
L’utilisateur peut saisir la date et l’heure.
Ci-dessous vous trouverez une illustration du composant DateField mis en
œuvre dans l’application testGUI (cf annexe n° 1).
3.2.3.8. La classe Gauge
La classe Gauge dérive également de la classe Item. Elle permet d’utiliser une
jauge graphique au sein d’un formulaire. Ces méthodes sont recensées dans le
tableau ci-dessous [DEL02][API].
Méthode
Description
Gauge(String label, boolean interactive, int
maxValue, int initialValue)
Constructeur permettant de créer une jauge en
spécifiant l’étiquette, le mode, la valeur maximale et la
valeur initiale.
int getMaxValue()
void setMaxValue(int maxValue)
int getValue()
void setValue(int value)
boolean isInteractive()
Permet de lire et de modifier la valeur maximale.
Permet de lire et de modifier la valeur courante de la
jauge.
Permet de savoir si la jauge est interactive ou non.
- 40 -
Travail de diplôme
Roggo Jean-Christophe
Une jauge peut être interactive ou non. Dans le cas d’une jauge non interactive,
seule l’application peut modifier sa valeur. Dans le cas d’une jauge interactive,
l’utilisateur peut modifier sa valeur.
Ci-dessous vous trouverez une illustration du composant Gauge mis en œuvre
dans l’application testGUI (cf annexe n° 1).
3.2.3.9. La classe ImageItem
ImageItem est une classe qui encapsule une instance de la classe Image (cf
documentation fournie avec le J2ME Wireless Toolkit). Comme les autres
composants associables à un formulaire, elle étend la classe abstraite Item.
Grâce à cette classe, il est possible de spécifier la disposition d’une image
associée à un formulaire. Pour cela, elle fournit les méthodes et champs décrits
dans les tableaux ci-dessous [DEL02][API].
Méthode
Description
ImageItem(String label, Image img, int layout,
String altText)
String getAltText()
void setAltText(String text)
Image getImage()
void setImage()
int getLayout()
void setLayout(int layout)
Constructeur prenant en paramètres l’étiquette,
l’image, la disposition et le texte de remplacement.
Permet de lire et de modifier le texte de
remplacement.
Permet de lire et de modifier l’objet Image encapsulé.
Permet de lire et de modifier la disposition de l’image
dans le formulaire.
La classe ImageItem comprend un certain nombre de champs correspondant à
des constantes qui spécifient la disposition du composant au sein d’un
formulaire. Le tableau ci-dessous présente ces champs.
Méthode
Description
LAYOUT_CENTER
LAYOUT_DEFAULT
LAYOUT_LEFT
LAYOUT_RIGHT
LAYOUT_NEWLINE_AFTER
LAYOUT_NEWLINE_BEFORE
L’image est centrée horizontalement.
L’image est placée selon le positionnement par défaut.
L’image est cadrée à gauche.
L’image est cadrée à droite.
Une nouvelle ligne commence après l’image.
Une nouvelle ligne commence avant l’image.
- 41 -
Travail de diplôme
Roggo Jean-Christophe
3.2.3.10. La classe StringItem
La classe StringItem encapsule une instance de la classe String. Elle dérive de
la classe Item et permet d’associer du texte statique à un formulaire. Ces
méthodes sont décrites dans le tableau ci-dessous [DEL02][API].
Méthode
Description
StringItem(String label, String text)
Constructeur prenant l’étiquette et le contenu textuel
en paramètres.
String getText()
void setText(String text)
Permet de lire et de modifier le contenu textuel.
3.2.3.11. La classe TextBox
La classe TextBox étend la classe abstraite Screen. Elle modélise un champ de
saisie qui peut être affiché sans être contenu dans un formulaire. Son interface
est très similaire à celle de la classe TextField (cf 3.2.3.6).
Ci-dessous vous trouverez une illustration du composant TextBox mis en œuvre
dans l’application testGUI (cf annexe n° 1).
3.2.3.12. La classe Alert
La classe Alert étend la classe abstraite Screen. Elle modélise une boîte de
dialogue affichant un message textuel, éventuellement accompagné d’une image
ou d’un son. On l’utilisera volontiers pour afficher un avertissement, une erreur,
une alarme … L’interface de cette classe est décrite dans le tableau ci-dessous.
Méthode
Alert(String title)
Alert(String title, String alertText, Image
alertImage, AlertType alertType)
String getString()
void setString(String str)
AlertType getType()
void setType(AlertType type)
int getDefaultTimeout()
Description
Constructeur permettant de créer une alerte en
spécifiant son titre uniquement ou en spécifiant en
plus son contenu textuel, son image associée et son
type.
Permet de lire et de modifier le contenu textuel de
l’alerte.
Permet de lire et de modifier le type de l’alerte.
Retourne la durée pendant laquelle l’alerte est affichée
- 42 -
Travail de diplôme
int getTimeout()
void setTimeout(int time)
Image getImage()
void setImage(Image img)
Roggo Jean-Christophe
Permet de lire et de modifier la durée pendant laquelle
l’alerte est affichée (en millisecondes).
Permet de lire et de modifier l’image associée à
l’alerte.
La constante FOREVER définie dans la classe Alert permet de spécifier que
l’alerte doit rester affichée tant que l’utilisateur n’a pas confirmé. L’instruction se
présentera de la manière suivante :
myAlert.setTimeout(Alert.FOREVER) ;
La classe AlertType permet de donner une indication sur la nature de l’alerte.
Elle comprend les constantes présentées dans le tableau ci-dessous.
Méthode
Description
ALARM
CONFIRMATION
ERROR
INFO
WARNING
Permet
Permet
Permet
Permet
Permet
de
de
de
de
de
spécifier
spécifier
spécifier
spécifier
spécifier
une
une
une
une
une
alerte
alerte
alerte
alerte
alerte
de
de
de
de
de
type
type
type
type
type
alarme.
confirmation.
erreur.
information.
avertissement.
L’instruction ci-dessous permet de créer une alerte de type information (aucune
image n’est associée à cette alerte).
myAlert = new Alert(“Alerte INFO”, “***information***“, null,
AlertType.INFO);
A chaque type d’alerte est associé un son. La classe AlertType propose une
méthode permettant d’utiliser ce son. L’instruction ci-dessous émet le son
associé au type d’alerte INFO.
AlertType.INFO.playSound(myDisplay) ;
[DEL02][API]
Ci-dessous vous trouverez une illustration du composant Alert mis en œuvre
dans l’application testGUI (cf annexe n° 1).
- 43 -
Travail de diplôme
Roggo Jean-Christophe
3.2.3.13. La classe Ticker
La classe Ticker modélise un texte défilant continuellement sur l’affichage. Le
composant Ticker peut être associé à toutes les classes héritant de la classe
Displayable. Ces méthodes sont recensées dans le tableau ci-dessous
[DEL02][API].
Méthode
Description
Ticker(String str)
String getString()
void setString(String str)
Constructeur permettant de spécifier le contenu
textuel du ticker.
Permet de lire et de modifier le contenu textuel du
ticker.
3.2.4. La gestion des évènements
La gestion des évènements au sein de l’interface utilisateur de haut niveau
proposée par MIDP repose sur le principe de Source – Listener. L’API d’interface
utilisateur de haut niveau comprend les classes et interfaces suivantes pour la
gestion des évènements :
ƒ
ƒ
ƒ
Command
CommandListener
ItemStateListener
3.2.4.1. La classe Command
La classe Command intègre des informations sémantiques sur une action. Cette
classe permet de gérer la navigation parmi les écrans. Elle ne contient que le
libellé de l’action, et non l’action elle-même. Cette action, déclenchée lors de
l’activation de la commande se trouve dans l’objet implémentant l’interface
CommandListener (cf 3.2.4.2) associé à l’écran. Une commande peut être
associée à n’importe quel composant dérivant de la classe Displayable (cf
3.2.2.2). Le tableau ci-dessous répertorie les méthodes de la classe Command.
Méthode
Description
Command(String label, int commandType, int
priority)
int getCommandType()
String getLabel()
int getPriority()
Constructeur permettant de spécifier le libellé, le type
et le niveau de priorité de la commande.
Permet de lire le type de la commande.
Permet de lire le libellé de la commande.
Permet de lire le niveau de priorité.
Une commande est caractérisée par un type. Le type permet de spécifier à quelle
touche du terminal la commande va être associée. Par exemple, si sur un
terminal, une commande d’annulation est habituellement associée à une touche
spécifique, lorsqu’on utilise le type CANCEL pour une commande, celle-ci sera
associée à cette même touche spécifique du terminal. Chacun des champs
présentés dans le tableau ci-dessous correspond à un type.
- 44 -
Travail de diplôme
Roggo Jean-Christophe
Champ
Description
BACK
CANCEL
EXIT
HELP
ITEM
OK
SCREEN
STOP
Type
Type
Type
Type
Type
Type
Type
Type
de
de
de
de
de
de
de
de
commande
commande
commande
commande
commande
commande
commande
commande
retour.
annulation.
quitter.
aide.
item.
confirmation.
écran.
arrêter.
Une commande est également caractérisée par un niveau de priorité. Cette
caractéristique permet de définir un niveau de priorité pour l’affichage des
commandes sur l’écran du terminal. La priorité est définie par l’intermédiaire
d’un entier, la plus haute priorité étant spécifiée par l’entier le plus petit. Le
terminal organise la disposition des commandes d’abord en fonction du type de
commande choisi, puis prend en compte les niveaux de priorité spécifiés.
[DEL02][API]
3.2.4.2. L’interface commandListener
Cette interface définit le listener associé à un objet affichable (cf 3.2.2.2). Tout
listener associé à un objet dérivant de la classe Displayable doit implémenter la
méthode
commandAction(Command
c,
Displayable
d).
C’est
dans
l’implémentation de cette méthode que l’on spécifiera l’action à entreprendre en
fonction de la commande actionnée. L’échantillon de code ci-dessous tiré du
MIDlet testGUI donne un exemple d’implémentation de cette méthode (cf
annexe n° 1).
public void commandAction (Command cmdSelected, Displayable d) {
if (cmdSelected == cmdSortie) {
destroyApp (false);
} else if (cmdSelected == cmdRetour) {
mainMenu();
}
else {
List l = (List) display.getCurrent();
switch (l.getSelectedIndex()) {
case 0:
testTextBox();
break;
case 1:
testAlert();
break;
case 2:
testForm();
break;
}
}
}
- 45 -
Travail de diplôme
Roggo Jean-Christophe
Les méthodes héritées de la classe Displayable par tous les composants
affichables permettent d’ajouter des commandes et de mettre en place le listener
(cf 3.2.2.2).
[DEL02][API]
3.2.4.3. L’interface ItemStateListener
Cette interface définit le listener associé à un formulaire et à ces éléments (cf
3.2.3.4). Ce listener permettra de gérer les évènements intervenant sur les
composants dérivant de la classe Item (cf 3.2.3.3). Tout listener de ce type doit
obligatoirement implémenter la méthode itemStateChanged(Item item). Cette
méthode est appelée lorsque l’état interne d’un composant Item a été modifié
par l’utilisateur. Voici les différents cas possibles :
ƒ
L’utilisateur modifie la valeur d’un composant Gauge (en mode
interactif).
ƒ
L’utilisateur modifie le contenu textuel d’un composant TextField.
ƒ
L’utilisateur change de sélection dans un composant ChoiceGroup.
ƒ
L’utilisateur modifie la date ou l’heure dans un composant DateField.
La méthode itemStateChanged(Item item) n’est appelée que lorsque
l’utilisateur effectue une modification interactive de l’état interne d’un composant
Item. Dans le cas où on modifie le contenu textuel d’un composant TextField
(cf 3.2.3.6) via la méthode setString(String
text), la méthode
itemStateChanged(Item item) du listener n’est donc pas appelée.
Pour mettre en place un listener sur un formulaire, on utilisera la méthode
setItemStateListener(ItemStateListener iListener) de la classe Form (cf
3.2.3.4).
[DEL02][API]
- 46 -
Travail de diplôme
Roggo Jean-Christophe
3.3. Le stockage persistant des données
Le stockage persistant des données consiste à stocker l’état des objets d’une
application dans un emplacement non volatile de telle manière à ce que ces
données soient conservées au delà de l’exécution de l’application. La section
suivante traite du mécanisme de stockage persistant des données fourni par le
profil MIDP : le RMS (Record Management System).
3.3.1. Le package RMS
Le package javax.microedition.rms contient les classes et interfaces
permettant de gérer le stockage persistant des données. Les tableaux ci-dessous
décrivent brièvement chacune de ces classes et interfaces.
Classe
Description
RecordStore
InvalidRecorIDException
Implémente un RecordStore
Exception déclenchée lorsque le recordID est invalide.
Exception déclenchée lorsqu’une exception générale
est survenue lors d’une opération sur un RecordStore.
Exception déclenchée lorsque le système de fichier du
RecordStore est plein.
Exception déclenchée lorsque le RecordStore spécifié
est introuvable.
Exception déclenchée lorsqu’une opération est tentée
sur un RecordStore fermé.
RecordStoreException
RecordStoreFullException
RecordStoreNotFoundException
RecordStoreNotOpenException
Interface
Description
RecordComparator
RecordEnumeration
RecordFilter
RecordListener
Définit
Définit
Définit
Définit
un comparateur d’enregistrements.
une énumération d’enregistrements.
un filtre d’enregistrements.
un listener associé à un RecordStore.
[DEL02][API]
3.3.2. Le Record Store
Un Record Store comprend un ensemble d’enregistrements. Il peut être comparé
à une table d’une base de donnée relationnelle. Chaque enregistrement d’un
Record Store est désigné par un identifiant. On parle alors d’ID d’enregistrement
(recordID). Cet ID d’enregistrement, un nombre entier, correspond à la clé
primaire des enregistrements. Cette valeur vaut 1 pour le premier
enregistrement du Record Store et sera incrémentée de 1 à chaque nouvel
enregistrement.
Le nom d’un Record Store est sensible à la casse et est limité à 32 caractères. Un
MIDlet ne peut pas créer deux Record Store de même nom dans une même
application. Deux Record Store peuvent en revanche avoir le même nom si ils
sont utilisés dans des applications distinctes.
Afin d’éviter toute corruption des données due à des accès concurrents, les
opérations de lecture ou d’écriture verrouillent le Record Store jusqu’à ce qu’elles
soient terminées. Cependant, dans le cas où plusieurs threads accèdent à un
Record Store, il est à la charge du développeur de synchroniser ces accès. En
- 47 -
Travail de diplôme
Roggo Jean-Christophe
effet, si deux threads différents veulent modifier un enregistrement du Record
Store au même moment, les opérations sont sérialisées correctement par le
RMS, mais au final, l’une des écritures écrasera l’autre ce qui risque de causer
des problèmes au sein du MIDlet.
L’espace disponible pour le stockage persistant diffère d’un terminal à l’autre.
Pour les téléphones mobiles compatibles MIDP existants sur le marché à l’heure
actuelle, l’espace de stockage disponible pour l’ensemble des applications
installées ne dépasse que rarement les 500 Ko. Pour le Sony Ericsson t610, par
exemple, chaque application dispose d’un espace de stockage d’environ 30 Ko et
le total de mémoire de stockage disponible pour les Record Store de toutes les
applications installées est d’environ 500 Ko (cf 4.2.1).
3.3.2.1. La classe RecordStore
Cette classe modélise un Record Store. Ces méthodes permettent d’effectuer les
opérations de base comme l’ouverture, la fermeture, la création, la modification
ou la suppression du Record Store. Le tableau ci-dessous décrit l’ensemble de
ces méthodes.
Méthode
Description
Méthode statique permettant d’ouvrir un Record Store
(si le paramètre createIfNecessary est vrai, le Record
Store est créé s’il n’existe pas déjà).
Permet de fermer un Record Store.
static RecordStore openRecordStore(String
recordStoreName, boolean createIfNecessary)
void closeRecordStore()
static void deleteRecordStore(String
recordStoreName
String getName()
static String[] listRecordStores()
RecordEnumeration
enumarateRecords(RecordFilter filter,
RecordComparator comparator, boolean
keepUpdated)
Permet de supprimer un Record Store.
Retourne le nom du Record Store.
Retourne la liste des Record Store du MIDlet.
Retourne une énumération des enregistrements selon
le filtre et l’ordre de tri spécifié.
int addRecord(byte[] data, int offset, int
numBytes)
void setRecord(int recordId, byte[] newData,
int offset, int numBytes)
byte[] getRecord(int recordId)
int getRecord(int recordId, byte[] buffer, int
offset)
void deleteRecord(int recordId)
int getNextRecordID()
int getNumRecords()
void setRecordListener(RecordListener
listener)
void removeRecordListener(RecordListener
listener)
int getRecordSize(int recordId)
int getSize()
int getSizeAvailable()
long getLastModified()
int getVersion()
Permet d’ajouter un enregistrement dans un Record
Store à partir d’un tableau d’octets. Une fois
l’enregistrement ajouté, son ID est retourné.
Permet de modifier l’enregistrement spécifié par le
paramètre recordId.
Retourne, sous forme de tableau d’octets, une copie
de l’enregistrement spécifié par le paramètre recordId.
Permet d’obtenir les données contenues dans
l’enregistrement spécifié (la méthode retourne le
nombre d’octets copiés dans buffer).
Permet de supprimer l’enregistrement spécifié.
Retourne l’identifiant du prochain enregistrement qui
sera ajouté au Record Store.
Retourne le nombre d’enregistrements contenus dans
le Record Store.
Permet de mettre en place et de supprimer le listener
associé au Record Store.
Retourne la taille en octets de l’enregistrement.
Retourne la taille totale en octets du Record Store.
Retourne l’espace de stockage courant disponible pour
le Record Store (en octets).
Retourne l’heure de la dernière modification du Record
Store selon le format spécifié par
System.currentTimeMillis().
Retourne le numéro de version du Record Store (à
chaque fois qu’un Record Store est modifié son
numéro de version est automatiquement incrémenté).
- 48 -
Travail de diplôme
Roggo Jean-Christophe
Pour créer des Record Store multi-colonnes, le développeur devra inclure des
séparateurs au sein de l’enregistrement et implémenter le parser adéquat pour
récupérer les différentes informations correctement.
En utilisant plusieurs Record Store le développeur pourra implémenter un
semblant de base de données relationnelle.
[DEL02][API]
3.3.2.2. L’interface RecordComparator
Cette interface définit un comparateur d’enregistrements. On implémentera
volontiers l’interface RecordComparator pour effectuer un tri sur les
enregistrements d’un Record Store. La méthode suivante devra être
implémentée :
int compare(byte[] rec1, byte[] rec2)
Outre cette méthode, l’interface définit également les trois constantes décrites
dans le tableau ci-dessous.
Champ
Description
Constante retournée par la méthode de comparaison
lorsque le résultat de la comparaison est : rec1 > rec2
(la valeur de la constante est 1).
Constante retournée par la méthode de comparaison
lorsque le résultat de la comparaison est : rec1 < rec2
(la valeur de la constante est –1).
Constante retournée par la méthode de comparaison
lorsque le résultat de la comparaison est : rec1 = rec2
(la valeur de la constante est 0).
FOLLOWS
PRECEDES
EQUIVALENT
[DEL02][API]
3.3.2.3. L’interface RecordFilter
Cette interface définit un outil de filtrage des enregistrements. On implémentera
cette interface pour filtrer les enregistrements en fonction du critère choisi. La
méthode suivante devra être implémentée :
boolean matches(byte[] candidate)
[DEL02][API]
3.3.2.4. L’interface RecordEnumeration
Cette interface définit une énumération d’enregistrements bidirectionnelle. On
l’utilisera volontiers pour extraire les enregistrements d’un Record Store selon un
- 49 -
Travail de diplôme
Roggo Jean-Christophe
ordre différent que leur ordre d’insertion. Ses méthodes sont décrites dans le
tableau ci-dessous.
Méthode
Description
int previousRecordId()
int nextRecordId()
boolean hasPreviousElement()
boolean hasNextElement()
byte[] previousRecord()
byte[] nextRecord()
int numRecords()
Permet de retourner l’ID de l’enregistrement précédent
et de l’enregistrement suivant.
Permet de savoir si il existe un enregistrement
précédent et un enregistrement suivant.
Retourne l’enregistrement précédent et
l’enregistrement suivant.
Retourne le nombre d’enregistrements.
Permet d’indiquer si l’énumération des
enregistrements doit être actualisée pour refléter les
modifications sur les enregistrements.
Retourne vrai si l’énumération est actualisée
automatiquement lors de modifications sur les
enregistrements.
Permet d’actualiser manuellement l’énumération.
Permet de libérer les ressources utilisées par
l’énumération d’enregistrements.
Permet de mettre l’énumération dans l’état où elle
était au moment de sa création.
void keepUpdated(boolean keepUpdated)
boolean isKeptUpdated()
void rebuild()
void destroy()
void reset()
[DEL02][API]
3.3.2.5. L’interface RecordListener
L’interface RecordListener définit le listener associé à un composant
RecordStore. Ce listener permet la supervision des modifications des
enregistrements qui consiste à être averti lorsqu’un ajout, une modification ou
une
suppression
sont
effectués
sur
un
enregistrement.
L’interface
RecordListener définit les trois méthodes décrites dans le tableau ci-dessous
correpondant chacune à un événement.
Méthode
Description
void recordAdded(RecordStore recordStore, int
recordId)
void recordChanged(RecordStore recordStore,
int recordId)
void recordDeleted(RecordStore recordStore,
int recordId)
Méthode exécutée lorsqu’un enregistrement est ajouté
au Record Store.
Méthode exécutée lorsqu’un enregistrement du Record
Store est modifié.
Méthode exécutée lorsqu’un enregistrement du Record
Store est supprimé.
[DEL02][API]
Vous trouverez dans l’annexe n°2 un exemple de mise en œuvre des composants
de RMS.
- 50 -
Travail de diplôme
Roggo Jean-Christophe
Cette quatrième partie débute par une brève présentation des différents outils
que j’ai utilisés lors de mes tests. L’étude d’un MIDlet permettant de convertir
des devises en utilisant un Web Service sera ensuite abordée.
4. J2ME en pratique
4.1. Les outils
Comme nous l’avions exposé dans la troisième partie de ce dossier, le cycle de
développement d’un MIDlet est constitué de cinq étapes chacune nécessitant
l’utilisation d’outil(s). Le tableau ci-dessous indique quels outils j’ai choisis pour
réaliser chacune de ces étapes dans mes développements :
Etape
Ecriture de l’application avec les API de MIDP.
Compilation et prévérification de l’application.
Test de l’application avec un émulateur
Packaging de l’application.
Outil(s)
L’environnement de développement J2ME
Wireless Toolkit 2.1 et l’éditeur de texte Edit+
L’environnement de développement J2ME
Wireless Toolkit 2.1
L’environnement de développement J2ME
Wireless Toolkit 2.1
L’environnement de développement J2ME
Wireless Toolkit 2.1
Clé USB Bluetooth MITSUMI BLUETOOTH USB
Test de l’application packagée sur le terminal
ADAPTATOR et téléphone mobile Sony Erisson
mobile.
t610
4.1.1. L’environnement de développement
Mon choix s’est arrêté sur le J2ME Wireless Toolkit pour des raisons pratiques
avant tout. En effet, l’environnement de Sun Microsystem est téléchargeable
gratuitement et s’avère simple et efficace. Beaucoup d’autres environnements de
développement J2ME existent sur le marché, souvent proposés sous forme de
plug-in. Vous trouverez quelques références dans le tableau ci-dessous.
Environnement
Description
MobileSet Plug-In
Plug-In pour Borland JBuilder
Visual Age Micro Edition
Plug-In pour IBM WebSphere Studio
Visual Age Micro Edition
Plug-In pour l’IDE d’Oracle, JDevelopper
EclipseMe Plug-In
Plug-In pour l’environnement open source
Eclipse
Pour plus de détails sur ces environnements consultez l’adresse suivante :
http://www.microjava.com/articles/techtalk/ide
- 51 -
Travail de diplôme
Roggo Jean-Christophe
4.1.1.1. J2ME Wireless Toolkit 2.1
L’installation du J2ME Wireless Toolkit est une formalité (les fichiers d’installation
sont disponibles sur le cd rom fourni en annexe). Une fois l’environnement
installé, le menu de la figure ci-dessous est disponible.
La première rubrique vous permet de sélectionner un émulateur par défaut. La
seconde rubrique vous donne accès à la documentation de l’environnement ainsi
qu’à celle des API (Application Program Interface). La rubrique suivante permet
de lancer la console pour créer et gérer des projets. La quatrième rubrique lance
un outil d’assistance au transfert de fichier sur le terminal cible via une
connexion OTA (Over The Air). La rubrique suivante vous permet de configurer
les émulateurs. La sixième rubrique permet d’exécuter une application J2ME
dans l’émulateur (les fichiers exécutables par l’émulateur sont les fichiers *.jad).
La dernière rubrique quant à elle donne accès à un utilitaire de configuration.
La console du J2ME Wireless Toolkit (Ktoolbar) est illustrée ci-dessous.
- 52 -
Travail de diplôme
Roggo Jean-Christophe
La console est le cœur de l’environnement de développement. Elle est utilisée
pour créer, gérer, compiler et packager les projets. En sélectionnant la rubrique
Settings de la console vous pourrez, entre autres, définir la configuration et le
profil J2ME, comme l’illustre l’image ci-dessous.
Lorsqu’un projet est créé, un dossier portant le nom du projet est ajouté dans le
répertoire apps situé à la racine du dossier d’installation. Le dossier de projet
contient les quatre répertoires décrits dans le tableau ci-dessous.
Dossier
Description
%WTK21/apps/nom_projet/bin
Contient le fichier *.jar, *.jad et le fichier
manifest (cf 3.1.2)
%WTK21/apps/nom_projet/classes
Contient les classes compilées
%WTK21/apps/nom_projet/lib
Contient les bibliothèques utiles à l’application
%WTK21/apps/nom_projet/res
Contient les ressources utiles à l’application (des
images au format *.png par exemple)
%WTK21/apps/nom_projet/src
Contient les sources des classes
- 53 -
Travail de diplôme
Roggo Jean-Christophe
Le J2ME Wireless Toolkit ne propose pas d’éditeur de texte pour écrire le code
source des applications. Le développeur utilisera son éditeur de texte préféré
pour écrire les fichiers sources puis ajoutera ces derniers au répertoire src du
projet.
La rubrique Create Package du menu illustré ci-dessous permet de générer le
fichier *.jar destiné au terminal mobile cible et le fichier *.jad destiné à
l’émulateur.
Pour tester les applications fournies sur le cd rom annexé à ce dossier dans
l’émulateur du J2ME Wireless Toolkit, il suffit d’effectuer les étapes suivantes :
ƒ
Installer le J2ME Wireless Toolkit 2.1
ƒ
Coller les répertoires correspondant à chaque projet dans le dossier
app situé à la racine du répertoire d’installation
ƒ
Lancer la console KToolbar
ƒ
Ouvrir le projet de votre choix
ƒ
Sélectionner le bouton Run de la console KToolbar
Pour obtenir des informations plus détaillées sur l’utilisation du J2ME Wireless
Toolkit 2.1, veuillez vous référer à la documentation fournie avec l’outil.
- 54 -
Travail de diplôme
Roggo Jean-Christophe
4.1.2. Le terminal mobile cible
Toutes les applications fournies sur le cd rom en annexe ont été testées et
s’exécutent correctement sur le téléphone mobile Sony Ericsson t610. Dans le
cas ou vous voudriez tester ces applications sur un autre terminal, veuillez
consulter l’adresse suivante qui vous donnera des informations quant à la
compatibilité du terminal avec la technologie J2ME :
http://jal.sun.com/webapps/device/device
Toutes les applications proposées sur le cd rom annexé sont destinées à des
terminaux mobiles J2ME compatibles avec la configuration CLDC 1.0 et le profil
MIDP 1.0. Le terminal cible sur lequel ces applications seront testées devra donc
obligatoirement implémenter cette configuration et ce profil (ou les versions
ultérieures, à savoir CLDC 1.1 et MIDP 2.0).
4.1.2.1. Le terminal mobile Sony Ericsson t610
Réseaux
900/1800/1900 GPRS
Résolution de l’affichage
Nb couleurs
128 x 160
65536
Java
CLDC 1.0/MIDP 1.0/MMAPI
Micronavigateur
WAP 2.0 (WML, xHTML)
Messagerie
SMS/EMS/MMS
Connectivité
Bluetooth/Infrarouge/SyncML
Mémoire
~2 MB
[SEW]
Comme spécifié dans le tableau ci-dessus, le t610 implémente la configuration
CLDC 1.0, le profil MIDP 1.0 et le package optionnel MMAPI. Le tableau suivant
donne des informations détaillées concernant la mémoire disponible pour
l’exécution des applications J2ME.
Mémoire de stockage RMS totale
500 KB
Mémoire de stockage RMS par application
Taille du heap Java
30 KB
256 KB
Taille du heap natif utilisé pour les
composants GUI
~150 KB
RAM vidéo native disponible pour Java
~80 KB
[SEJ]
- 55 -
Travail de diplôme
Roggo Jean-Christophe
Pour obtenir plus d’informations concernant ce terminal mobile, vous êtes invités
à consulter les documents suivants que vous trouverez sur le cd rom fourni en
annexe :
ƒ
wp_t610_r2a.pdf
ƒ
dg_j2me_midp1_r3a.pdf
Sony Ericsson propose un site offrant toutes les informations nécessaires au
développement d’applications J2ME pour les différents modèles de la marque
(exemples d’applications, forum …). L’adresse suivante vous permettra
d’accéder à ces informations gratuitement :
http://developer.sonyericsson.com/site/global/home/p_home.jsp
Notons également que Sony Ericsson distribue gratuitement sa propre version de
l’environnement J2ME Wireless Toolkit accompagnées d’émulateurs configurés de
telle manière à recréer l’apparence et le comportement de ses différents modèles
de téléphones. Les fichiers nécessaires à l’installation de l’environnement
SonyEricsson J2ME SDK 2.1.4 beta sont disponibles sur le cd rom annexé.
Remarque : sur le terminal mobile t610 en particulier, pour qu’un MIDlet
utilisant un composant de connexion HttpConnection s’exécute correctement, il
est nécessaire de configurer un nouveau profil d’accès Internet général. Si le
profil WAP par défaut est utilisé, le MIDlet ne pourra pas ouvrir de connexion
HTTP. Pour configurer un nouveau profil d’accès Internet général, consultez la
documentation du téléphone et renseignez vous auprès de votre opérateur
téléphonique.
4.1.3. L’outil de transfert de l’application
Une fois l’application packagée grâce à l’environnement de développement (cf
4.1.1), elle peut être installée sur le terminal cible. Le transfert de l’application
packagée depuis la station de développement vers le terminal cible peut être
effectué de différentes manières. Soit le fichier *.jar est stocké sur un serveur et
le terminal cible le télécharge via un navigateur WAP, soit le fichier est transféré
grâce à une connexion directe entre la station de développement et le terminal
cible.
La première solution nécessite que le terminal soit muni d’un navigateur WAP, ce
qui est le cas de la plupart des téléphones mobiles compatibles CLDC 1.0 et MIDP
1.0. On utilisera donc volontiers cette solution pour distribuer des MIDlets à
grande échelle.
La seconde solution nécessite le concours d’un service de transfert de fichiers via
une connexion par câble ou une connexion OTA (Over The Air). Tous les MIDlet
disponibles sur le cd rom annexé ont été transférés via Bluetooth pour être
testés sur le terminal cible. Le service de transfert de fichier OBEX (Object
Exchange) supporté par le terminal cible Sony Ericsson t610 (cf 4.2.1) et la clé
USB (Universal Serial Bus) Bluetooth du fabricant MITSUMI installée sur la
station de développement ont permis de mettre en œuvre la connexion OTA.
- 56 -
Travail de diplôme
Roggo Jean-Christophe
4.2. L’application CurrencyConverter
Sur le cd rom fourni en annexe, vous trouverez l’application CurrencyConverter.
Pour pouvoir exécuter cette application dans l’émulateur du J2ME Wireless
Toolkit, référez vous au point 4.1.1.1 de la présente étude. Ce prototype
d’application, destiné à la configuration CLDC 1.0 et au profil MIDP 1.0, permet
de convertir des devises par l’intermédiaire d’un serveur PHP (Personal Home
Page). Dans ce cas précis, l’application J2ME s’exécutant sur le terminal mobile
s’apparente à un client léger (cf Gartner Model). En effet, le MIDlet
CurrencyConverter envoie une requête HTTP GET à un serveur PHP qui se
chargera d’effectuer un appel SOAP (Simple Objetc Access Protocol) RPC
(Remote Procedure Call) sur un autre serveur pour obtenir un service. Une fois le
service rendu, le serveur PHP effectue un calcul, puis renvoie le résultat à
l’application J2ME. Le schéma ci-dessous illustre cette architecture distribuée.
SOAP RPC
Serveur PHP
Serveur de Web Services
HTTP GET
Client
J2ME
- 57 -
Travail de diplôme
Roggo Jean-Christophe
L’avantage de cette architecture est que le terminal mobile profite des ressources
de deux parties tierces. En effet, aucun calcul n’est effectué sur le terminal. Le
désavantage principal réside dans le fait que le bon fonctionnement de
l’application dépend en grande partie des deux serveurs impliqués. Si un de ces
serveurs tombe en panne, aucune conversion ne pourra être effectuée. Pour
résoudre ce problème, on pourrait stocker un jeu limité d’information sur le
terminal client (cf 3.3) de telle sorte à pouvoir, si nécessaire, exécuter
l’application de manière totalement autonome.
Une autre solution consisterait à éliminer une de ces tierces parties en utilisant le
package kSOAP, librairie permettant l’invocation de Web Service au sein d’une
application J2ME. Pour obtenir plus d’informations concernant ce package et son
utilisation veuillez vous référer aux adresses suivantes :
http://ksoap.objectweb.org/
http://www.sys-con.com/story/?storyid=37193&DE=1
http://webservices.xml.com/lpt/a/ws/2003/08/19/ksoap.html
http://www.capescience.com/articles/wireless/index.shtml
http://www.javaworld.com/javaworld/jw-08-2002/jw-0823-wireless.html
http://wirelessadvisor.net/doc/12697
Il faut toutefois être conscient du fait que l’utilisation d’un tel package augmente
considérablement la taille du fichier *.jar à destination du terminal mobile. Avec
l’architecture actuelle, l’application CurrencyConverter, une fois packagée,
occupe un espace mémoire d’environ 5 ko. Si le package kSOAP avait été utilisé,
la taille de l’application packagée aurait atteint environ 50 Ko.
4.2.1. Le client J2ME
Le code source du client J2ME est disponible dans le répertoire du projet
CurrencyConverter fourni sur le cd rom annexé. Ce prototype comporte deux
classes, l’une responsable de la gestion de l’interface utilisateur (cf
Converter.java) et l’autre responsable de l’interaction réseau avec le serveur
PHP (cf NetworkInteraction.java).
La classe responsable de l’interaction réseau implémente l’interface Runnable
[API], ce qui permet de mettre en œuvre la connexion réseau dans un autre
thread (processus) que celui où est géré l’interface utilisateur. Si ces deux
mécanismes étaient implantés dans le même thread, l’exécution de l’application
pourrait aboutir à un dead-lock (verrou mortel).
La classe responsable de la gestion de l’interface graphique utilise plusieurs
composants GUI haut niveau de MIDP pour permettre à l’utilisateur de saisir les
différentes informations de conversion.
- 58 -
Travail de diplôme
Roggo Jean-Christophe
Ci-dessous
vous
trouverez
quelques
illustrations
de
l’application
CurrencyConverter exécutée sur l’émulateur du J2ME Wireless Toolkit.
Fig. 1 Le champ de texte
et la liste de monnaies
source
Fig. 2 La liste des
monnaies de destination
Fig. 3 L’écran de sécurité
Fig. 4 Le message
témoignant du succès de
l’interaction
Fig. 5 Le résultat de la
conversion
Fig. 6 Le message
d’erreur témoignant d’un
refus d’accès
Lorsque l’application démarre, l’écran de saisie de la Fig. 1 s’affiche. Cet écran
permet à l’utilisateur de saisir la valeur à convertir dans un champ de texte
n’acceptant que des nombres entiers (une contrainte de saisie est spécifiée à
l’instanciation de la classe TextField cf 3.2.3.6). Les deux liste de choix invitent
l’utilisateur à sélectionner une devise source et une devise de destination (Fig. 1
et Fig. 2). Une fois la commande Convertir activée par l’utilisateur, l’écran de
sécurité de la Fig. 3 s’affiche. Le message témoignant du succès de l’interaction
s’affiche quelques secondes après l’acceptation de l’utilisateur (Fig. 4). Une fois
que l’utilisateur a confirmé, le résultat de la conversion s’affiche enfin (Fig. 5). Si
l’utilisateur refuse que l’application utilise le réseau (Fig. 3), l’écran de la Fig. 6
s’affiche. Le refus de l’utilisateur est valable pour toute la durée d’exécution de
l’application. Pour effectuer une conversion, il faudra donc quitter l’application,
puis la relancer.
- 59 -
Travail de diplôme
Roggo Jean-Christophe
L’application CurrencyConverter n’effectue aucun calcul pour réaliser la
conversion, cette tâche est assurée par le serveur PHP avec lequel elle
communique.
4.2.2. Le serveur PHP
Le code source du script PHP exécuté sur le serveur est disponible sur le cd rom
fourni en annexe. La librairie nuSOAP est utilisée pour effectuer l’appel au Web
Service. Une fois le taux de la devise retourné, le serveur PHP convertit la valeur
que le client J2ME lui a fournie, puis, lui renvoie le résultat.
L’appel de Web Service depuis un script PHP n’est pas directement l’objet de la
présente étude. Pour obtenir plus d’informations sur ce sujet, vous pouvez
consulter l’adresse suivante :
http://csproject.it.bton.ac.uk/sdh1/swm35/postcourse/2.php
4.2.3. Le Web service
Le Web Service invoqué depuis le serveur PHP est fourni par XMETHODS. Il
retourne le taux de conversion d’une devise par rapport à une autre. Toutes les
informations nécessaires concernant le Web Service Currency Exchange Rate
sont disponibles à l’adresse suivante :
http://www.xmethods.com/ve2/ViewListing.po;jsessionid=9Oq5HRbo5fbf8Xwns4SKOn3(QHyMHiRM)?key=uuid:D784C184-99B2-DA25-ED453665D11A12E5
Remarque : étant donné que l’architecture de ce prototype implique deux
serveurs tiers, il n’est pas garantit que vous puissiez tester ce prototype à tout
moment. En effet, le serveur de Web Service est normalement fiable mais il se
peut qu’il ne réponde pas si il est surchargé (le prototype ne gère pas ce cas de
figure). D’autre part, le serveur PHP n’est pas en activité 24h/24h.
- 60 -
Travail de diplôme
Roggo Jean-Christophe
5. Conclusion
L’explosion du marché des terminaux mobiles et la popularité du langage Java
justifient que les développeurs s’intéressent à une technologie comme J2ME. Par
ailleurs, l’architecture modulaire caractérisant la technologie de Sun
Microsystems est parfaitement adaptée aux différents types de terminaux
mobiles et à leur évolution technologique perpétuelle. J2ME, comme les autres
technologies Java, comporte l’avantage notoire de la portabilité (Write Once And
Run Everywhere). Une même application peut être exécutée sur un téléphone
portable ou sur un PDA PocketPC (des tests de dernière minute qui n’ont
malheureusement pas pu être intégrés à la présente étude me permettent de le
confirmer). La portabilité des applications J2ME est un argument de force face à
des technologies concurrentes comme celle de Microsoft (Microsoft Embedded
Architecture), qui se concentre sur un unique environnement mobile, Windows
CE. D’autre part, la collaboration intensive de Sun Microsystem avec des
fabricants de terminaux mobiles tels que Motorola, Nokia, Sony Ericsson ou
Siemens facilite l’évolution de la technologie en fonction des terminaux cibles.
Notons également que Sun propose des outils simples et efficaces pour assurer
le cycle de développement d’une application. Les émulateurs proposés facilitent
les tests, mais il est toutefois conseillé de tester les applications sur le terminal
cible pour se faire une idée exacte du résultat.
Les terminaux mobiles disposent de ressources limitées. Les limitations se
rapportant à la puissance de calcul ou à l’espace de stockage peuvent être
contournées grâce à une architecture distrbuée (utilisation de Web Services,
stockage de données sur un serveur …). Seules les contraintes d’affichage
limitent réellement les possibilités de développement.
- 61 -
Travail de diplôme
Roggo Jean-Christophe
Bibliographie
Livre
[DEL02] :
Bruno Delb
J2ME Applications Java pour terminaux mobiles
EYROLLES 2002
ISBN 2-212-11084-7
Sites
[WJS04] :
Wireless Java Sun Microsystem
http://wireless.java.sun.com/
[JSU04] :
Java Sun J2ME
http://java.sun.com/j2me/
[DSU04] :
Introduction Mobility Java Technology
http://developers.sun.com/techtopics/mobility/getstart/
Articles
[JNE04] :
Le Journal du Net
Le marché des terminaux mobile s’envole
06/2004
http://www.journaldunet.com/0406/040602nokia.shtml
[MVE02] :
Electronique
Les machines Java pour l’embarqué
06/2002
http://www.electronique.biz/Pdf/ELM200206010126100.pdf
Documentation
[API] :
Documentation des API J2ME
Fournie avec le J2ME Wireless Toolkit
[SEW] :
Sony Ericsson t610 White paper
Fournie sur le cd rom annexé
wp_t610_r2a.pdf
[SEJ] :
Java Support in Sony Ericsson mobiles phones
Fournie sur le cd rom annexé
dg_j2me_midp1_r3a.pdf
- 62 -
Travail de diplôme - annexe n°1
Roggo Jean-Christophe
Annexe n°1 : API d’interface utilisateur haut niveau
L’application testGUI est un exemple de mise en œuvre de la plupart des composants de
l’API d’interface utilisateur haut niveau fournie par le profil MIDP.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;
public class TestGUI extends MIDlet implements CommandListener {
// Déclaration du gestionnaire d'affichage
private Display display = null;
// Déclaration d'un composant List qui fera office de menu
private List myMenu = null;
// Déclaration d'un composant Image
private Image myImg = null;
// Déclaration d'une autre image
private Image myImgMenu1 = null;
// Déclaration d'une autre image
private Image myImgMenu2 = null;
// Déclaration d'une autre image
private Image myImgMenu3 = null;
// Déclaration d'une zone de texte statique
private StringItem myStringItem = null;
// Déclaration de la liste de choix
private ChoiceGroup myChoiceGroup = null;
// Déclaration de la zone de texte
private TextBox myTextbox = null;
// Déclaration d'un ticker
private Ticker myTicker = null;
// Déclaration de l'alerte
private Alert myAlert = null;
// Déclaration d'un composant date
private DateField myDate = null;
// Déclaration d'un composant formulaire
private Form myForm = null;
// Déclaration d'un composant jauge
private Gauge myGauge = null;
// Déclaration d'un champ de texte
private TextField myTextfield = null;
// Déclaration et création des commandes retour, menu et sortie
static final Command cmdRetour = new Command ("Retour", Command.BACK, 0);
static final Command cmdSortie = new Command ("Sortie", Command.EXIT, 1);
// Les sources des images
static final String sourceImg = "/duke.png";
static final String sourceImgMenu1 = "/redSquare.png";
static final String sourceImgMenu2 = "/greenSquare.png";
static final String sourceImgMenu3 = "/blueSquare.png";
/**
* Constructeur
**/
public TestGUI() {
// Création du menu
myMenu = new List ("Test GUI", Choice.IMPLICIT);
// Création de toutes les images
try {
myImgMenu1 = Image.createImage(sourceImgMenu1);
myImgMenu2 = Image.createImage(sourceImgMenu2);
myImgMenu3 = Image.createImage(sourceImgMenu3);
myImg = Image.createImage(sourceImg);
-1-
Travail de diplôme - annexe n°1
Roggo Jean-Christophe
}
catch (IOException e){
e.printStackTrace();
}
// Ajouts des éléments au menu
myMenu.append ("Test TextBox", myImgMenu1);
myMenu.append ("Test Alert", myImgMenu2);
myMenu.append ("Test Form", myImgMenu3);
// Ajout de la commande sortie au menu
myMenu.addCommand (cmdSortie);
// Mise en place du listener
myMenu.setCommandListener (this);
// Création du ticker
myTicker = new Ticker ("Test de l'interface graphique haut niveau.");
// Association du ticker au menu
myMenu.setTicker (myTicker);
// Création d'un composant DateField
myDate = new DateField ("La date d'ajourd'hui : ", DateField.DATE);
// Obtention de la date courante et assignation au composant DateField
java.util.Date now = new java.util.Date();
myDate.setDate (now);
// Création d'un composant jauge
myGauge = new Gauge("Jauge", true, 10, 0);
// Création d'un composant champ de texte qui sera associé à un formulaire
myTextfield = new TextField("Champ de texte", "", 50, TextField.ANY);
// Création d'une liste de choix (à choix exclusif)
myChoiceGroup = new ChoiceGroup ("Faites votre choix :", myChoiceGroup.EXCLUSIVE);
// Ajout des éléments de la liste de choix
myChoiceGroup.append ("Option 1", null);
myChoiceGroup.append ("Option 2", null);
myChoiceGroup.append ("Option 3", null);
// Création de la zone de texte statique
myStringItem = new StringItem ("Une image :", "");
// Création d'un composant formulaire
myForm = new Form ("Formulaire");
// Association du champ de texte, de la date, de la jauge, de la liste de choix,
// de la zone de texte statique et de l'image au formulaire
myForm.append (myTextfield);
myForm.append (myDate);
myForm.append (myGauge);
myForm.append(myChoiceGroup);
myForm.append (myStringItem);
myForm.append (new ImageItem(null, myImg, ImageItem.LAYOUT_CENTER, null));
// Ajout d'une commande de retour
myForm.addCommand (cmdRetour);
// Mise en place du listener
myForm.setCommandListener (this);
// Création d'une zone de texte de taille 50 avec le libellé
// "Saisissez votre texte :". La contrainte de saisie ANY est spécifiée ce qui signifie
// que l'utilisateur pourra saisir n'importe quel caractère.
myTextbox = new TextBox ("Saisir du texte :", "", 50, TextField.ANY);
// Ajout de la commande de retour au TextBox
myTextbox.addCommand (cmdRetour);
// Mise en place du listener
myTextbox.setCommandListener (this);
// Création d'une alerte de type INFO
myAlert = new Alert ("Une alerte sonore");
myAlert.setType (AlertType.INFO);
// Cette alerte reste affichée tant que l'utilisateur ne fait pas de confirmation
myAlert.setTimeout(Alert.FOREVER);
myAlert.setString ("Alerte de type INFO.");
}
-2-
Travail de diplôme - annexe n°1
Roggo Jean-Christophe
/**
* Lance le MIDlet.
**/
public void startApp() throws MIDletStateChangeException {
display = Display.getDisplay (this);
mainMenu();
}
/**
* Suspend le MIDlet
**/
public void pauseApp() {
}
/**
* Termine l'exécution du MIDlet
**/
public void destroyApp (boolean unconditional) {
notifyDestroyed();
}
/**
* Affichage du menu principal
**/
private void mainMenu() {
// Affichage du menu principal
display.setCurrent(myMenu);
}
/**
* Test du composant TextBox
**/
private void testTextBox() {
// Affichage du composant TextBox
display.setCurrent (myTextbox);
}
/**
* Test du composant Alert
**/
public void testAlert() {
// Affichage de l'alerte
display.setCurrent (myAlert);
}
/**
* Test du composant Form
**/
public void testForm() {
// Affichage du composant formulaire et de ces éléments associés
display.setCurrent (myForm);
}
-3-
Travail de diplôme - annexe n°1
Roggo Jean-Christophe
/**
* Gestion des événements
**/
public void commandAction (Command cmdSelected, Displayable d) {
// Si la commande Sortie est activée, on quitte le MIDlet.
if (cmdSelected == cmdSortie) {
destroyApp (false);
} else if (cmdSelected == cmdRetour) {
// Si la commande Retour est activée, on retourne au menu.
mainMenu();
}
else {
// Dans les autres cas, il s'agit forcément de la sélection d'un élément
// du menu. On lit la position de l'élément sélectionné dans la liste
// et on appelle la méthode correspondante.
List l = (List) display.getCurrent();
switch (l.getSelectedIndex()) {
case 0:
testTextBox();
break;
case 1:
testAlert();
break;
case 2:
testForm();
break;
}
}
}
}
Vous trouverez ci-dessous quelques illustrations de l’application testGUI exécutée sur
l’émulateur standard du J2ME Wireless Toolkit 2.1.
Fig. 1 Ecran de démarrage
de l’application testGUI
Fig. 2 Menu implémenté par
la classe List
-4-
Fig. 3 Champ de texte
implémenté par la classe TextBox
Travail de diplôme - annexe n°1
Fig. 4 Alerte de type INFO
implémentée par la classe
Alert
Roggo Jean-Christophe
Fig. 5 Formulaire avec des
composants TextField,
DateField, Gauge …
Fig. 6 Suite du formulaire
avec les composants
ChoiceGroup et Image
Fig. 5 Ecran de saisie de la
date du composant DateField
Une fois l’application lancée le menu illustré à la Fig. 2 s’affiche. Si l’utilisateur choisi Test
TextBox le champ de texte illustré à la Fig. 3 s’affiche. La commande Retour permet de
revenir au menu. Lorsque l’utilisateur choisit Test Alert, l’alerte illustrée à la Fig. 4 s’affiche.
Une fois que l’utilisateur a confirmé, le menu s’affiche à nouveau. Si l’utilisateur choisit Test
Form le formulaire et ses composants associés illustrés à la Fig. 5 et Fig. 6 s’affichent.
Lorsque l’utilisateur veut saisir une nouvelle date dans le champ de date l’écran de la Fig. 5
s’affiche.
-5-
Travail de diplôme - annexe n°2
Roggo Jean-Christophe
Annexe n°2 : Mise en œuvre de RMS
L’application testRecordStore est un exemple de mise en œuvre du RMS (Record
Management System). Son code source est présenté dans l’encadré ci-dessous.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
// Le MIDlet implémente les interfaces CommandListener et RecordListener
public class TestRec extends MIDlet implements CommandListener, RecordListener {
// Déclaration de la commande de sortie
private Command cmdExit;
// Déclaration de la commande de sauvegarde
private Command save;
// Déclaration de la commande d'affichage du menu
private Command cmdMenu;
// Déclaration du gestionnaire d'affichage
private Display myDisplay;
// Déclaration du composant TextBox qui permettra la saisie de nouveaux enregistrements
private TextBox tb = null;
// Déclaration de l'enregistrement
private Rec rec = null;
// Déclaration d'un Record Store
private RecordStore myDb = null;
// Déclaration d'un composant List qui fera office de menu principal
private List menu = null;
// Déclaration d'un formulaire pour l'affichage des enregistrements
private Form myForm = null;
// Déclaration d'un formulaire pour l'affichage du nombre d'enregistrements
private Form myFormNb = null;
// Déclarations de composants StringItem qui seront associés au formulaire ci-dessus
private StringItem strNbRec = null;
private StringItem strTailleRec = null;
public TestRec () {
try
{
// Ouverture du Record Store (si il n'existe pas, il est créé)
myDb = RecordStore.openRecordStore("myDb", true);
// Mise en place d'un listener sur le Record Store
myDb.addRecordListener(this);
}
catch (RecordStoreException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible d'ouvrir le Record Store.");
myDisplay.setCurrent(errRec);
}
}
-1-
Travail de diplôme - annexe n°2
Roggo Jean-Christophe
// La classe modélisant l'enregistrement
public class Rec {
private String mot = "";
public Rec(String mot) {
this.mot = mot;
}
// Transforme la chaîne mot en tableau d'octets
public byte[] toBytes() {
return this.mot.getBytes();
}
}
// Affichage d'un composant TextBox pour la saisie d'un nouvel enregistrement
private void newRec() {
tb.setString("");
myDisplay.setCurrent(tb);
}
// Affichage du menu principal
private void mainMenu() {
myDisplay.setCurrent(menu);
// Pour émettre un son
AlertType.CONFIRMATION.playSound(myDisplay);
}
// Initialise un formulaire
private void initForm() {
myForm = new Form("Listing");
myForm.addCommand (cmdExit);
myForm.addCommand (cmdMenu);
myForm.setCommandListener (this);
}
// Initialisation des différents composants GUI au démarrage de l'application
public void startApp() {
myDisplay = Display.getDisplay (this);
cmdMenu = new Command("Menu", Command.SCREEN, 1);
cmdExit = new Command ("Sortie", Command.SCREEN, 2);
save = new Command ("Save", Command.OK, 1);
tb = new TextBox ("New Rec", "", 1024, 0);
tb.addCommand (save);
tb.addCommand (cmdExit);
tb.addCommand (cmdMenu);
tb.setCommandListener (this);
this.initForm();
myFormNb = new Form("Nb Rec");
strNbRec = new StringItem("Nombre d'enregistrements : ", "");
strTailleRec = new StringItem("Taille du Record Store : ", "");
myFormNb.append(strNbRec);
myFormNb.append(strTailleRec);
myFormNb.addCommand (cmdExit);
myFormNb.addCommand (cmdMenu);
myFormNb.setCommandListener (this);
menu = new List("Menu", Choice.IMPLICIT);
menu.append("New rec", null);
menu.append("Nb rec", null);
menu.append("All rec", null);
menu.append("Clear all", null);
menu.addCommand(cmdExit);
menu.setCommandListener(this);
// Affichage du menu principal
this.mainMenu();
}
// Exécuté lorsque l'application est suspendue
public void pauseApp() {
}
-2-
Travail de diplôme - annexe n°2
Roggo Jean-Christophe
// Exécuté lorsque l'application se termine
public void destroyApp (boolean unconditional) {
try
{
// Fermeture du Record Store
myDb.closeRecordStore();
}
catch (RecordStoreException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible de fermer le Record Store.");
myDisplay.setCurrent(errRec);
}
notifyDestroyed();
}
// Affiche l'ensemble des enregistrements
private void allRec() {
int nbRec = 0;
String str = "";
try
{
// Récupération du nombre d'enregistrements contenus dans le Record Store
nbRec = myDb.getNumRecords();
}
catch (RecordStoreException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible d'accéder au Record Store.");
myDisplay.setCurrent(errRec);
}
// Teste si il y a au moins un enregistrement dans le Record Store
if (nbRec > 0) {
// Si le formulaire contient moins d'éléments
// que le nombre d'enregistrements contenus dans le Record Store,
// c'est que la méthode allRec n'a pas encore été exécutée depuis
// le lancement de l'application. Le formulaire devra donc être
// rénitialisé. En effet, si l'utilisateur a créé des nouveaux
// enregistrements avant d'afficher l'ensemble des enregistrements
// du Record Store, le listener a répercuté les mises à jour
// sur le formulaire. Pour éviter ce test, on aurait pu extraire
// les enregistrements du Record Store et les ajouter au formulaire
// au démarrage de l'application. Etant donné que l'extraction des
// enregistrements est consommatrice de ressources, ce choix
// permet un démarrage moins laborieux de l'application.
// L'extraction n'est effectuée que si l'utilisateur a besoins
// d'afficher l'ensemble des enregistrements. Notons également que
// cette extraction n'est effectuée qu'une seule fois pendant la durée
// d'exécution de l'application.
if (myForm.size() < nbRec){
// Purge du formulaire d’affichage
this.initForm() ;
byte[] myData = null;
try
{
// On parcours le Record Store
for (int i = 1 ; i <= nbRec ; i++ )
{
myData = myDb.getRecord(i);
if (myData != null){
str = new String(myData);
// On ajoute l'enregistrement au formulaire
-3-
Travail de diplôme - annexe n°2
Roggo Jean-Christophe
myForm.append(new StringItem("Rec n°" +
Integer.toString(i), " : " + str));
}
}
}
catch (RecordStoreException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible d'accéder au Record Store.");
myDisplay.setCurrent(errRec);
}
}
// On affiche le formulaire
myDisplay.setCurrent(myForm);
}
else {
// Affichage d'une alerte d'information si le Record Store est vide
final Alert info = new Alert("Info");
info.setType(AlertType.INFO);
info.setString("Le Record Store est vide.");
info.setTimeout(Alert.FOREVER);
myDisplay.setCurrent(info);
}
}
// Sauve l'enregistrement dans le Record Store
private void saveRec() {
try
{
String str = tb.getString();
if (!str.equals(""))
{
rec = new Rec(str);
myDb.addRecord(rec.toBytes(), 0, rec.toBytes().length);
// Affichage d'une alerte indiquant que l'enregistrement a été sauvegardé
final Alert info = new Alert ("Info");
info.setType(AlertType.INFO);
info.setTimeout(Alert.FOREVER);
info.setString("Votre saisie <<" + str + ">> a été enregistrée.");
myDisplay.setCurrent(info);
tb.setString("");
}
}
catch (RecordStoreFullException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible d'ajouter l'enregistrement. Le Record Store est
plein.");
myDisplay.setCurrent(errRec);
}
catch (RecordStoreException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible d'accéder au Record Store.");
myDisplay.setCurrent(errRec);
}
}
// Affiche le nombre d'enregistrements et la taille du Record Store
private void countRec() {
try
{
-4-
Travail de diplôme - annexe n°2
Roggo Jean-Christophe
int nbRec = myDb.getNumRecords();
strNbRec.setText(Integer.toString(myDb.getNumRecords()));
strTailleRec.setText(Integer.toString(myDb.getSize()) + " octets");
myDisplay.setCurrent(myFormNb);
}
catch (RecordStoreException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible d'accéder au Record Store.");
myDisplay.setCurrent(errRec);
}
}
// Purge du Record Store
private void clearAll() {
try
{
// Purge du formulaire d'affichage
this.initForm();
// On ferme le Record Store
myDb.closeRecordStore();
// On efface le Record Store
RecordStore.deleteRecordStore("myDb");
// On affiche une alerte d'information
final Alert info = new Alert ("Info");
info.setType(AlertType.INFO);
info.setTimeout(Alert.FOREVER);
info.setString("Le Record Store est purgé.");
myDisplay.setCurrent(info);
// On crée un nouveau Record Store de même nom
myDb = RecordStore.openRecordStore("myDb", true);
// Mise en place du listener sur ce Record Store
myDb.addRecordListener(this);
}
catch (RecordStoreException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible d'accéder au Record Store.");
myDisplay.setCurrent(errRec);
}
}
// Gestion des évènements
public void commandAction (Command myCommand, Displayable myDisplayable) {
if (myCommand == cmdExit) {
destroyApp(false);
}
else if (myCommand == save) {
this.saveRec();
}
else if (myCommand == cmdMenu) {
this.mainMenu();
}
else {
List list = (List)myDisplay.getCurrent();
switch (list.getSelectedIndex())
{
case 0:
this.newRec();
break;
case 1:
-5-
Travail de diplôme - annexe n°2
Roggo Jean-Christophe
this.countRec();
break;
case 2:
this.allRec();
break;
case 3:
this.clearAll();
break;
}
}
}
// Implémentation des méthodes définies dans l'interface Record Listener
// Exécuté lorsqu'un enregistrement est ajouté au Record Store
public void recordAdded(RecordStore recordStore, int recordId){
try
{
// On met le formulaire d'affichage à jour
myForm.append(new StringItem("Rec n°" + recordId, " : " + new
String(recordStore.getRecord(recordId))));
}
catch (RecordStoreException e)
{
// Affiche une alerte en cas d'erreur
final Alert errRec = new Alert ("Erreur");
errRec.setType(AlertType.ERROR);
errRec.setString("Impossible d'accéder au Record Store.");
myDisplay.setCurrent(errRec);
}
}
// Exécuté lorsqu'un enregistrement du Record Store est modifié.
// L'implémentation de cette méthode est vide car l'application n'offre pas la
// possibilité de modifier les enregistrements.
public void recordChanged(RecordStore recordStore, int recordId){
}
// Exécuté lorsqu'un enregistrement du Record Store est supprimé.
// L'implémentation de cette méthode est vide car l'application n'offre pas la
// possibilité de supprimer les enregistrements un à un.
public void recordDeleted(RecordStore recordStore, int recordId){
}
}
Vous trouverez ci-dessous quelques illustrations de l’application testRecordStore
exécutée sur l’émulateur standard du J2ME Wireless Toolkit 2.1.
-6-
Travail de diplôme - annexe n°2
Roggo Jean-Christophe
Fig. 1 Ecran de démarrage
de l’application
Fig. 2 Menu principal de
l’application
Fig. 3 Ecran de saisie d’un nouvel
enregistrement
Fig. 4 Les commandes
disponibles depuis l’écran de
saisie
Fig. 5 Ecran d’affichage du
nombre d’enregistrements
Fig. 6 Ecran d’affichage de
l’ensemble des
enregistrements
Fig. 7 Alerte affichée lorsque
le Record Store est purgé
Fig. 8 Alerte affichée lorsque
le Record Store est vide
Fig. 9 Alerte affichée lorsqu’ un
enregistrement a été ajouté
L’application testRecordStore permet d’enregistrer des chaînes de caractères dans un
Record Store (prototype de memo). Lorsque l’application est lancée, le menu principal
illustré à la Fig. 2 s’affiche.
En sélectionnant la rubrique New rec, l’écran de saisie d’un nouvel enregistrement de la
Fig. 3 s’affiche. En cliquant sur le bouton Menu, les commandes disponibles s’affichent (cf
Fig. 4). La commande Menu permet de retourner au menu principal de l’application. La
commande Sortie permet de quitter l’application et la commande Save permet de
sauvegarder la chaîne de caractères saisie. Lorsque la commande Save est activée l’alerte
d’information de la Fig. 9 est affichée pour informer l’utilisateur que sa saisie a été
enregistrée dans le Record Store.
En sélectionnant la rubrique Nb rec du menu principal, l’écran illustré à la Fig. 5 s’affiche.
Notons que même lorsqu’il est vide, le Record Store occupe un certain espace (stockage
d’informations structurelles propres au Record Store).
-7-
Travail de diplôme - annexe n°2
Roggo Jean-Christophe
Lorsque la rubrique All rec du menu principal est sélectionnée, l’écran d’affichage de
l’ensemble des enregistrements du Record Store est affiché (cf Fig. 6). Si le Record Store
est vide une alerte d’information est affichée (cf Fig. 8).
En sélectionnant la rubrique Clear all du menu principal, le Record Store est effacé puis
recréé. Tous les enregistrements sont donc supprimés et une alerte informe l’utilisateur
de la purge du Record Store (cf Fig. 7).
-8-
Travail de diplôme - annexe n°3
Roggo Jean-Christophe
Annexe n°3 : Mise en œuvre du composant HttpConnection
L’application testHttp est un exemple d’utilisation du composant HttpConnection. Son
code source est présenté dans l’encadré ci-dessous.
import
import
import
import
java.io.*;
javax.microedition.midlet.*;
javax.microedition.io.*;
javax.microedition.lcdui.*;
// MIDlet permettant de télécharger le contenu d'un fichier texte
public class TestHttp extends MIDlet {
// Déclaration du gestionnaire d'affichage
private Display myDisplay;
// Déclaration et initialisation d'un chaîne de caractères contenant l'URL
// désignant l'emplacement du fichier texte distant
private String url = "http://www.ruchat.ch/~yoda/test.txt";
// Déclaration d'un formulaire qui sera utilisé pour afficher
// le contenu téléchargé du fichier texte
private Form myForm = null;
// Constructeur
public TestHttp() {
myForm = new Form("Résultat");
}
// Exécuté au démarrage de l'application
public void startApp() {
myDisplay = Display.getDisplay(this);
try
{
downloadTxt(url);
}
catch (SecurityException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
}
// Télécharge le contenu du fichier texte distant
private void downloadTxt(String url) throws IOException {
StringBuffer b = new StringBuffer();
InputStream is = null;
HttpConnection c = null;
try
{
long len = 0 ;
int ch = 0;
c = (HttpConnection)Connector.open(url);
is = c.openInputStream();
len =c.getLength();
if( len != -1) {
// Lecture du flux d'octets
for(int i =0 ; i < len ; i++ ){
if((ch = is.read()) != -1) {
b.append((char) ch);
}
}
-1-
Travail de diplôme - annexe n°3
Roggo Jean-Christophe
} else {
// Lecture jusqu'à ce que la connexion soit fermée
while ((ch = is.read()) != -1) {
len = is.available() ;
b.append((char)ch);
}
}
myForm.append(new StringItem("Contenu du fichier texte : ", b.toString()));
}
finally
{
if (c != null)
{
is.close();
c.close();
}
}
myDisplay.setCurrent(myForm);
}
// Exécuté lorsque l'application est suspendue
public void pauseApp() { }
// Exécuté lorsque l'application se termine
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
}
Vous trouverez ci-dessous quelques illustrations de l’application testHttp exécutée sur
l’émulateur standard du J2ME Wireless Toolkit 2.1.
Fig. 1 Ecran de démarrage
de l’application
Fig. 2 Ecran de sécurité
affiché par le système
Fig. 3 Ecran affichant le résultat
du téléchargement
L’application testHttp permet de télécharger le contenu d’un fichier texte via une
connexion HTTP. Lorsqu’un MIDlet utilise un composant HttpConnection (ou un autre
composant de connexion réseau), le système d’exploitation du terminal mobile affiche
l’écran de la Fig. 2 pour des raisons de sécurité. Cet écran demande à l’utilisateur si il
autorise l’application à ouvrir une connexion réseau. Si l’utilisateur répond oui,
l’application pourra établir des connexions réseaux pendant toute la durée de son
-2-
Travail de diplôme - annexe n°3
Roggo Jean-Christophe
exécution. En revanche, si l’utilisateur répond non, l’application ne pourra établir aucune
connexion pendant son exécution (l’exception java.lang.SecurityException est
déclenchée). Pour pouvoir établir à nouveau une connexion, l’utilisateur devra quitter
l’application puis la relancer.
Si l’utilisateur autorise l’application à ouvrir une connexion, l’écran de résultat de la Fig. 3
est affiché une fois le téléchargement terminé.
-3-

Documents pareils

Adaptation multi-réseaux pour applications Mobiles

Adaptation multi-réseaux pour applications Mobiles messages textuels soit des images. que nous avons développée recommande l'utilisation de l'interface "active" pour les deux médias en cas de panne sur la deuxième interface …en donnant la priorité ...

Plus en détail