:: Enseignements :: ESIPE :: E4INFO :: 2015-2016 :: Interface Graphique avec Android ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | ShareDraw |
L'objectif de ce projet est de réaliser une application Android proposant un
tableau blanc partagé en réseau entre différents utilisateurs.
Le projet est à rendre en deux fois :
-
La documentation de votre projet est à rendre le mercredi 18 mai sur la
plateforme e-learning.
-
Et votre projet sera récupéré lors de la soutenance et déposé
ici.
Fonctionnement
Tout d'abord l'application doit offrir à l'utilisateur la possibilité soit
de créer un nouveau tableau blanc, soit de rejoindre un tableau existant.
Il doit donc être possible de récupérer, à partir du serveur, une liste de
tableaux blancs en cours d'utilisation. Chaque tableau blanc est identifié
par un nom unique (l'unicité est garantie par le serveur). Une recherche
par nom de tableau doit pouvoir être réalisée.
Une fois le tableau rejoint, une activité permettant de le visualiser et
d'interagir avec lui est affichée. Cette activité permet d'autre part
d'afficher la liste de tous les participants de ce tableau avec la
capacité de discuter avec eux par messages textuels, un message pouvant
être adressé à un ou plusieurs utilisateurs simultanément.
Interface graphique
L'interface graphique est principalement constituée d'une activité
comportant plusieurs fragments :
-
un fragment d'affichage de la liste des utilisateurs du tableau
-
un fragment pour la visualisation et l'édition du tableau
-
un fragment comportant l'historique des messages de discussion offrant
également la possibilité d'envoyer un nouveau message (les destinataires
étant sélectionnés dans le fragment de la liste des utilisateurs)
Nous décrivons maintenant plus en détails le principal fragment permettant
l'affichage et la modification du tableau.
Fragment tableau
Ce fragment affiche le contenu du tableau. Le tableau occupe une aire
potentiellement illimitée : seule une portion de celle-ci est affichée.
Afin de naviguer sur le tableau, il est possible de translater la
portion affichée en maintenant deux doigts appuyés et en les déplaçant.
Deux doigts peuvent être aussi utilisés pour réaliser des gestes de
pincement permettant de changer l'échelle d'affichage du tableau (il est
possible d'utiliser une échelle arbitraire). Des bordures colorées en
limite de la portion affichée permettent de savoir si le tableau se
prolonge par du contenu à gauche, à droite, en bas ou en haut.
Une palette flottante (déplaçable) doit être affichée sur le tableau
afin de pouvoir sélectionner différents outils de tracés (ligne à main
levée, ligne droite, texte, polygone, ellipse...). On pourra proposer
des options de configuration accessibles depuis la palette pour ces
tracés (épaisseur de la ligne, couleur de la ligne, couleur de
remplissage...).
Capture et rejeu des dessins
Par défaut, les dessins réalisés dans un tableau devront être sauvegardés
par l'application. L'utilisateur sera ainsi capable de les rejouer
hors-connexion. Un slider permettra de se déplacer rapidement dans le
temps pour se rendre à l'état du tableau à un instant donné. Un format de
fichier spécifique devra être conçu pour l'enregistrement des captures qui
pourront être partagées par tout moyen (email, Bluetooth, réseau
social...) vers l'application d'un autre utilisateur.
Médium de communication
Idéalement, la communication entre les différents utilisateurs d'un
tableau doit être réalisée directement de socket à socket. Toutefois, il
est possible que la connectivité Internet des utilisateurs ne permette pas
un tel usage (notamment si les deux utilisateurs en communication sont
présents derrière un dispositif de NAT partageant une adresse IP publique
entre plusieurs internautes) ; la communication par l'intermédiaire d'un
serveur central paraît donc plus adaptée pour ce type de contexte.
Nous proposons ainsi un protocole de communication utilisant un serveur
web central avec une API de type REST. Ce serveur maintient un ensemble de
files de messages, une file de messages représentant un tableau blanc avec
l'historique de chaque tracé réalisé (un tracé étant représenté par un
message).
Le serveur web proposé est totalement agnostique pour le contenu des
messages: il se contente de gérer des queues de façon minimaliste. Nous
vous fournissons
une implantation simple du serveur web ici:
il s'agit d'un script Python 3 comprenant dans ses commentaires la
description des différentes requêtes REST supportées (trois commandes sont
supportées : lister les files représentant les tableaux, ajouter un
message dans une file et récupérer un message d'une file). Il est possible
si on le souhaite d'implanter soi-même un serveur proposant au moins les
mêmes fonctionnalités (mais vous ne serez pas évalué sur cette partie du
travail).
Les messages échangés avec le serveur utilisent un format JSON. Voici un
jeu de messages essentiels qu'il est obligatoire de supporter (mais il est
toujours possible d'ajouter de nouveaux messages pour implanter de
nouvelles fonctionnalités). Il est demandé de bien respecter le format de
ces messages essentiels afin d'assurer une interopérabilité entre les
différentes applications implantées (les coordonnées sont exprimées en
utilisant des flottants ; l'axe des abcisses est dirigé vers la droite,
l'axe des ordonnées vers le bas ; les coordonnées peuvent être négatives):
-
Indique que l'on rejoint un tableau blanc:
{
"admin": "join"
}
-
Indique que l'on quitte un tableau blanc:
{
"admin": "leave"
}
-
Trace une ellipse de centre (x, y) et de rayon radiusX sur l'axe des
abcisses et radiusY sur l'axe des ordonnées (si radiusX = radiusY, il
s'agit d'un cercle):
{
"draw": {
"shape": "ellipse",
"center": [x, y],
"radius": [radiusX, radiusY]
}
}
-
Trace un rectangle dont le coin supérieur gauche a pour coordonnées
(left, top) et le coin inférieur droit (right, bottom):
{
"draw": {
"shape": "rectangle",
"left": left,
"top": top,
"right": right,
"bottom": bottom
}
}
-
Trace une ligne comportant une succession de segments dont les
extrémités sont indiquées en coordonnées ; les coordonnées (xi, yi) sont
les coordonnées du début du segment i et de la fin du segment
i-1 ; si (x1, y1) = (xn, yn), la ligne est fermée:
{
"draw": {
"shape": "polyline",
"coordinates": [[x1, y1], [x2, y2], ..., [xn, yn]]
}
}
-
Permet d'écrire du texte (ici "Hello World!") à la position indiquée qui
représente le coin supérieur gauche du texte:
{
"draw": {
"shape": "text",
"position": [x, y],
"content": "Hello world!"
}
}
-
Permet d'adresser un message au destinataire "foo" (plusieurs
destinataires peuvent être indiqués en les séparant par des virgules, il
est possible aussi de ne pas spécifier de destinataire en n'indiquant
pas la clé "destination" ou alors en utilisant la valeur null ; le
message est alors envoyé à tous les membres du tableau):
{
"say": {
"content": "Message to say",
"destination": "foo"
}
}
Des options doivent être fournies pour les messages de type
draw
afin de préciser la façon dont sont dessinés les objets. On utilisera
alors:
{
"draw": {
...,
"options": { ... }
}
}
Le dictionnaire options peut contenir les entrées suivantes :
-
strokeWidth pour indiquer l'épaisseur du tracé du trait (sous
la forme d'un flottant)
-
strokeColor pour indiquer la couleur du trait (une liste de 4
entiers compris entre 0 et 255 pour le canal alpha et les trois
composantes primaires rouge, vert et bleu)
-
fillColor pour indiquer la couleur de remplissage du tracé
(couleur exprimée de la même façon que strokeColor)
-
fontSize pour indiquer la taille de la fonte utilisée pour
dessiner du texte
Par exemple si l'on souhaite d'abord tracer un rectangle de bordure noire
d'épaisseur 0.01 et de remplissage rouge, puis à l'intérieur un cercle de
bordure bleue d'épaisseur 0.02 et de remplissage transparent (canal alpha
à 0), nous transmettons les messages :
-
{
"draw": {
"shape": "rectangle",
"left": -1.0,
"top": -1.0,
"right": 1.0,
"bottom": 1.0,
"options": {
"strokeWidth": 0.01,
"strokeColor": [255, 0, 0, 0],
"fillColor": [255, 255, 0, 0]
}
}
}
-
{
"draw": {
"shape": "ellipsis",
"center": [0.0, 0.0],
"radius": [1.0, 1.0],
"options": {
"strokeWidth": 0.02,
"strokeColor": [255, 0, 0, 255],
"fillColor": [0, 0, 0, 0]
}
}
}
La machine peut subir momentanément des ruptures de connectivité ; dans
une telle situation, il est recommandé de laisser l'utilisateur continuer
à utiliser l'interface graphique de tableau blanc pour dessiner et
dialoguer. Les données seront alors envoyées dès que la connectivité aura
été rétablie. L'application cherchera également à récupérer les données
qu'elle n'aurait pas reçues.
La communication doit être maintenue tant que l'utilisateur participe au
tableau ; cette participation est donc toujours active même si l'activité
est en arrière-plan voir détruite. La communication doit donc être
réalisée par le biais d'un service qui relaiera le cas échéant les
messages à l'activité (et vice-versa) par la transmission d'Intent.
Améliorations
De nombreuses améliorations sont envisageables si les fonctionnalités
demandées ont déjà été correctement implantées. Voici quelques exemples:
-
Chiffrer les messages adressés personnellement avec les message
{ "say": ... } à certains utilisateurs du tableau. En effet,
le fonctionnement actuel du serveur consiste à communiquer tous les
messages d'une file en clair à tout utilisateur qui en ferait la
demande; le client a donc connaissance de la totalité des messages
échangés, y compris des messages privés.
-
Exporter le tableau blanc vers une image.
-
Importer une image dans le tableau blanc.
-
...
Documentation
Un rapport de développement au format PDF décrivant l'architecture globale
du projet ainsi que les principaux choix de développement devra être rendu
avec le projet. Un fichier README destiné aux utilisateurs devra être
également présent afin de décrire le fonctionnement de l'application ainsi
que sa compilation.
Feuille de route
Voici une liste de fonctionnalités à implanter par ordre de priorité pour
la bonne réalisation du projet:
-
Fonctionnement basique d'une vue pour le tableau blanc. Cette vue doit
être connectée à un modèle stockant les formes et doit être rafraîchie
lorsque le modèle évolue. On teste cette vue avec un seul type de forme
pour commencer.
-
Récupération des tracés des autres utilisateurs. Un service se charge de
contacter le serveur web central pour récupérer les tracés correspondant
à un tableau donné. Il envoie ces tracés à l'activité qui les rajoute
dans son modèle connecté à la vue d'affichage.
-
Envoi des tracés. Un listener enregistré sur le modèle provoque l'envoi
des tracés ajoutés localement vers le service qui lui-même les envoie
sur le serveur web. Le service communiquant avec le serveur web doit
pouvoir s'accomoder des pertes de connectivité.
-
Support du déplacement sur le tableau blanc. L'utilisateur doit pouvoir
déplacer la portion du tableau visualisée à l'écran.
-
Support de l'échelle sur le tableau blanc. Le zoom/dezoom à différentes
échelles doit être supporté.
-
Support de différentes formes pour le tracés. Il doit être possible de
dessiner des rectangles, ellipses, lignes... Les formes sont
sélectionnables sur une palette affichée sur le tableau (et déplaçable).
Le code est suffisamment modulaire pour pouvoir ajouter avec un moindre
effort une nouvelle forme.
-
Utilisation de fragments. Le tableau doit être affichable sous la forme
d'un fragment.
-
Support de la fonctionnalité de chat. Deux autres fragments doivent être
ajoutés pour afficher la liste des utilisateurs ainsi que la liste des
messages postés. Il doit être possible de poster un nouveau message et
recevoir les messages envoyés.
-
Sauvegarde en local du tableau. Un tableau doit être sauvegardable
localement sous la forme d'un fichier et exportable par bluetooth,
email, envoi sur un réseau social... Le tableau doit être consultable
hors-ligne avec un curseur permettant d'observer son état à un instant
donné.
-
Chiffrement des messages. Les messages privés sont chiffrés avec les
clés publiques des destinataires des messages ; chaque utilisateur
rejoignant un tableau pouvant intégrer dans son message "join" un champ
avec sa clé publique.
© Université de Marne-la-Vallée