Développons en Java
v 2.40   Copyright (C) 1999-2023 .   
126. CLDC 128. CDC Imprimer Index Index avec sommaire Télécharger le PDF

 

127. MIDP

 

chapitre    1 2 7

 

Niveau : niveau 4 Supérieur 

 

 

C'est le premier profile qui a été développé dont l'objectif principal est le développement d'application sur des machines aux ressources et à l'interface limitées tel qu'un téléphone cellulaire. Ce profil peut aussi être utilisé pour développer des applications sur des PDA de type Palm.

L'API du MIDP se compose des API du CDLC et de trois packages :

Des informations complémentaires et le téléchargement de l'implémentation de référence de ce profil peuvent être trouvés sur le site : https://jcp.org/aboutJava/communityprocess/final/jsr118/index.html

Il existe deux versions du MIDP :

Ce chapitre contient plusieurs sections :

 

127.1. Les Midlets

Les applications créées avec MIDP sont des midlets : ce sont des classes qui héritent de la classe abstraite javax.microedition.midlet.Midlet. Cette classe permet le dialogue entre le système et l'application.

Elle possède trois méthodes qui permettent de gérer le cycle de vie de l'application en fonction des trois états possibles (active, suspendue ou détruite) :

Ces trois méthodes doivent obligatoirement être redéfinies.

Exemple ( MIDP 1.0 ) :
  package fr.jmdoudoux.dej.j2me;

  import javax.microedition.midlet.*;
  import javax.microedition.lcdui.*;

  public class Test extends MIDlet {

    public Test() {
    }

    public void startApp() {
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
  }

Le cycle de vie d'une midlet est semblable à celui d'une applet. Elle possède plusieurs états :

Le changement de l'état de la midlet peut être provoqué par l'environnement d'exécution ou la midlet.

La méthode startApp() est appelée lors du démarrage ou redémarrage de la midlet. Il est important de comprendre que cette méthode est aussi appelée lors du redémarrage de la midlet : elle peut donc être appelée plusieurs fois au cours de son exécution.

Les méthodes pauseApp() et destroyApp() sont appelées respectivement lors de mise en pause de la midlet et juste avant la destruction de la midlet.

 

127.2. L'interface utilisateur

Les possibilités concernant l'IHM de MIDP sont très réduites pour permettre une exécution sur un maximum de machines allant du téléphone portable au PDA. Ces machines présentent des contraintes fortes concernant l'interface qu'elles proposent à leurs utilisateurs.

Avec le J2SE, deux API permettent le développement d'IHM : AWT et Swing. Ces deux API proposent des composants pour développer des interfaces graphiques riches de fonctionnalités avec un modèle de gestion des événements complet. Ils prennent en compte un système de pointage par souris, avec un écran couleur possédant de nombreuses couleurs et une résolution importante.

Avec MIDP, le nombre de composants et le modèle de gestion des événements sont spartiates. Il ne prend en compte qu'un écran tactile souvent monochrome ayant une résolution très faible. Avec un clavier limité en nombres de touches et dépourvu de système de pointage, la saisie de données sur de tels appareils est particulièrement limitée.

L'API pour les interfaces utilisateurs du MIDP est regroupée dans le package javax.microedition.lcdui.

Elle se compose des éléments de haut niveaux et des éléments de bas niveaux.

 

127.2.1. La classe Display

Pour pouvoir utiliser les éléments graphiques, il faut obligatoirement obtenir un objet qui encapsule l'écran. Un tel objet est du type de la classe Display. Cette classe possède des méthodes pour afficher les éléments graphiques.

La méthode statique getDisplay() renvoie une instance de la classe Display qui encapsule l'écran associé à la midlet fournie en paramètre de la méthode.

Exemple ( MIDP 1.0 ) :
package fr.jmdoudoux.dej.j2me;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class Hello extends MIDlet {

  private Display display;

  public Hello() {
    display = Display.getDisplay(this);
  }

  public void startApp() {
  }

  public void pauseApp() {
  }

  public void destroyApp(boolean unconditional) {
 }
}

Les éléments de l'interface graphique appartiennent à une hiérarchie d'objets : tous les éléments affichables héritent de la classe abstraite Displayable.

La classe Screen est la classe mère des éléments graphiques de haut niveau. La classe Canvas est la classe mère des éléments graphiques de bas niveau.

Il n'est pas possible d'ajouter directement un élément graphique dans un Display sans qu'il soit inclus dans un objet héritant de Displayable.

Un seul objet de type Displayable peut être affiché à la fois. La classe Display possède la méthode getCurrent() pour connaître l'objet couramment affiché et la méthode setCurrent() pour afficher l'objet fourni en paramètre.

 

127.2.2. La classe TextBox

Ce composant permet de saisir du texte.

Exemple ( MIDP 1.0 ) :
package fr.jmdoudoux.dej.j2me;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class Hello extends MIDlet {

  private Display display;
  private TextBox textbox;

  public Hello() {
    display = Display.getDisplay(this);
    textbox = new TextBox("", "Bonjour", 20, 0); 
  }

  public void startApp() {
    display.setCurrent(textbox);
  }

  public void pauseApp() {
  }

  public void destroyApp(boolean unconditional) {
  }
}

Résultat :

sur l'émulateur Palm   sur l'émulateur de téléphone mobile
  

 

127.2.3. La classe List

Ce composant permet la sélection d'un ou plusieurs éléments dans une liste d'éléments.

Exemple ( MIDP 1.0 ) :
package fr.jmdoudoux.dej.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class Test extends MIDlet {
  private Display display;
  private List liste;
  
  protected static final String[] elements = {"Element 1",
                                            "Element 2",
                                            "Element 3",
                                            "Element 4"};

  public Test() {
    display = Display.getDisplay(this);
    liste = new List("Selection", List.EXCLUSIVE, elements, null);;
  }
  
  public void startApp() {
    display.setCurrent(liste);
  }
  
  public void pauseApp() {
  }
  
  public void destroyApp(boolean unconditional) {
  }
}

Résultat :

sur l'émulateur Palm   sur l'émulateur de téléphone mobile
  

 

en construction
La suite de cette section sera développée dans une version future de ce document

 

127.2.4. La classe Form

 

La classe From permet d'insérer dans l'élément graphique qu'elle représente d'autres éléments graphiques : cette classe sert de conteneurs. Les éléments insérés sont des objets qui héritent de la classe abstraite Item.

Exemple ( MIDP 1.0 ) :
package fr.jmdoudoux.fr.j2me;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class Hello extends MIDlet {

  private Display display;
  private Form mainScreen;

  public Hello() {
    display = Display.getDisplay(this);
  }

  public void startApp() {
    mainScreen = new Form("Hello");
    mainScreen.append("Bonjour");
   display.setCurrent(mainScreen);
  }

  public void pauseApp() {
  }

  public void destroyApp(boolean unconditional) {
  }
}

 

127.2.5. La classe Item

La classe javax.microedition.lcdui.Item est la classe mère de tous les composants graphiques qui peuvent être insérés dans un objet de type Form.

Cette classe définit seulement deux méthodes, getLabel() et setLabel() qui sont le getter et le setter pour la propriété label.

Il existe plusieurs composants qui héritent de la classe Item

Classe

Rôle

ChoiceGroup

sélection d'un ou plusieurs éléments

DateField

affichage et saisie d'une date

Gauge

affichage d'une barre de progression

ImageItem

affichage d'une image

StringItem

affichage d'un texte

TextField

saisie d'un texte


Exemple ( MIDP 1.0 ) :
package fr.jmdoudoux.fr.j2me;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class Hello extends MIDlet {

  private Display display;
  private Form form;
  private ChoiceGroup choiceGroup;
  private DateField dateField;
  private DateField timeField;
  private Gauge gauge;
  private StringItem stringItem;
  private TextField textField;

  public Hello() {
    display = Display.getDisplay(this);
    form = new Form("Ma form");

    String choix[] = {"Choix 1", "Choix 2"};
    stringItem = new StringItem(null,"Mon texte");
    choiceGroup = new ChoiceGroup("Sélectionner",Choice.EXCLUSIVE,choix,null);
    dateField = new DateField("Heure",DateField.TIME);
    timeField = new DateField("Date",DateField.DATE);
    gauge = new Gauge("Avancement",true,10,1);
    textField = new TextField("Nom","Votre nom",20,0);

    form.append(stringItem);
    form.append(choiceGroup);
    form.append(timeField); 
    form.append(dateField); 
    form.append(gauge);
    form.append(textField);
  }

  public void startApp() {
    display.setCurrent(form);
  }

  public void pauseApp() {
  }

  public void destroyApp(boolean unconditional) {
  }
}

Résultat sur l'émulateur de téléphone mobile :

Résultat sur l'émulateur Palm OS :

 

 

 

 

127.2.6. La classe Alert

Cette classe permet d'afficher une boîte de dialogue pendant un temps déterminé.

Elle possède deux constructeurs :

Elle possède des getters et des setters sur chacun de ces éléments.

Pour préciser le type de la boîte de dialogue, il faut utiliser une des constantes définies dans la classe AlertType dans le constructeur ou dans la méthode setType() :

Constante

type de la boîte de dialogue

ALARM

informer l'utilisateur d'un événement programmé

CONFIRMATION

demander la confirmation à l'utilisateur

ERROR

informer l'utilisateur d'une erreur

INFO

informer l'utilisateur

WARNING

informer l'utilisateur d'un avertissement


Pour afficher un objet de type Alert, il faut utiliser une version surchargée de la méthode setCurrent() de l'instance de la classe Display. Cette version nécessite deux paramètres : l'objet Alert à afficher et l'objet de type Displayable qui sera affiché lorsque l'objet Alert sera fermé.

La méthode setTimeout() qui attend un entier en paramètre permet de préciser la durée d'affichage en milliseconde de la boîte de dialogue. Pour la rendre modale, il faut lui passer le paramètre Alert.FOREVER.

Exemple ( MIDP 1.0 ) :
package fr.jmdoudoux.dej.j2me;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class Test extends MIDlet {

  private Display display;
private Alert alert;
  private Form form;

  public Test() {
    display = Display.getDisplay(this);
    form = new Form("Hello");
    form.append("Bonjour");

   alert = new Alert("Erreur", "Une erreur est survenue", null, AlertType.ERROR);
   alert.setTimeout(Alert.FOREVER);
  }

  public void startApp() {
    display.setCurrent(alert, form);
  }

  public void pauseApp() {
  }

  public void destroyApp(boolean unconditional) {
  }
}

Résultat sur l'émulateur de téléphone mobile:

Résultat sur l'émulateur Palm OS:

 

127.3. La gestion des événements

Les interactions entre l'utilisateur et l'application se concrétisent par le traitement d'événements particuliers pour chaque action.

MIDP définit des interfaces de type Listener pour la gestion des événements :

Interface Rôle

CommandListener

Listener pour une activation d'une commande
ItemStateListener Listener pour un changement d'état d'un composant(modification du texte d'une zone de texte, ...)

 

en construction
Cette section sera développée dans une version future de ce document

 

127.4. Le stockage et la gestion des données

Avec MIDP, le mécanisme pour la persistance des données est appelé RMS (Record Management System). Il permet le stockage de données et leur accès ultérieur.

RMS propose un accès standardisé au système de stockage de la machine dans laquelle s'exécute le programme. Il n'impose pas aux constructeurs la façon dont les données doivent être stockées physiquement.

Du fait de la simplicité des mécanismes utilisés, RMS ne définit qu'une seule classe : RecordStore. Cette classe ainsi que les interfaces et les exceptions qui composent RMS sont regroupées dans le package javax.microedition.rms.

Les données sont stockées dans un ensemble d'enregistrements (records). Un enregistrement est un tableau d'octets. Chaque enregistrement possède un identifiant unique nommé recordId qui permet de retrouver un enregistrement particulier.

A chaque fois qu'un ensemble de données est modifié (ajout, modification ou suppression d'un enregistrement), son numéro de version est incrémenté.

Un ensemble de données est associé à un unique ensemble composé d'une ou plusieurs Midlets (Midlet Suite).

Un ensemble de données possède un nom composé de 32 caractères maximum.

 

127.4.1. La classe RecordStore

L'accès aux données se fait obligatoirement en utilisant un objet de type RecordStore.

Les principales méthodes sont :

Méthode

Rôle

int addRecord(byte[],int, int)

Ajouter un nouvel enregistrement

void addRecordListener(RecordListener)

 

void closeRecordStore()

Fermer l'ensemble d'enregistrements

void deleteRecord(int)

Supprimer l'enregistrement dont l'identifiant est fourni en paramètre

static void deleteRecordStore(String)

Supprimer l'ensemble d'enregistrements dont le nom est fourni en paramètre

Enumeration enumerateRecords(RecordFilter , RecordComparator, boolean)

Renvoyer une énumération pour parcourir tout ou partie de l'ensemble

String getName()

Renvoyer le nom de l'ensemble d'enregistrements

int getNextRecordID()

Renvoyer l'identifiant du prochain enregistrement créé

int getNumRecords()

Renvoyer le nombre d'enregistrements contenu dans l'ensemble

byte[] getRecord(int)

Renvoyer l'enregistrement dont l'identifiant est fourni en paramètre

int getRecord(int, byte[], int )

Obtenir les données contenues dans un enregistrement dont l'identifiant est fourni en paramètre. Renvoie le nombre d'octets de l'enregistrement

int getRecordSize(int)

Renvoyer la taille en octets de l'enregistrement dont l'identifiant est fourni en paramètre

int getSize()

Renvoyer la taille en octets occupée par l'ensemble

static String[] listRecordStores()

Renvoyer un tableau de chaînes de caractères contenant les noms des ensembles de données associés au Midlet courant

static RecordStore openRecordStore(String, boolean)

Ouvrir un ensemble de données dont le nom est fourni en paramètre. Celui-ci est créé s'il n'existe pas et que le booléen est à true

void setRecord(int, byte[], int, int)

Mettre à jour l'enregistrement précisé avec les données fournies en paramètre


Pour pouvoir utiliser un ensemble d'enregistrements, il faut utiliser la méthode statique openRecordStore() en fournissant le nom de l'ensemble et un booléen qui précise si l'ensemble doit être créé au cas où celui-ci n'existerait pas. Elle renvoie un objet RecordStore qui encapsule l'ensemble d'enregistrements.

L'appel de cette méthode peut lever l'exception RecordStoreNotFoundException si l'ensemble n'est pas trouvé, RecordStoreFullException si l'ensemble de données est plein ou RecordStoreException dans les autres cas problématiques.

 

 

La méthode closeRecordStore() permet de fermer un ensemble précédemment ouvert. Elle peut lever les exceptions RecordStoreNotOpenException et RecordStoreException.

 

en construction
La suite de cette section sera développée dans une version future de ce document

 

127.5. Les suites de midlets

 

en construction
Cette section sera développée dans une version future de ce document

 

127.6. Packager une midlet

Une application constituée d'une suite de midlets est packagée sous la forme d'une archive .jar. Cette archive doit contenir un fichier manifest et tous les éléments nécessaires à l'exécution de l'application (fichiers .class et les ressources telles que les images, ...).

 

127.6.1. Le fichier manifest

Ce fichier contient des informations sur l'application.

Ce fichier contient une définition des propriétés utilisées par l'application. Ces propriétés sont sous la forme clé/valeur.

Plusieurs propriétés sont définies par les spécifications des midlets : celles-ci commencent par MIDlet-.

Propriétés Rôle
MIDlet-Name Nom de l'application
MIDlet-Version Numéro de version de l'application
MIDlet-Vendor Nom du fournisseur de l'application
MIDlet-Icon Nom du fichier .png contenant l'icône de l'application
MIDlet-Description Description de l'application
MIDlet-Info-URL  
MIDlet-Jar-URL URL de téléchargement de fichier jar
MIDlet-Jar-Size taille en octets du fichier .jar
MIDlet-Data-Profile  
MicroEdition-Configuration  

 

Il est possible de définir ses propres attributs

 

127.7. MIDP for Palm O.S.

MIDP for Palm O.S. est une implémentation particulière du profile MIDP pour le déploiement et l'exécution d'applications sur des machines de type Palm. Elle permet d'exécuter des applications écrites avec MIDP sur un PALM possédant une version 3.5 ou supérieure de cet O.S.

Cette implémentation remplace l'ancienne implémentation développée par Sun nommée KJava.

 

127.7.1. L'installation

MIDP for Palm O.S. n'est plus téléchargeable : il fallait télécharger le fichier midp4palm-1_0.zip et sa documentation dans le fichier midp4palm-1_0-doc.zip.

L'installation comprend une partie sur le poste de développement PC et une partie sur la machine Palm pour les tests d'exécution.

Pour pouvoir utiliser MIDP for Palm O.S., il faut déjà avoir installé CLDC et MIDP.

Il faut commencer l'installation sur le PC en décompressant les deux fichiers dans un répertoire.

Pour pouvoir exécuter les applications sur le Palm, il faut installer le fichier MIDP.prc contenu dans le répertoire PRCFiles sur le Palm en procédant comme pour toute application Palm.

En cliquant sur l'icône, on peut régler différents paramètres.

Un clic sur le bouton "Preferences" permet de modifier ces paramètres.

 

127.7.2. La création d'un fichier .prc

MIDP for Palm O.S. fournit un outil pour transformer les fichiers .jad et .jar qui composent une application J2ME en un fichier .prc directement installable sur un Palm.

Sous Windows, il suffit d'exécuter le programme converter.bat situé dans le sous-répertoire Converter du répertoire d'installation.

Il faut que la variable d'environnement JAVA_PATH pointe vers le répertoire d 'installation d'un JDK 1.3. minimum. Si ce n'est pas le cas, un message d'erreur est affiché.

Error: Java path is missing in your environment
         Please set JAVA_PATH to point to your Java directory
         e.g. set JAVA_PATH=c:\bin\jdk1.3\

Si tout est correct, l'application se lance.

Il est possible de préciser le répertoire du ou des fichiers .prc générés en utilisant l'option "Preference" du menu "File" :

Une boîte de dialogue permet de choisir entre le même répertoire que celui qui contient le fichier .jad ou de sélectionner un répertoire quelconque.

Il suffit de cliquer sur l'icône en forme de répertoire dans la barre d'icônes pour sélectionner le fichier .jad. Les fichiers .jad et .jar de l'application doivent obligatoirement être dans le même répertoire.

Un clic sur le bouton "Convert", lance la conversion.

Si la conversion échoue, un message d'erreur est affiché. Exemple, si le fichier .jar correspond au fichier .jad est absent, alors le message suivant est affiché :

Si toutes les opérations se sont correctement passées, alors un message récapitulatif est affiché :

 

127.7.3. L'installation et l'exécution d'une application

Une fois le fichier .prc créé, il suffit d'utiliser la procédure standard d'installation d'un tel fichier sur le Palm (ajouter le fichier dans la liste avec "l'outil d'installation" du Palm et lancer une synchronisation).

Une fois l'application installée, l'icône de l'application apparaît.

Pour exécuter l'application, il suffit comme pour une application native, de cliquer sur l'icône.

Lors de la première exécution, il faut lire et valider la licence d'utilisation.

Une splash screen s'affiche durant le lancement de la machine virtuelle.

Puis l'application s'exécute.

 


126. CLDC 128. CDC Imprimer Index Index avec sommaire Télécharger le PDF    
Développons en Java
v 2.40   Copyright (C) 1999-2023 .