Projet RA Télécommande Mplayer La MIDlet Cycle de vie. Carmier Cyprien

publicité
Carmier Cyprien
Chatellier Anthony
François Amaury
Melas Mickael
M2 GL
Année 2006/2007
Projet RA Télécommande Mplayer
La MIDlet
Cycle de vie.
L’application J2ME pour le téléphone portable, doit respecter le cycle de vie d’une MIDlet (type dont elle hérite). Afin de respecter ce cycle, l’application doit implémenter trois méthodes startApp, pauseApp, et destroyApp.
La méthode startApp fait office de main. En fait elle agit comme la méthode run d’un Thread.
La méthode pauseApp permet de gérer la MIDlet lorsqu’elle n’est plus la tâche active, mais nous ne nous en occupant pas. Enfin la méthode destroyApp gère la terminaison de l’application.
Ici la MIDlet se constitue d’un seul écran. L’affichage passe par l’objet Display et les « items » sont placés dans un Form (lui­même attaché au Display). L’application devant se comporter comme une simple télécommande, nous plaçons donc des boutons (générés à l’aide de constantes afin de facilement pouvoir en ajouter ou supprimer), et un champ texte afin de visualiser le code envoyé au serveur.
Les commandes.
Après avoir créé les widgets, il faut alors leur attribuer des commandes. Il y a deux type de commandes. La commande EXIT sert à quitter l’application (touche rouge du téléphone par exemple). Cette commande se détecte avec un Listener, et la méthode commandAction (avec un Displayable en paramètre, donc l’environnement graphique) permet d’associer du code avec cette commande.
La commande PRESS est créée afin d’assurer la gestion de l’appui sur un bouton. Cette commande apparaît sur un bouton de menu. Le code est associé avec la méthode commandAction qui prend ici un Item en paramètre (l’Item associé à la commande).
Communication Bluetooth Client ­Serveur
La dernière composante de la MIDlet est la composante liée à la communication avec le serveur, donc la composante Bluetooth. Celle­ci doit permettre de détecter des appareils proposant le service voulu (identifié par l’UUID enregistré auprès du SDP), puis d’envoyer les données. En ce qui concerne la détection de périphériques et la détection de service, l'API jsr82 permet de les gérer très précisément grâce, entre autres, à la classe DiscoveryAgent et à ses fonctions searchServices() et startInquiry(). Cependant nous avons opté pour méthode plus simple, c'est à dire que l'on ne cherche pas à lister explicitement tous les périphériques et tous les services pour ensuite permettre à l'utilisateur d'en choisir un. Étant donné que notre programme ne concerne que Mplayer, nous cherchons uniquement ce service, et dès qu'on le trouve, on se connecte au périphérique qui le fournit, sans en laisser le choix à l'utilisateur. Ceci est rendu possible par la méthode selectService du DiscoveryAgent. Malheureusement nou n'avons pas réussi à vérifier que cette méthode fonctionne bien.
Une fois qu'il est connecté, le composant gérant le Bluetooth permet donc d’envoyer les données en passant par le protocole RFCOMM. Nous utilisons un DataOutputStream afin de pouvoir envoyer les données (nous envoyons un entier associer à la commande mis en constante), au format UTF. Ce formatage des deux côtés (MIDlet / serveur) permet de s’assurer la compatibilité des données.
Coté serveur nous avons choisi d'utiliser Avetana, qui est une implémentation open source de la jsr82. Nous avons donc exactement la même interface coté serveur et coté client. Le code du serveur est très simple, il consiste uniquement à enregistrer un service avec un identifiant (UUID) quelconque, puis à accepter les connexions des clients, et ensuite à lire données reçues pour les transférer vers la partie Mplayer de notre programme.
Le Serveur
La communication de notre serveur avec l’application mplayer a été développé grâce à la technologie JNI et les commandes disponibles dans la bibliothèque Xlib. Bien que mplayer possède un mode slave, permettant de lui passer les commandes sur l’entrée standard, nous n’avons pas eu le temps d’orienter notre code vers cette solution. En effet nous n’avions pars remarqué dans un premier temps cette option du logiciel et elle ne nous a été communiqué que lors de notre dernier rendez vous avec le professeur. Nous avions déjà passé 4 jours à comprendre pourquoi notre code ne fonctionnait pas alors que le problème venait de la clé USB Bluetooth qui était tout simplement défectueuse. Plutôt donc que de passer le dernier jour qui nous restait sur la création d’un nouveau serveur de communication, nous avons préféré continuer avec le système existant tout en essayant de vérifier pas à pas chaque point de notre programme (notamment le problème de communication entre le téléphone et le pc où nous avions beaucoup de retour d’erreur comme quoi la commande n’était pas envoyée).
Xlib
Commençons par expliquer le rôle de Xlib dans notre projet. mplayer fonctionnant en ligne de commande, il existe une liste de raccourcis claviers permettant de le contrôler facilement. Ainsi lorsque l’on veut passer la vidéo en plein écran, il suffit de presser la touche « f ». Nous avons alors décidé de réutiliser les raccourcis claviers pour à notre tour faire parvenir les commandes de notre téléphone vers le programme. S’appuyant sur un des rapports de l’année passée, nous avons pu constaté que Xlib permettait de faire des simulations d’envois de lettres via une commande XSendEvent(). Après plusieurs essais non concluant sur l’utilisation de cette fonction, nous nous sommes réorientés vers une autre fonction de Xlib : XXX. Le seul inconvénient de cette méthode est que le signal sera envoyé à la fenêtre ayant le focus. Il faut donc lors de l’utilisation de notre serveur que le focus soit sur la vidéo que nous sommes entrain de lire.
JNI
Xlib étant écrit en C, il a fallu l’interfacer avec notre serveur écrit en java. Nous avons donc du utiliser les JNI qui permettent de charger dynamiquement une librairie statique dans un programme de type java. Ici se trouve le véritable intérêt de l’utilisation de Xlib pour notre projet. En effet il doit être faisable d’envoyer une simulation de touche à partir d’un programme java directement, sans passer par les commandes Xlib. Notre intérêt dans le projet a été de découvrir un maximum de point technique pour lors inconnu de chacune des personnes du groupe. L’utilisation des JNI étant ici possible, nous en avons saisis l’occasion. La technique est la suivante. Tout d’abords il faut écrire le fichier java qui chargera la bibliothèque et appellera les fonctions qui sont contenues à l’intérieure.
public class HelloWorld {
static {System.loadLibrary("HelloWorld");} //chargement de la bibliothèque
public static native void printCpp(); //declaration en static des fonctions
//continues dans la bibliothèque
public static void main(String args[]) {
HelloWorld.printCpp(); //appel de la fonction de manière classique
}
}
Compilé ensuite le code via la fonction javac. Cela fournira alors le .class de votre application java.
Grâce à la fonction javah nous allons pouvoir créer un fichier d’entête contenant l’ensemble des fonctions liées statiquement dans votre programme java, qui devrait se trouver dans la bibliothèque.
Un simple :
#javah HelloWord et voilà le résultat :
/* DO NOT EDIT THIS FILE ­ it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: printCpp
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_printCpp
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
Puisque nous chargeons une bibliothèque du nom de HelloWord nous obtenons un fichier du nom de : HelloWord.h. Il ne reste alors qu’à implémenter l’ensemble des fonctions déclarées dans le .h dans un fichier du nom de : HelloWord.cpp.
#include "HelloWorld.h" #include <iostream.h>
JNIEXPORT void JNICALL Java_HelloWorld_printCpp(JNIEnv *, jclass) {
// Un affichage sur la console en C++
cout << "Hello world in C++" << endl; }
Compiler notre application C++ grâce à la commande :
#g++ ­o libHelloWorld.so ­shared ­IvotreRep HelloWorld.cpp
Il ne reste plus alors qu’à lancer l’application java de manière habituelle et tout marchera bien.
Pour plus de renseignements techniques sur ce que sont les JNI, nous vous renvoyons vers la page suivante, qui détail toute la démarche pour ajouter du code JNI à vos applications.
http://www.infini­fr.com/Sciences/Informatique/Langages/Imperatifs/Java/jni.html
Téléchargement