P
'
t
i
t
e
C
h
a
t
t
e
 
spacer~ PROGRAMMERS DON'T DIE, THEY JUST GOSUB WITHOUT RETURN Articles | Connexion
 
~Java mobile

Précédent  
  Java  
  Suivant
 Présentation

Au-delà du simple langage, se trouve la plate-forme Java. Cette dernière a pris pied dans de nombreux domaines particulièrement celui de l'informatique embarquée. Nous allons découvrir comment en tirer profit pour développer un outil destiné aux téléphones mobiles.
 Sommaire


 Introduction

Une configuration définit les ressources minimales nécessaires pour accueillir la plate-forme Java. Aujourd'hui, deux configurations ont pris place dans des appareils grand public, à savoir Connected Device Configuration (CDC) et Connected Limited Device Configuration (CLDC). De ces deux configurations, la plus répandue s'avère être la seconde, présente dans les PDAs et téléphones mobiles. C'est également celle qui nous intéressera. En ce qui concerne les profils, là aussi nous retrouvons deux définitions : MIDP et PersonalJava. Si la seconde s'adresse aux systèmes disposant de ressources relativement importantes (Login: avait présenté PersonalJava dans le cadre d'un développement d'application Java pour assistant digital Zaurus), la première, qui signifie Mobile Information Device Profile, s'adresse aux appareils limités en capacités. Le rôle des profils est de compléter la configuration avec des fonctionnalités spécifiques au matériel. Au final, du point de vue du développeur, nous obtenons un jeu d'API plus ou moins large, dépendant de l'appareil cible.

Au coeur de la plate-forme Java se trouvent trois sous plate-formes possédant chacun un rôle distinct. Au plus haut niveau nous rencontrons J2EE (Java 2 Enterprise Edition) qui permet le développement et le déploiement d'applications au niveau de l'entreprise (architectures B2C et B2B). En dessous prend place la plus connue J2SE (Java 2 Standard Edition). Celle-ci permet le développement et l'exécution de logiciels au niveau de l'utilisateur. Il s'agit de la plate-forme la plus répandue, surtout parmi les programmeurs amateurs. Tout en bas de cette chaîne nous découvrons enfin ce qui nous intéresse, la plate-forme J2ME pour Java 2 Micro Edition. Cette dernière, contrairement aux précédentes, ne se trouve pas réellement définie. En son sein se trouvent de nouveaux sous-ensembles appelés configurations et profils. Ceux-ci permettent de caractériser des cibles de déploiement.

J2ME se destine à la production d'applications Java pour systèmes embarqués. La notion d'un tel système se révèle plutôt large dans l'environnement J2ME. Ainsi téléviseurs, PDAs, téléphones mobiles et voitures seront tous considérés comme des systèmes embarqués. Toutefois, la diversité de ces systèmes et surtout leurs nombreuses différences (un téléphone Nokia 3510i autorisera 200 ko de mémoire tandis que le modèle 3590 bénéficiera de 140 ko) impose la mise en place d'un système de distinction tout en gardant une base commune. J2ME a donc été créée sous forme d'une architecture 2-tiers : les configurations d'un côté et les profils de l'autre.


 Outils de développement

Les téléphones mobiles compatibles Java suivent les spécifications CLDC 1.0 et MIDP 1.0. Concrètement, tous ces téléphones proposent les paquetages suivants :

  • java.io pour la gestion des entrées/sorties
  • java.lang pour les classes de base
  • java.util pour les collections et utilitaires
  • javax.microedition.io pour les connexions distantes
  • javax.microedition.lcdui pour les interfaces graphiques
  • javax.microedition.midlet pour créer une application
  • javax.microedition.rms pour le stockage de données

Certains constructeurs, comme Nokia, peuvent ajouter des paquetages supplémentaires. Par exemple, des classes des paquetages supplémentaires de Nokia viennent d'être intégrées à la spécification MIDP 2.0. Celles-ci permettent par exemple de créer des jeux plein écran très simplement. Toute application MIDP est appelée MIDlet (en référence aux applets) et doit dériver de la classe javax.microedition.midlet.MIDlet.



Cycle de vie d'un MIDlet

Pour se lancer dans le développement d'applications pour téléphones mobiles, seule l'API MIDP 1.0, téléchargeable sur le site http://java.sun.com s'avère indispensable. Toutefois, les constructeurs offrent de nombreux outils destinés à faciliter le travail du programmeur. Tout au long de cet article, nous allons nous reposer sur les kits de développements et émulateurs de Nokia. Ces derniers sont gratuits, téléchargeables sur le site http://forum.nokia.com et de qualité. De plus, les téléphones Nokia sont très répandus et les nouvelles séries supportant Java (séries 30, 40, 60 et 80) commencent à faire leur apparition sur le marché. L'application que nous allons étudier sera testée sur des émulateurs des modèles 3510i (appareil en couleurs) et 6310i (appareil noir et blanc) ainsi que sur un véritable 3510i. Ceux d'entre vous qui désireraient acquérir un téléphone compatible Java seront sûrement rebutés par les prix. Toutefois les modèles 3410 et 3510i restent abordables. Notez que l'utilisation de ces kits de développement n'est en rien nécessaire. L'archive MIDP 1.0 (d'environ 400 ko) suffit.

Des éditeurs de logiciels proposent par ailleurs des environnements de développement dédiés à de tels travaux. Borland offre ainsi un MobileSet pour JBuilder, Sun Microsystems propose SunONE Studio Mobile Edition (gratuit) et MetroWerks apporte CodeWarrior Wireless Studio Edition. Sachez que les kits de Nokia ont été conçus pour s'intégrer à JBuilder et SunONE Studio. Puisque ce dernier n'est autre qu'une extension de l'environnement Open Source NetBeans, nous allons naturellement opter pour celui-ci.

Au final, le développement de notre logiciel demande l'installation des outils suivants (les numéros de version sont fournis à titre indicatif seulement) : Nokia's Developer Suite 1.0 for J2ME, NetBeans 3.4 et bien entendu le J2SE SDK 1.4.0 pour compiler. Vous pourrez également décider d'ajouter un ou plusieurs émulateurs supplémentaires (celui fourni avec la suite Nokia correspond au modèle 6310i) en téléchargeant par exemple le Nokia 3510i MIDP SDK.


 Création d'un projet J2ME

Une fois que vous aurez lancé NetBeans vous devrez créer un nouveau projet à l'aide du Project Manager. Pour garantir votre confort d'édition et de compilation il sera impératif de monter dans le système de fichiers l'archive lib/classes.zip de l'un des émulateurs. Les outils du kit de développement Nokia apparaissent dans le menu Tools/Nokia mais ne s'activent que dans certains situations. Pour ce faire, commencer par créer sur votre disque dur un répertoire qui accueillera votre projet puis montez le dans le système de fichiers du projet avant de lui ajouter un sous-répertoire intitulé classes/. Sachez que chaque fois que nous ferons appel aux outils Nokia, un noud du système de fichiers du projet devra posséder le focus dans NetBeans. Ainsi, pour créer notre premier MIDlet devons-nous cliquer sur le répertoire classes/ puis sur Tools/Nokia/Create Class. Assurez-vous de créer une nouvelle classe dérivant de javax.microedition.midlet.MIDlet et important les paquetages midlet et lcdui. Lorsque vous aurez compilé cette classe vous pourrez l'exécuter en cliquant dessus dans le système de fichiers puis en exécutant Tools/Nokia/Start Emulators. Remarquez que vous pouvez facilement activer ou désactiver des émulateurs par l'entremise du menu Configure Emulators.

En dessous de l'onglet du système de fichiers se trouve un onglet de propriétés. En sélectionnant votre MIDlet dans l'explorateur de projet, un nouvel onglet Execution apparaîtra au côté de celui des propriétés. Il vous permet de modifier des caractéristiques relatives à la compilation et à l'exécution du projet. Si vous avez à ce stade déjà essayé de compiler puis d'exécuter les émulateurs, vous aurez sans doute rencontré un problème. Il s'agit de l'erreur "Bad major version number". Rappelez-vous que les machines virtuelles embarquées par nos téléphones sont bien moins avancées que celles présentes sur nos ordinateurs. De ce fait, nos classes doivent être compilées comme si elles l'étaient avec un JDK 1.1. Ceci s'avère possible en commande en ligne par l'intermédiaire de l'option -target 1.1. Dans NetBeans, vous devez cliquer sur l'option Compiler de l'onglet Execution. Une fenêtre s'ouvre alors. Dans cette dernière, modifier la propriété Target JDK dans l'onglet Expert en précisant 1.1 comme valeur. L'erreur ainsi réglée provient de l'outil de pré-vérification fourni avec chaque émulateur. Celui-ci génère des fichiers .class modifiés pour les machines virtuelles des téléphones. Il permet également de s'assurer de la validité du bytecode. Notez à ce propos que les types float et double ne sont pas acceptés !

Pour ceux d'entre vous qui ne veulent pas s'embarrasser de tous ces kits de développement, sachez que vous trouverez un outil de vérification dans la distribution J2ME de java.sun.com.


 Un MIDlet

Le MIDlet que nous allons étudier s'intitule ProgXMIDlet. Celui-ci a pour vocation de se voir employé conjointement à un site Internet nommé ProgX. Proposant des articles de programmation dans divers thèmes (XML, PHP, Java.) ce site s'efforce d'être le plus accessible possible. Ainsi l'outil ProgXMIDlet permet de consulter depuis son téléphone portable les thèmes proposés sur le site. En sélectionnant un thème, l'utilisateur pourra consulter les titres des articles disponibles. Les données seront transmises par un servlet qui parcourra les articles du site. Vous trouverez dans la section téléchargements le code source complet dudit site. Si vous désirer utiliser le MIDlet avec celui-ci vous devrez l'installer sur un serveur Apache/PHP supportant les extensions XML et XSLT et placer les servlets sur un serveur d'applications Java mappé sur le port 8080. Pour simplifier les tests, le script test.php présent dans le répertoire j2me/www permet de simuler le comportement du servlet censé générer les listes pour le MIDlet.

Au démarrage, notre outil ira récupérer les données à une URL précise. Celle-ci doit retourner des titres de thèmes, séparés par un caractère \n. Pour consulter la liste des titres d'un thème particulier, ProgXMIDlet consultera la même URL suffixée de ?thema=NomThème. En imaginant que vous avez installé le servlet, les URL employées seront http://localhost:8080/listarticles et http://localhost:8080/listarticles?thema=Java. Pour la réalisation de ce MIDlet nous devons donc apprendre à réaliser une interface graphique présentant des listes ainsi que des connexions sur serveurs distants.

Un MIDlet connaît trois états dans son cycle de vie : en pause, actif et détruit. Une fois créé par le système d'exploitation du téléphone, son état devient "en pause". Puis le système invoque la méthode startApp() qui change l'état en actif. Le retour au premier état a lieu lors de l'invocation de la méthode pauseApp(). Enfin, à tout moment l'exécution de la méthode destroyApp() conduit à l'état détruit. Nous constatons ainsi que la méthode startApp() peut se voir appelée plusieurs fois au cours du cycle de vie de l'application. Le constructeur du MIDlet fera donc office de méthode main() pour toutes les tâches ne devant s'opérer qu'une seule fois.


 Interface utilisateur

La réalisation d'interfaces utilisateur pour téléphones mobiles s'avère particulièrement difficile tant la place à l'écran manque. L'ensemble des outils graphiques (on ne parle pas de widget en environnement MIDP mais de displayable) se trouve dans le paquetage javax.microedition.lcdui. Nous pouvons considérer la classe Display comme la plus importante. Elle permet en effet de modifier le contenu de l'interface. Pour obtenir une instance de cette classe, nous devons impérativement employer la méthode statique getDisplay(MIDlet c). Vous constaterez qu'un seul objet de type displayable peut être activé à la fois. Cela signifie que nous devons opter pour un champ texte ou une liste, mais pas les deux en même temps.

La spécification d'objet actif a lieu grâce à la méthode setCurrent(Displayable d) du Display. Voici par exemple un Hello World en J2ME MIDP :

TextBox hello = new TextBox("Hello", "World", 0, TextBox.ANY);
Display display = Display.getDisplay(this);
display.setCurrent(hello);
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
L'impossibilité d'afficher plusieurs choses à la fois rend parfois le développement d'applications J2ME assez complexe. Certains Design Patterns apportent des solutions à ces problèmes. Si vous désirez voir traités dans ces pages les motifs de conception Menu, Pagination, Slide et Wizard n'hésitez pas à contacter la rédaction.

Notez cependant que le displayable Form autorise le mélange de divers composants comme des images, des jauges ou de simples étiquettes en utilisant des astuces d'affichages. Les habitués du WAP connaissent bien les Form qui conduisent, lors du choix d'un élément, à un écran entièrement nouveau. Pour notre part nous nous contenterons des classes Alert (pour afficher des messages) et List (pour traiter des listes). La création d'une liste se réalise de la sorte :

this.listThemas = new List("ProgX - Themas", List.IMPLICIT);
       
      
JextCopier dans Jext
Le second argument peut prendre les valeurs IMPLICIT, EXCLUSIVE et MULTIPLE. Une liste exclusive n'autorise la sélection que d'un seul et unique élément à la fois tandis qu'une liste multiple permet de choisir plusieurs entrées. Néanmoins, nous utiliserons des listes implicites. Ces dernières se comportent comme des listes exclusives à ceci près que toute action est considérée comme une sélection. En effet, chaque displayable peut se voir assigné des commandes qui apparaissent sous la forme de menus à l'écran (leur présentation dépend du téléphone, de leur nombre et de leurs caractéristiques).

De même, un displayable peut posséder un CommandListener chargé de gérer les actions générées par ces commandes. Nous pouvons ainsi compléter notre liste en lui ajoutant un menu pour quitter l'application :

Command exitCommand = new Command("Exit", Command.EXIT, 1);
this.listThemas = new List("ProgX - Themas", List.IMPLICIT);
this.listThemas.addCommand(exitCommand);
this.listThemas.setCommandListener(this);
       
      
JextCopier dans Jext
Nous désignons ici par this le CommandListener de la liste, le MIDlet actuel. Pour assurer la gestion de la commande de sortie du logiciel, nous pourrions employer les quelques lignes de code du listing 1. L'application propose de cette manière des menus dans les listes pour faire marche arrière, sélectionner un thème ou encore changer l'URL où obtenir les données. Nous pouvons ajouter les noms des thèmes et les titres des articles aux listes par l'intermédiaire de la méthode append().


 Connexions distantes et stockage

Lors du premier lancement de l'application, nous demandons à l'utilisateur d'entrer l'URL à laquelle le programme ira chercher les données des listes. Pour éviter de la demander à chaque exécution, l'application stocke cette entrée en mémoire sur le téléphone. Ceci est rendu possible par le paquetage javax.microedition.rms. Le stockage des données s'effectue au sein d'enregistrements d'octets (donc de manière similaire à ce qui est proposé par la machine virtuelle SuperWaba sur Palm Pilot et PocketPC). Ce paquetage se révèle particulièrement facile d'accès puisqu'il ne contient qu'une seule classe, RecordStore.

Nous pourrons lire l'URL stockée en exécutant les instructions qui suivent :

RecordStore store = RecordStore.openRecordStore("progx", false);
byte b[] = store.getRecord(1);
this.servletURL = new String(b, 0, b.length);
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Le second paramètre de la méthode statique openRecordStore() permet, quand il vaut true, de créer le jeu d'enregistrements s'il n'existe pas déjà. L'écriture de l'enregistrement s'effectue dans notre application au sein de la méthode commandAction() après validation par l'utilisateur d'un champ texte. Ce dernier, représenté par une instance de la classe TextBox, autorise la lecture d'une valeur sous forme de chaîne de caractères que nous devons transformer en tableau d'octets. Le listing 2 présente les lignes nécessaires pour sauvegarder l'URL entrée. Nantis de cette URL nous allons pouvoir contacter le serveur et obtenir les informations souhaitées.

Nous devons pour cela nous servir du paquetage javax.microedition.io et de son unique classe Connector. Cette dernière permet de réaliser toutes sortes de connexions distantes différentes, particulièrement des connexions HTTP. La méthode open() renvoie un objet Connection que nous pouvons convertir explicitement en HttpConnection ou ContentConnection (d'autres conversions sont possibles si nous n'utilisons pas le préfixe http:// dans l'adresse). La première renvoie aussi bien le corps de la réponse HTTP que l'en-tête. La seconde quant à elle ne fournit que le corps, c'est donc à elle qu'ira notre préférence. La méthode getContent() du MIDlet crée une nouvelle connexion puis lit et interprète son contenu à l'instar du listing 3.

Nous avons ici rapidement fait le tour des possibilités offertes par J2ME MIDP. La lecture du code source de ProgXMIDlet vous donnera quelques informations supplémentaires.


 Déployer des applications J2ME MIDP

Le déploiement de votre nouvelle application sur un téléphone nécessite un téléchargement OTA (Over The Air) dans le jargon J2ME. Il s'agit en fait de créer un paquetage compréhensible par les appareils. Pour ce faire, vous devez créer un fichier .jad (pour Java Application Descriptor) contenant des informations sur le MIDlet et un .jar contenant l'application elle-même. Le listing 4 présente un .jad généré à l'aide du kit de développement Nokia dans NetBeans. Vous devrez ensuite placer ces fichiers sur un serveur Web supportant les types MIME suivants (ici rédigés pour Apache) :

AddType text/vnd.wap.wml wml
AddType application/java-archive jar
AddType text/vnd.sun.j2me.app-descriptor jad
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Enfin vous devrez placer un fichier WML accessible par le WAP sur ce même serveur pour permettre aux utilisateurs de télécharger votre logiciel :

<wml>
  <card id="card1" title="Télécharger un MIDlet">
    <p>
      Voici notre MIDlet :<br />
      <a href="ProgX.jad">ProgX</a><br />
    </p>
  </card>
</wml>
       
      
JextCopier dans Jext
Notez que si vous désirez tester le déploiement de votre MIDlet sur votre ordinateur par l'entremise d'un émulateur, ou si vous désirez transformer votre PC en serveur WAP/J2ME, vous devrez vous munir d'une passerelle WAP. En installant le Nokia Mobile Internet Toolkit 3.1 (MINT) vous obtiendrez une telle passerelle, malheureusement limitée à votre seule machine. Celle-ci se révélera néanmoins suffisante pour tester vos déploiements. Sachez enfin que des hébergeurs tels que Free jouent très bien ce rôle. Vous pouvez ainsi installer ProgXMIDlet en entrant l'URL http://jext.free.fr/j2me/ dans votre téléphone compatible Java.


 Listings

public classe ProgXMIDlet extends MIDlet implements CommandListener
{
  // .
  public void commandAction(Command command, Displayable displayable)
  {
    if (command.getCommandType() == Command.EXIT)
      requestExit();
  }

  private void requestExit()
  {
    destroyApp(false);
    notifyDestroyed();
  }
}
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
TextBox askURL = (TextBox) displayable;
this.servletURL = askURL.getString();
byte[] b = this.servletURL.getBytes();

RecordStore store = RecordStore.openRecordStore("progx", true);
store.addRecord(b, 0, b.length);
store.closeRecordStore();
       
      
JextCopier dans Jext
ContentConnection c = (ContentConnection) Connector.open(url);
InputStream is = c.openInputStream();
char ch = '\0';
while ((ch = is.read()) != -1)
  // .
       
      
JextCopier dans Jext
MIDlet-Name: ProgX
MIDlet-Vendor: Helix Team
MIDlet-Version: 1.0
MIDlet-Jar-Size: 5707
MIDlet-Jar-URL: ProgX.jar
MIDlet-Icon: /progxmidlet.png
MIDlet-Description: This MIDlet allows to browse articles from ProgX
MIDlet-1: ProgXMIDlet, /progxmidlet.png, ProgXMIDlet
       
      
JextCopier dans Jext

 Téléchargement

Voir section téléchargements du menu à gauche.



par Romain Guy
romain.guy@jext.org
http://www.jext.org
Dernière mise à jour : 14/10/2006


Précédent  
  Java  
  Suivant

 
#ProgX©2005 Mathieu GINOD - Romain GUY - Erik LOUISE