Master E-Services Génie Logiciel et Interaction Homme-Machine PROJET UCAMPUS 2010-2011 SPADI Julien VAN HOEYMISSEN Thomas
TABLE DES MATIERES 1. L APPLICATION... 2 1.1 Objectif Principal... 2 1.2 Fonctionnalités présentes... 2 2. PHASE D ANALYSE... 2 2.1 Public visé... 2 2.2 Scénarios d utilisation... 3 3. PHASE DE CONCEPTION... 5 3.1 Diagramme de Use case... 5 3.2 Maquette... 6 3.3 Schéma de la base de données... 12 4. REALISATION... 13 4.1 Fonctionnement de notre application... 13 4.2 Difficultés rencontrées et résolution des problèmes... 19 5. FUTUR DE L APPLICATION... 21 5.1 Évolutions possible... 21 5.2 Problèmes à résoudre... 22 5.3 Préconisations... 22 6. BILAN DU TRAVAIL... 23 6.1 La question utile et utilisable... 23 6.2 Méthode de travail utilisée... 23 6.3 Apports personnels... 24 6.4 Bilan sur les technologies utilisées... 25 7. CONCLUSION... 27 8. ANNEXE... 28 1
1. L APPLICATION 1.1 OBJECTIF PRINCIPAL L objectif principal de l application est de permettre à l utilisateur de se repérer dans le campus de Lille 1. En effet, le campus étant assez grand, il est parfois un peu compliqué de trouver le lieu où l on doit se rendre, surtout si l on est un nouvel étudiant. Ainsi avec cette application appelée UCampus, l utilisateur est capable de se localiser sur le campus. 1.2 FONCTIONNALITES PRESENTES La liste des fonctionnalités présentes sur l application est la suivante : Se localiser Afficher les bâtiments d une catégorie donnée Recherche d un bâtiment sur le campus Itinéraire piéton ou en voiture vers un bâtiment du campus Navigation piéton ou en voiture via le GPS vers un bâtiment du campus Consulter la fiche détaillée de chaque bâtiment (Adresse, horaires, description) Appeler le bâtiment / Consulter son site internet. Consulter le menu du RU 2. PHASE D ANALYSE 2.1 PUBLIC VISE Avant de se lancer dans la conception de l application (base de données, interactions et maquettages écrans), nous nous sommes d abord demandé quelles fonctionnalités devraient être présentes de base dans notre application. Pour cela nous nous sommes demandé quel type d utilisateurs pourrait trouver notre application utile. Il s est dégagé ainsi quatre types de public vise. Tout d abord, l utilisateur qui arrive pour la première fois sur le campus de Lille 1. Il doit se rendre dans un bâtiment spécifique et étant donnée la taille du campus, il se retrouve un peu perdu. Il pourra ainsi, avec UCampus, se rendre où il le souhaite soit en voiture soit à pied. Vient ensuite l utilisateur qui est déjà habitué au campus de Lille 1 mais qui exceptionnellement doit se rendre dans un bâtiment dont il ignore l adresse. Il pourra s y rendre via UCampus. Ensuite, il y a l utilisateur qui est sur le campus depuis un temps assez conséquent qui a besoin d un renseignement sur un bâtiment particulier. Il peut alors via UCampus consulter les informations générales du bâtiment (horaires, adresse, ) mais également accéder à des fonctionnalités telles que l appel au bâtiment, 2
Finalement, il y a le professionnel qui se rend sur le campus pour par exemple donner un cours ou faire une intervention. Ainsi, avant sa venue, il est possible de lui demander de télécharger UCampus pour qu il puisse s y retrouver et donc, par exemple, ne pas arriver en retard. 2.2 SCENARIOS D UTILISATION Ensuite nous nous sommes fait une représentation sous forme de scénarios de l utilisation concrète de notre application. Voici 6 exemples d utilisation mettant en scène 3 acteurs différents qui n ont pas la même connaissance du campus : o Pierre est un étudiant en 3ème année de licence informatique à Lille 1 o o François est un étudiant en 1ère année de physique Émilie est une RH d Atos Worldline, elle ne connaît pas l université de Lille1 Appeler le SIUMPPS Pierre souhaite obtenir un rendez-vous avec un médecin. Pour cela il se connecte à l application UCampus, sur la page d accueil il clic sur Rechercher un lieu, puis sélectionne la catégorie Santé et le bâtiment SIUMPPS. Une fois arrivé sur la fiche détaillée, il consulte les horaires d ouverture puis sélectionne l onglet Complément d information. Dans cet onglet, il clic sur le bouton Appeler ce bâtiment. Il est ainsi mis en contact direct avec le service Inter-Universitaire de Médecine Préventive et de Promotion de la Santé de l'université Lille 1. Consulter le menu du Barrois Pierre souhaite consulter le menu de son restaurant universitaire préféré : Le Barrois. Pour cela il se connecte à l application UCampus, sur la page d accueil il clic sur Rechercher un lieu, puis sélectionne la catégorie Restaurants et le bâtiment Le Barrois. Une fois arrivé sur la fiche détaillée, il sélectionne l onglet Complément d information et clic sur le bouton Menu du RU. Le navigateur web de son smart phone se lance à la page du menu du Barrois. Visualiser tous les RU du campus François ne connaît pas bien l université de Lille 1, il souhaite savoir où sont situés tous les restaurants universitaire. Pour cela il se connecte à l application UCampus, sur la page d accueil il clique sur Maps, puis clic sur le bouton représenté par une loupe. La liste des catégories lui apparaît, il sélectionne la catégorie Restaurants et clic sur Restaurants : tous les bâtiments. S affiche alors à l écran l emplacement de chacun des restaurants universitaire de l université de Lille 1. 3
Visualiser l itinéraire piéton jusqu au Pariselle François s'aperçoit que le Pariselle est le restaurant universitaire le plus proche de lui. Il décide de s y rendre à pied. Sur la page de géolocalisation, il clic sur le bouton représenté par un panneau de signalisation avec une flèche et accède ainsi à la pop-up Itinéraire. Il renseigne la destination par Le Pariselle, le mode de déplacement par Piéton et clic sur le bouton Itinéraire. François est averti de la distance en kilomètres qui le sépare du Pariselle et l'itinéraire le plus rapide est dessiné en bleu sur la carte. Il lui ne reste plus qu à le suivre. Se rendre à la salle de sport Halle Vallin à pied François a rendez-vous avec Florent pour jouer au badminton dans la salle de sport Halle Vallin. Toutefois, il ne connaît pas du tout la route pour s y rendre. François se connecte à l application UCampus, sur la page d accueil, il clic sur Maps, puis sur le bouton représenté par un panneau de signalisation avec une flèche pour renseigner sa navigation. Il accède ainsi à la pop-up Itinéraire. Il renseigne la destination par Halle Vallin, le mode de déplacement par Piéton et clic sur le bouton Navigation. Le GPS Google navigation se lance et détermine le chemin à pied que François doit suivre pour arriver à destination. Se rendre en voiture au Sully Émilie est invitée dans le cadre d un projet de communication à participer à des simulations d entretiens qui ont lieu dans le restaurant universitaire du Sully. Lors de son invitation, le projet de communication lui a conseillé d utiliser l application UCampus pour venir. Pour cela elle se connecte à l application UCampus, sur la page d accueil, elle clic sur Rechercher un lieu, puis sélectionne la catégorie Restaurants et le bâtiment Le Sully. Une fois arrivé sur la fiche détaillée, elle sélectionne l onglet Localisation / Maps et clic sur le bouton Navigation Voiture. Le GPS Google navigation se lance et Émile n a plus qu à suivre les instructions du GPS pour arriver à bon port. Les scénarios ont pour but de montrer concrètement des cas d utilisation. Cependant il y a plusieurs façons d'accéder aux fonctionnalités. 4
3. PHASE DE CONCEPTION 3.1 DIAGRAMME DE USE CASE De ces scénarios d usage nous avons dégagé un diagramme de use cases (voir figure 1) afin de déterminer les enchaînements d actions possibles de notre application et afin de bien déterminer si notre application respectera les objectif attendus déterminés dans les scénarios d usages. En bleu sont représentés les états auxquels nous voulions arrivés dans nos scénarios. Figure 1: Diagramme de use case de l'application UCampus 5
3.2 MAQUETTE De cette phase d analyse, a découlé la conception de notre application. Après avoir déterminé les scénarios d usages nous nous sommes mis à faire la maquette de notre application afin de voir si toutes les possibilités décrites dans nos scénarios seraient bien réalisables dans notre application finale. Ainsi, à l aide l outil Balsmiq, nous avons réalisé la maquette de notre application. 3.2.1 La page d accueil Figure 2: La maquette de la page d'accueil de l'application UCampus Nous avons décidé de faire une page d accueil assez simple en termes de contenu d information (voir figure 2). Ainsi pour ne pas perdre l utilisateur, il n est possible de réaliser que deux actions possibles via les deux boutons. Nous avons aussi ajouté le logo de notre application sur cette page comme dans de nombreuses autres applications. 6
3.2.2 Partie Géolocalisation / Itinéraire : La map Figure 3 : La maquette de la page Maps de l'application UCampus Pour l aspect ergonomique de la page Maps (voir figure 3), nous nous sommes inspirés de l application mobile Google Maps car nous pensions qu elle était claire, ludique, pratique et intuitive. Nous avons essayés de garder et de mettre en œuvre ces caractéristiques. Cette page est composée de 2 parties : Partie haute : Une barre d onglet contenant 4 boutons : Afficher les catégories de lieu Définir un itinéraire Se géolocaliser Réinitialiser la carte. Partie centrale : La carte Google Maps permettant de géo localiser l utilisateur, d afficher les différents lieux et de le guider. 7
3.2.3 Partie Géolocalisation / Itinéraire : La pop-up d itinéraire et de navigation Figure 4 : La maquette de la pop-up d itinéraire et de navigation de l'application UCampus Cette pop-up (voir figure 4) permet de renseigner les données d un itinéraire : Départ : Position de l utilisateur Arrivée : Destination de l itinéraire Mode : Mode déplacement (Piéton ou Voiture) 2 boutons permettent de choisir le type d itinéraire : Navigation : Itinéraire via le GPS Itinéraire : Itinéraire statique (trait bleu sur la map) Lors de la conception des écrans nous avions ajoutés un bouton Annuler permettant de retourner à l écran de la carte. Toutefois, ce bouton a été enlevé lors du développement de UCampus car sur les applications Android il n y a pas de bouton annuler. Il faut utiliser le bouton retour du téléphone. 8
Nous avons choisi d utiliser une pop-up plutôt qu une nouvelle page car nous avons estimé que les informations présentés n étaient pas assez nombreuses pour remplir une page. 3.2.4 Partie Géolocalisation / Itinéraire : L affichage des informations sur la map Figure 5 : maquette de l affichage des informations sur la map de l'application UCampus Sur cette page (voir figure 5), on retrouve la position de l utilisateur, le ou les bâtiments que l utilisateur souhaite afficher et l itinéraire entre l utilisateur et un bâtiment de l université. Pour représenter l utilisateur nous avons utilisés la même icône que celle utilisée sur Google Maps. Les bâtiments sont représentés par une icône symbolisant la catégorie de ce bâtiment. Chaque icône doit être le plus explicite et reconnaissable possible. Nous souhaitions qu à partir de l icône du bâtiment avoir un accès rapide à la fiche détaillée du bâtiment. Afin de représenter l itinéraire piéton ou en voiture de l utilisateur vers un bâtiment, nous avons souhaités mettre à disposition de l utilisateur 2 outils : La navigation GPS. L itinéraire statique représenté par un trait bleu. 9
3.2.5 Partie Recherche de bâtiment : les listes de catégories et de bâtiments Figure 6 : maquette des listes de catégories et de bâtiments de l'application UCampus Afin d avoir une navigation simple et agréable, nous avons décidé de présenter les catégories et les bâtiments sous forme de liste (voir figure 6). Nous nous sommes inspirés du tutoriel «Personnaliser une ListView» proposé sur le site http://www.tutomobile.fr. La découverte de ce tutoriel a été très bénéfique dans l avancement de l aspect graphique de notre application (voir partie difficultés rencontrées et résolution des problèmes). Pour ne pas que l utilisateur se perde dans la recherche de bâtiment, le titre de la catégorie est toujours présent sur chaque liste de bâtiments. De plus nous avons décidé de mettre des icônes assez explicites pour chaque catégorie (un cuisinier pour la catégorie Restaurants Universitaires par exemple). 10
3.2.6 Partie Recherche de bâtiment : la fiche détaillée d un bâtiment Figure 7 : La maquette de la fiche détaillée d un bâtiment de l application UCampus La page représentant la fiche détaillée d un bâtiment est découpée en trois parties (voir figure 7) à savoir : La partie informations générales du bâtiment contenant l adresse, le numéro de téléphone, Le partie navigation et itinéraire La partie autre dans laquelle on peut trouver la possibilité d appeler le bâtiment par exemple Nous avons décidé d utilisé un système d onglet pour permettre de mieux structurer les parties. Ainsi la lisibilité est plus claire. De plus, le fait d utiliser des icônes dans les onglets permet un gain de place assez conséquent compte tenu du nombre d information à afficher dans la page. Ainsi, nous avons réussi à faire en sorte que l utilisateur n ait pas à scroller dans la fiche du bâtiment. 11
3.2.7 Menu Android Sur toutes les pages de UCampus, l utilisateur a accès en appuyant sur le bouton Menu de son téléphone à un menu lui permettant d accéder à différentes pages. Ce menu change selon la page où se trouve l utilisateur. S il est sur la page de Géolocalisation, le menu sera constitué de Lieux, Itinéraire, Effacer les résultats, Réglages et Plus. S il est sur la page d accueil, le menu sera constitué de Réglages et Plus. Sur toutes les autres pages, le menu sera constitué de Géo localisation, Accueil, Réglages et Plus. 3.3 SCHEMA DE LA BASE DE DONNEES Figure 8 : Le schéma de la base de données de l'application UCampus La base est séparée en deux partie (voir figure 8) car nous n avons besoin que de 2 objets à représenter à savoir d un côté les bâtiments présent sur le Campus et de l autre la catégorie de ce bâtiment afin de permettre un certain classement ou ordre dans la liste des bâtiments. La table BATIMENT contient les champs: ID_BAT : l identifiant unique pour chaque bâtiment auto-incrémenté (ici il s agit d une String mais nous avons fait en sorte que l auto-incrémentation se fasse quand même) NAME_BAT : le nom du bâtiment NUMERO_BAT : le numéro de téléphone du bâtiment HORAIRES_BAT : Les horaires d ouverture du bâtiment IMAGE_BAT : le chemin vers l image à afficher dans la fiche de description du bâtiment LATITUDE_BAT : la latitude du bâtiment (utilisée pour la géolocalisation) 12
LONGITUDE_BAT : la longitude du bâtiment (utilisée pour la géolocalisation) SITEINTERNET_BAT : le lien vers le site internet du bâtiment pour avoir plus d informations ID_CAT : l identifiant de la catégorie à laquelle le bâtiment appartient La table CATEGORIE contient quant à elle les champs : ID_CAT : l identifiant unique pour chaque catégorie auto-incrémentée NAME_CAT : le nom de la catégorie ICON_CAT : le chemin vers l'icône représentant la catégorie Comment ajouter une catégorie de bâtiment et un bâtiment? Pour le moment, l ajout de bâtiment et de catégorie doit se faire directement dans le code source mais cela pourra et surtout devra être modifié en passant par un parser xml par exemple (voir partie amélioration). Ainsi, afin de rajouter un bâtiment dans la base, il suffit de se rendre dans la classe InsertBDD et d y ajouter d abord une catégorie en créant un objet catégorie et en l insérant dans la base de données, puis pour ajouter un bâtiment il faut créer l objet bâtiment et l insérer dans la base de données en prenant bien en compte l identifiant de la catégorie créée auparavant (l identifiant est généré dans l ordre des insertion dans la base en partant de 1). Il faut bien évidemment veiller à fermer les connections à la base de données après. Pour que la nouvelle catégorie soit prise en compte dans la partie géolocalisation, il faut ajouter une icône qui représentera la catégorie et créer 2 objets dans la classe Geolocaliasation.java: MyItemizedOverlay qui contiendra les lieux à afficher pour cette catégorie Drawable qui correspond à l icône qui sera affichée pour cette catégorie Voir annexe : Tutorial Créer une catégorie de bâtiment 4. REALISATION 4.1 FONCTIONNEMENT DE NOTRE APPLICATION Nous allons vous présenter les écrans de notre application UCampus ainsi que leurs fonctionnalités sous forme de zones de texte présentant les actions réalisées en via cet élément. 13
1 2 Figure 9 : La page d'accueil de UCampus 1 : Ouvre les fonctionnalités de géolocalisation 2 : Ouvre la fonctionnalité de recherche de lieu dont la première page 1 2 Figure 10 : La page de géolocalisation de UCampus Lors d un clic sur le bouton Maps de la page d accueil, l utilisateur est géolocaliser sur la carte. 1 : Barre d onglets permettant de rechercher un lieu, un itinéraire, de se géolocaliser et de réinitialiser la carte 2 : Position de l utilisateur 14
1 2 3 Figure 11 : Pop-up itinéraire Cette pop-up s ouvre lors d un click sur le deuxième élément de la barre d onglets. 1 : Destination de l itinéraire : Auto compression à partir d une lettre saisie par l utilisateur 2 : Mode de déplacement Piéton ou Voiture 3 : Choix du mode de l itinéraire : Via le GSP (Navigation) ou statique (Itinéraire) Figure 12 : Représentation de l itinéraire Une fois l itinéraire renseigné et un clic sur le bouton Itinéraire de la pop-up précédente, un trait bleu représente l itinéraire le plus rapide en distance vers le lieu choisi. 15
1 Figure 13 : La liste des catégories de l'application UCampus Lors d un clic sur le bouton Rechercher un lieu de la page d accueil, la liste des catégories de lieux est proposé à l utilisateur. 1 : Ouvre la liste des bâtiments contenus dans la catégorie choisie 1 2 Figure 14 : La liste des bâtiment correspondants à une catégorie de l'application UCampus Lorsque l utilisateur choisi une catégorie de lieux, les bâtiments de cette catégorie s affichent. 1 : Ouvre la fiche détaillée du bâtiment sélectionné 2 : Affiche sur la map tous les bâtiments de la catégorie choisie 16
Figure 15 : Tous les restaurants universitaires de Lille 1 Si l utilisateur a cliqué sur l écran précédent sur tous les bâtiments, la carte contient tous les bâtiments de cette catégorie. Ces bâtiments sont représentés par l icône de la catégorie. 1 2 Figure 16 : La partie informations générales de la fiche détaillée d'un bâtiment de l'application UCampus Si l utilisateur a cliqué sur l écran précédent sur un bâtiment, il accède à sa fiche détaillée. 1 : Ouvre la partie géolocalisation de la fiche détaillée 2 : Ouvre la partie Complément d information de la fiche détaillée 17
1 2 3 4 5 Figure 17 : La partie Localisation/Maps de la fiche détaillée d'un bâtiment de l'application UCampus Ouverture de l onglet Localisation/Maps de la fiche détaillée. 1 : Affiche le bâtiment sur la map 2 : Affiche l itinéraire à pied vers le bâtiment sur la map 3 : Affiche l itinéraire en voiture vers le bâtiment sur la map 4 : Ouvre le service de Google Navigation en mode piéton vers le bâtiment 5 : Ouvre le service de Google Navigation en mode voiture vers le bâtiment 1 2 Figure 18 : La partie Complément d'information de la fiche détaillée d'un bâtiment de l'application UCampus Ouverture de l onglet Complément d information de la fiche détaillée. 1 : Appel le bâtiment 2 : Affiche le menu (ou le site internet) du bâtiment dans un navigateur web 18
1 2 Figure 19 : Le menu de la fiche détaillée d'un bâtiment de l'application UCampus 1 : Affiche la map centrée sur ma position 2 : Affiche la page d accueil Les autres éléments du menu sont en construction. 4.2 DIFFICULTES RENCONTREES ET RESOLUTION DES PROBLEMES 4.2.1 Difficultés communes Lors de ce projet, nous avons rencontrés de nombreuses difficultés notamment liées au langage de programmation Android. En effet, c était la première fois que nous travaillions sur un projet Android. Nous avons consultés de nombreux sites, forums, tutoriels et cours pour parvenir à développer UCampus. Le site le plus utilisé à était http://developer.android.com. La principale difficulté commune que nous ayons rencontrée s est portée sur l aspect graphique, la mise en page, le placement des boutons, comment déterminer les tailles des objets,. Pour résoudre en partie ce problème, Julien a trouvé un logiciel (DroidDraw) qui permet par Drag and drop de faire de la mise en page sous Android et d obtenir le code XML généré. Toujours concernant l affichage et la mise en page de l application, Thomas a trouvé un tutoriel permettant de faire un affichage plutôt ergonomique des listes de catégories et de bâtiment. Ce qui nous a permis de comprendre un peu plus les principes des fichiers xml utilisé dans le développement des interfaces graphiques sous Android. Nous nous sommes aussi rendu compte que certaines actions comme la navigation par exemple prenaient du temps à se lancer. L utilisateur ne sait pas si l action a bien été enclenchée. Nous avons donc décidé d ajouter une vibration à chaque pression de l utilisateur afin qu il ait un feedback immédiat. 19
Le dernier problème commun que nous avons rencontré était lié à la clé Google map nécessaire à l utilisation de la carte. En effet, pour utiliser la carte proposée par Google, il est obligatoire de générer une clé Google map propre à chaque ordinateur où le projet est compilé. Étant donné que l on travaillait à deux sur le projet et que l on utilisait SVN, il fallait chacun générer une clé Google map correspondant à son poste. Nous avons ainsi crée un fichier ( clegooglemap.txt) qui contient la clé de chaque poste où le projet a été compilé. 4.2.2 Difficultés rencontrées par Thomas D un point de vue technique, les fonctionnalités liées à la géolocalisation (navigation, localisation et itinéraire) m ont posées le plus de problèmes. J ai suivi différents tutoriels (http://developer.android.com/resources/tutorials/views/hellomapview.html;http://mobiforge.com/developing/story/using-google-maps-android) pour développer ses fonctions. J ai également utilisé des fonctions développées par d autres développeurs comme la fonction qui permet de déterminer la distance entre sa position et un lieu et la fonction qui permet de mettre à jour sa position. En ce qui concerne le guidage de l utilisateur, j étais parti sur un guidage uniquement via la carte. En mettant à jour le trait de l'itinéraire à chaque modification de sa position. Toutefois, je me suis rendu compte que cette façon allée être trop fastidieuse et pas assez efficace. De plus Google proposant un outil de navigation GPS (Google Navigation) intégrée au smart phone, nous avons décidés de l utiliser. Ainsi, l utilisateur peut soit tracer un itinéraire fixe soit utiliser un GPS pour se déplacer. D un point de vue fonctionnel, ce qui m a pris le plus de temps a été de placer les bâtiments sur la carte en récupérant les coordonnées GPS (latitude et longitude) via Google Maps. J avais donc d un côté la carte de l université de Lille1, d un autre coté cette même vue sur Google map mais sans tous les bâtiments. 4.2.3 Difficultés rencontrées par Julien Un de mes principaux soucis dans cette application était de créer une base de données et d y faire les actions principales telles que l insertion et l accès aux données présentes dans cette dernière. Après avoir consulté quelques tutoriels, je me suis penché sur un en particulier (Comment utiliser SQLite sous Android disponible sur le site http://www.tutomobile.fr). Ainsi, j ai pu découvrir comment créer et administré une base de données sous Android en utilisant la technologie SQLite. J ai choisi cette technologie car elle est intégrée de base à l OS Android, de plus je n ai pas trouvé d autre technologie disponible pour effectuer la gestion des données. Ensuite, j ai remarqué qu à chaque démarrage de l application, toutes les catégories et les bâtiments étaient chargés une fois de plus dans la base de données. En fait, je chargeais la classe d insertion dans la base à chaque appel à l application. Ainsi, la base se retrouvait pleine de doublons. Pour pallier à ce problème, j ai fait en sorte que s il s agit du premier chargement de l application (i.e. si la base est vide), la classe d insertion en base s occupe de 20
nourrir la base de données. En revanche, si l application et déjà installée et qu il il y a donc des données présentes en base alors rien n est inséré. Finalement, dans les listes de recherche, il y a une icône représentant chaque type de catégories et de bâtiment. Ces icônes m ont posées quelques problèmes car elles étaient directement intégré au projet.apk et non pas sur la carte SD du téléphone. Pour faire simple, elles étaient déjà compilées dans le projet. Ainsi, il m était impossible de récupérer l image directement en faisant appel à la méthode createfrompath(string pathname) qui est proposée dans la documentation d Android et qui permet de créer l objet Drawable (Image) correspondant à l image se trouvant dans le pathname. De plus, chaque catégorie dispose de sa propre icône dont il faut aller chercher le nom dans la base de données. Il fallait donc trouver un autre moyen pour créer cette icône en fonction de la catégorie. Après quelques recherches sur les forums dédiés au développement mobiles, j ai trouvé la solution en utilisant la méthode permettant de récupérer l identifiant de l image compilé. Il suffisait ensuite de faire correspondre cette identifiant à l objet Drawable à afficher. 5. FUTUR DE L APPLICATION 5.1 ÉVOLUTIONS POSSIBLE Nous avons réfléchis à des pistes d évolutions qui permettraient d enrichir UCampus. 4 catégories regroupent ces pistes d évolution: 5.1.1 Elargir les cibles potentielles Tout d abord, il serait intéressant d ajouter un module de reconnaissance vocale pour permettre à des personnes déficientes visuelles d utiliser l application. De plus, étant donné que l Université Lille 1 accueille chaque année plus de environ 4000 étudiants internationaux, ce qui représente plus de 20% de la population totale des étudiants, proposer à l utilisateur le choix de la langue peut être très utile. 5.1.2 Faciliter la navigation au sein de UCampus Si l utilisateur connaît le nom du bâtiment dont il souhaite avoir des informations, il serait utile d ajouter une fonction de recherche du bâtiment dès la page d accueil. De plus, nous pensons que la géolocalisation peut être améliorée dans le sens où l utilisateur définit la catégorie de lieux et demande le bâtiment de cette catégorie le plus proche de lui. Par exemple, l utilisateur se situe au M5 et souhaite savoir quel est le restaurant universitaire le plus proche. Des évolutions liées à la fiche détaillée d un bâtiment telles que l intégration du menu du restaurant universitaire et l ajout d une photo représentant le bâtiment sont parfaitement envisageable. 21
5.1.3 Données de UCampus A l heure actuelle, la base de données de UCampus contient 3 catégories de lieux (Restaurant, Santé et Salle de sport) et 7 bâtiments. Pour optimiser son utilisation, il est nécessaire d enrichir la base de données par des catégories de lieux et par des bâtiments. De plus, le mode de base de données actuellement mis en place est propre à chaque smart phone, c est à dire que la base de données est embarquée dans le mobile. Ce qui implique qu à chaque modifications de la base de données il est nécessaire de re-télécharger l application. Pour remédier à ce problème il faut utiliser une base de données externe hébergée sur un serveur. 5.1.4 Ajout de nouvelles fonctionnalités Il est envisageable d enrichir UCampus par des services utiles à chaque étudiants. On peut imaginer intégrer une boite mail pour les mails de la Fac, un agenda de ses cours ou même gérer ses cartes (étudiante, bibliothèque, Crous). Une version widget de UCampus, permettrait un accès plus rapide à une des fonctionnalités de l application car il est accessible directement via le bureau de son smart phone. Par exemple ce widget pourrait servir à récupérer le numéro de téléphone d un bâtiment. Il s agit en fait de déterminer quelle est la fonctionnalité la plus utilisée sur UCampus et d en faire un widget. 5.2 PROBLEMES A RESOUDRE Sur la version présentée il reste quelques problèmes mineurs à réglés. Lorsqu un utilisateur souhaite connaître l'itinéraire vers un lieu, un trait bleu est dessiné sur la carte Google map. Si l utilisateur effectue un nouvel itinéraire, le trait de l ancien itinéraire reste. Pour effacer le trait d un itinéraire, il est nécessaire de soit cliquer sur le bouton Réinitialiser soit d afficher un lieu sur la carte. Il est également possible pour un utilisateur de ne pas utiliser la 3G et le GPS lorsqu il est sur la page de géolocalisation. En effet, le contrôle de l activation de ces deux outils est effectué lors de l accès à la page de géolocalisation. Si l utilisateur quitte l application et y retourne, il arrivera directement où il était lors de la fermeture de l application. Ainsi, il peut très bien arriver sur l écran de géolocalisation sans avoir réactivé son GPS et sa 3G. Il serait donc judicieux de tester si la 3G et le GPS sont actifs à tout moment. Il faudrait également intégrer dans le modèle de données une partie description du bâtiment afin de pouvoir intégrer plus d informations sur le bâtiment et aussi permettre une meilleure mise en page du premier onglet de la fiche produit. 5.3 PRECONISATIONS Afin d utiliser UCampus dans des conditions optimales, nous préconisons son utilisation en extérieur. Ceci afin de permettre une géolocalisation plus rapide et surtout plus précise. Le GPS étant plus précis en extérieur. 22
Si la géolocalisation ne fonctionne pas correctement, il est conseillé de se géolocaliser avec Google Maps et de revenir sur UCampus. 6. BILAN DU TRAVAIL 6.1 LA QUESTION UTILE ET UTILISABLE Nous avions un objectif lors dans la réalisation de cette application. En effet, il fallait qu elle soit utile et utilisable. Les différents publics visés sont déjà un argument permettant de montrer que notre application est utile. En effet, le fait d avoir catégorisé des types d utilisateurs rend cette application utile car chaque type trouvera une utilité à UCampus. De plus, le fait que de nombreuses fonctionnalités soient présentes renforce l argumentation sur l utilité de notre application. En effet, UCampus dispose de fonctionnalités qui permettent à l utilisateur de trouver ce qu il cherche, si bien évidemment il sait ce que l application permet de faire. L utilisabilité de notre application réside dans l IHM. En effet, nous avons voulu une ergonomie assez claire. De plus nous voulions que l utilisateur n ait pas trop d actions à faire pour arriver à ce qu il cherche. Nous nous sommes aussi appuyer sur des APIs qui ont déjà été approuvées par de nombreux utilisateurs comme Google Maps et Google Navigation. Ainsi, nous sommes persuadés que les parties utilisant ces APIs sont utilisables. Nous avons évalué les caractères utile et utilisable de UCampus grâce à une expérimentation utilisateur. Pour cela nous avons fait manipuler l application par un ensemble de «sujets». Au début, nous souhaitions que les «sujets» ne soient pas des étudiants de la formation E- services afin d avoir des avis les plus neutres possibles. Toutefois, dans un souci de respect des délais nous avons fait tester UCampus à des étudiants en E-services. Le retour a été positif cependant étant donnée le type de sujet (informaticien), nous n avons pas pu avoir une idée précise sur l utilité et l utilisabilité de UCampus. Il aurait été nécessaire d élargir les types de «sujet» par rapport à la nationalité, à l âge, au sexe et à la formation scolaire de l utilisateur. 6.2 METHODE DE TRAVAIL UTILISEE Nous avons consacré les deux premières séances de projet au listing des fonctionnalités à développer au sein de UCampus. Trois parties ce sont dégagées : Géolocalisation Base de données Mise en page Nous nous sommes ainsi répartis ces trois parties. Thomas a travaillé sur l aspect géolocalisation et Julien sur la partie base de données et mise en page. Ces parties n étant pas étroitement liées nous avons pu travailler chacun de notre côté et facilement intégrer le développement de l un et l autre grâce à l utilisation d un SVN. Nous avons également mis à jour la forge mis à notre disposition, afin de tenir informer de notre avancement. 23
Nous nous étions fixés 3 jalons : JALON : 1ERE VERSION UCAMPUS (12/20/10) o La première version de l'application doit permettre de : Se géolocaliser Localiser sur la carte les restaurants universitaires de Lille 1 Se rendre via un itinéraire piéton ou voiture vers un des restaurants universitaires de Lille 1 (Google Navigation - Google Maps) Consulter les informations de chaque restaurant universitaire (Nom, adresse, horaires, menu, téléphone) JALON : AJOUT DE NOUVEAUX LIEUX - RECONNAISSANCE VOCALE (01/11/11) o Enrichissement des lieux : o Bâtiments de cours informatiques Bâtiments administratifs Salles de sport Intégrer la reconnaissance vocale JALON : VERSION LIVRABLE (01/25/11) o Cette version doit contenir des données réelles. Permettre à un utilisateur d'utiliser toutes les fonctionnalités de l'application. Comme on peut le constater sur la version présentée le 25/01/2011, les jalons n ont pas été exactement respectés. En effet, au cours du projet nous nous sommes rendu compte que la fonctionnalité de reconnaissance vocale était secondaire et surtout très compliqué à mettre en place. De plus cette fonction était développée par un autre groupe et ils ne savaient pas encore comment la mettre en place. Ce qui nous a permis de nous concentrer sur le développement des fonctionnalités primordiales (navigation, recherche, appel). En ce qui concerne l enrichissement des lieux, nous avons préférés ajouter des catégories où nous étions capables de renseigner tous les bâtiments de cette catégorie. De plus, étant donné qu il s agit d une version de présentation nous avons souhaité mettre en valeur les fonctionnalités plutôt que la quantité de données. 6.3 APPORTS PERSONNELS 6.3.1 Thomas Dés l annonce des sujets de GLIHM, j ai tout de suite été attiré par UCampus car il permettait de mettre en perspective les enseignements reçus cette année dans le cadre d un projet professionnel. Au commencement du projet, je n avais jamais développé en Android. Ce projet m a permis d apprendre le langage de développement Android. Etant en alternance chez Atos Worldline dans le département Télécom Utilities Media, cette compétence me sera très utile car les plans directeurs sont orientés applications mobiles Android/Iphone. Grâce à ce projet, je me sens capable de développer des applications Android. 24
De plus, le fait de travailler en équipe est très enrichissant : échanges, entraides, confrontations des opinions, apprentissage au contact des autres et cohésion d équipe. Ces différentes compétences sont de plus en plus recherchées par les entreprises. Le projet UCampus, ne se limitait pas uniquement au développement d une application mobile mais comprenait les phases d analyse, de conception, de maquettage, de développement et de suivi. Le fait de pouvoir gérer ces différentes phases du projet était important pour moi car elles font parties intégrante de notre vie professionnelle. Finalement, ce projet m a permis d accroitre mes compétences techniques et relationnelles, d enrichir mon CV et d avoir de nombreuses idées d application mobile. 6.3.2 Julien Tout d abord, le fait de développer une application «from scratch» est l un des apports personnels le plus intéressant. En effet, le fait de pouvoir choisir soi-même les fonctionnalités présentes dans l application, de pouvoir choisir comment les mettre en place, de pouvoir choisir la mise en page et le design, m a permis de m investir du début jusqu à la fin du développement de l application. Il y a une certaine «fierté» de concevoir et de développer une application en partant de rien. De plus, mon attrait pour les nouvelles technologies m ayant poussé à choisir ce sujet, je n ai pas été déçu de l apprentissage du développement sous Android. Je me sens maintenant assez à l aise dans ce domaine. Je n hésiterais pas à développer de nouvelles applications sous Android si l opportunité se présente. L expérience a été tellement intéressante qu elle m a fait changer de téléphone portable passant d un IPhone à un téléphone Android. Le fait que le développement soit en Java ayant aussi aidé car je ne me suis pas senti perdu en terme de langage de développement. Finalement, le fait d avoir eu à disposition des outils tels que le SVN a été bénéfique car cela à simplifier notre manière de travailler en ensemble. Nous avons pu ainsi bien séparer les tâches et toujours avoir la dernière version de notre application sur nos téléphones. Ceci permettant de détecter les éventuels bugs et de les corriger immédiatement. 6.4 BILAN SUR LES TECHNOLOGIES UTILISEES 6.4.1 Android Android est un système d'exploitation open source pour smart phones, PDA et terminaux mobiles conçu par Google. Il s agit également d un langage de programmation basé sur le JAVA et sur le XML. Le JAVA permet d'interagir avec l utilisateur en faisant la liaison entre l interface graphique et la base de données. Quant au XML, il permet notamment de décrire les interfaces graphiques. UCampus a été développé pour la version 2.1 d Android baptisé Eclair. Toutefois, UCampus, est utilisable sur la version 2.2 et sur les versions antérieures d Android. Le fait que le langage utilisé pour le développement sous Android soit du Java permet à des étudiants comme nous de prendre assez facilement en main un projet Android. En effet, nous avons tous au moins 3 ans de développement Java derrière nous. De plus la documentation sur 25
le site d Android est vraiment complète et enrichie de nombreux exemple qui permettent de mieux comprendre certaine subtilités. Cependant la partie affichage graphique est assez compliquée à maîtriser. 6.4.2 DroidDraw DroidDraw est un éditeur wysiwyg (What You See Is What You Get) disponible sur Windows, Mac et Linux. Grace au drag and drop il est possible d assembler les différents éléments de l application. Une fois l interface terminée un fichier xml est généré. DroidDraw a été particulièrement utilisé pour la fiche détaillé d un bâtiment. DroidDraw est tout de même limité en termes de développement pur et dur, il faut envisager son utilisation comme une aide au développement de l interface utilisateur plus qu un générateur de code. Bien qu il s agisse d un outil bien utile pour le développement d IHM sous Android pour ce genre de projet, il est clair qu il n est pas encore assez abouti pour être utilisé à grande échelle. Nous l avons surtout utilisé pour pouvoir faire des LinearLayout que nous avons ensuite intégrer aux fichiers xml présent dans le dossier layout du projet. L intérêt pour nous était de pouvoir développer des IHMs assez simples. 6.4.3 SQLite SQLite est une bibliothèque écrite en C qui propose une base de données accessible par du langage SQL. Il est intégré de base à l OS Android. 6.4.4 Balsamiq Balsamiq est un outil qui permet de faire du mock-up, c'est à dire de maquetter un site ou une application mobile, assez simplement. Nous avons utilisé la version gratuite online car elle présentait les principaux éléments qui nous intéressaient pour maquetter notre application comme par exemple des boutons, des onglets, Balsamiq est un outil assez puissant car il permet en quelques clics d avoir une représentation très concrète de l application finale. De plus le rendu final de la maquette au design crayonné est assez beau. Pour aller plus loin dans le mock-up, nous nous sommes demandé s il existait un outil qui permettait d avoir une version dynamique de la maquette faite avec Balsamiq. Nous avons trouvé cet outil : Napkee. Cependant, nous ne l avons pas utilisé dans le cadre de ce projet. De plus, il n y a qu une version d essai de 45 jours, la version complète coûtant 45 dollars. 26
7. CONCLUSION Nous avons donc passé environ six mois à analyser, concevoir et développer cette application. De ce projet, nous ne pouvons retirer que des éléments bénéfiques. Nous sommes maintenant à l aise avec le développement Android, nous avons découvert des outils pour la conception d application, trouver des moyens de résoudre certains problèmes, Nous sommes contents d avoir pu mettre ce projet en place. Nous estimons, bien qu il y ait encore des problèmes à résoudre, que les bases de cette application sont présentes et qu il sera aisé de les améliorer. 27
8. ANNEXE TABLE DES MATIERES DE L ANNEXE 1. PARTIE XML AFFICHAGE... 30 1.1 main.xml : page d accueil... 30 1.2 catlist.xml : page d affichage de la liste des bâtiments... 30 1.3 batlist.xml : page d affichage de la liste des bâtiments... 30 1.4 affichageitem.xml : élément s affichant dans les listes... 31 1.5 viewbatiment.xml : page d affichage de la fiche détaillée... 32 1.6 geolocalisation.xml : affichage de la page de géolocalisation... 37 1.7 balloon_overlay.xml : overlay sur la map... 38 1.8 itineraire.xml : pop-up sur la map... 39 1.9 phonebutton.xml : exemple d un image button personnalisé... 40 2. COUCHE MODELE... 40 2.1 Batiment.java : classe représentant l objet Bâtiment... 40 2.2 Catégorie.java : classe représentant l objet Catégorie... 43 3. COUCHE DAO... 44 3.1 BatimentDataBase.java : création de la base de bâtiment avec SQLite... 44 3.2 CategorieDataBase.java : création de la base de catégorie avec SQLite... 45 3.3 BatimentDAO.java : connexion et CRUD sur la base des bâtiments... 46 3.4 CategorieDAO.java : connexion et CRUD sur la base des catégories... 50 4. COUCHE UTILITAIRES... 52 4.1 InsertBDD.java : classe d insertion dans lma base... 52 5. COUCHE ANDROID... 54 5.1 Home.java : la page d accueil... 54 5.2 CatList.java : page de listing des catégories... 57 5.3 BatList.java : page de listing des bâtiments... 59 5.4 ViewBatiment.java : fiche détaillée du bâtiment... 62 5.5 Geolocalisation.java : Geolocalisation via Google Maps... 78 5.6 MyItemizedOverlay.java : Contient les Overlay d une catégorie... 91 5.7 BalloonItemizedOverlay.java : Apparait lors d un click sur un bâtiment... 92 5.8 BalloonOverlayView.java : Représente le marker lors d un click sur un bâtiment... 96 28
5.9 MyOverLay.java : Représente une superposition sur la carte... 98 6. TUTORIAL... 101 6.1 Créer une catégorie de bâtiment... 101 29
1. PARTIE XML AFFICHAGE 1.1 MAIN.XML : PAGE D ACCUEIL <?xml version="1.0" encoding="utf-8"?> <!-- Page d'accueil --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <RelativeLayout android:id="@+id/relativelayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/top" android:gravity="top"> </RelativeLayout> <!-- bouton pour lancer la map --> <Button android:id="@+id/localisationhome" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/localisation" android:layout_margin="50px" android:background="@drawable/custombutton" android:textcolor="#ffffff" android:textsize="11pt"/> <!-- Bouton pour rechercher un batiment --> <Button android:id="@+id/searchhome" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/search" android:layout_margin="50px" android:background="@drawable/custombutton" android:textcolor="#ffffff" android:textsize="11pt"/> </LinearLayout> 1.2 CATLIST.XML : PAGE D AFFICHAGE DE LA LISTE DES BATIMENTS <?xml version="1.0" encoding="utf-8"?> <!-- Page de la liste des catégories de batiment --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="wrap_content" android:layout_margintop="15px" android:layout_marginbottom="15px" android:layout_height="wrap_content" android:text="catégories" android:layout_gravity="center_horizontal" android:textsize="18px" /> <ListView android:id="@+id/listviewcategories" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> 1.3 BATLIST.XML : PAGE D AFFICHAGE DE LA LISTE DES BATIMENTS <?xml version="1.0" encoding="utf-8"?> <!-- Page d'accueil --> 30
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <RelativeLayout android:id="@+id/relativelayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/top" android:gravity="top"> </RelativeLayout> <!-- bouton pour lancer la map --> <Button android:id="@+id/localisationhome" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/localisation" android:layout_margin="50px" android:background="@drawable/custombutton" android:textcolor="#ffffff" android:textsize="11pt"/> <!-- Bouton pour rechercher un batiment --> <Button android:id="@+id/searchhome" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/search" android:layout_margin="50px" android:background="@drawable/custombutton" android:textcolor="#ffffff" android:textsize="11pt"/> </LinearLayout> 1.4 AFFICHAGEITEM.XML : ELEMENT S AFFICHANT DANS LES LISTES <?xml version="1.0" encoding="utf-8"?> <!-- fichier qui permet de représenter une ligne dans la liste des catégories et des bâtiments --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10px" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingleft="10px" android:layout_weight="1" > <TextView android:id="@+id/titre" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textsize="16px" android:textstyle="bold" /> <TextView android:id="@+id/description" 31
android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> </LinearLayout> 1.5 VIEWBATIMENT.XML : PAGE D AFFICHAGE DE LA FICHE DETAILLEE <?xml version="1.0" encoding="utf-8"?> <!-- Page d'un batiment --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <!-- Le conteneur d'onglets --> <TabHost android:id="@+id/tabhost01" android:layout_height="fill_parent" android:layout_width="fill_parent"> <LinearLayout android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent"> <!-- Le contenu des onglets --> <TabWidget android:id="@android:id/tabs" android:layout_height="wrap_content" android:layout_width="fill_parent"> </TabWidget> <FrameLayout android:id="@android:id/tabcontent" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_marginleft="15px" android:layout_marginright="15px"> <!-- Onglet info générale --> <LinearLayout android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent" android:scrollbars="vertical" android:id="@+id/general_info"> <TextView android:layout_width="wrap_content" android:layout_margintop="15px" android:layout_marginbottom="15px" android:layout_height="wrap_content" android:text="informations Générales" android:layout_gravity="center_horizontal" android:textcolor="#000000" android:textsize="18px" /> <TextView android:id="@+id/name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="name" android:textcolor="#000000" /> <TextView android:id="@+id/numero" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="numero" android:textcolor="#000000" /> <TextView android:id="@+id/ouverture" android:layout_width="fill_parent" android:layout_height="wrap_content" 32
33 android:text="ouverture" android:textcolor="#000000" /> <TextView android:id="@+id/adresse" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="adresse" android:textcolor="#000000" /> </LinearLayout> <!-- Onglet maps --> <LinearLayout android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent" android:scrollbars="vertical" android:id="@+id/loc_maps"> <!-- Titre localisation Map --> <TextView android:id="@+id/loctext" android:layout_width="wrap_content" android:layout_height="40px" android:text="localisation / Maps" android:layout_alignparenttop="true" android:gravity="center" android:layout_gravity="center_horizontal" android:textcolor="#000000" android:textsize="18px"> </TextView> <!-- localiser --> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageButton android:id="@+id/localise" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10px" android:src="@drawable/locbutton" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingleft="10px" android:layout_weight="1"> <TextView android:id="@+id/loc" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textsize="16px" android:textstyle="bold" android:text="localiser" android:textcolor="#000000" /> </LinearLayout> </LinearLayout> <!-- itineraire piéton --> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android"
34 android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageButton android:id="@+id/itinerairepieton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10px" android:src="@drawable/pietonbutton" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingleft="10px" android:layout_weight="1"> <TextView android:id="@+id/itinerairepietontext" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textsize="16px" android:textstyle="bold" android:text="itinéraire Piéton" android:textcolor="#000000" /> </LinearLayout> </LinearLayout> <!-- itineraire voiture --> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageButton android:id="@+id/itinerairevoiture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10px" android:src="@drawable/carbutton" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingleft="10px" android:layout_weight="1"> <TextView android:id="@+id/itinerairevoituretext" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textsize="16px" android:textstyle="bold" android:text="itinéraire Voiture" android:textcolor="#000000" /> </LinearLayout>
35 </LinearLayout> <!-- navigation piéton --> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageButton android:id="@+id/navigationpieton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10px" android:src="@drawable/pietonbutton" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingleft="10px" android:layout_weight="1"> <TextView android:id="@+id/navpietontext" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textsize="16px" android:textstyle="bold" android:text="navigation Piéton" android:textcolor="#000000" /> </LinearLayout> </LinearLayout> <!-- navigation voiture --> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageButton android:id="@+id/navigationvoiture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10px" android:src="@drawable/carbutton" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingleft="10px" android:layout_weight="1"> <TextView android:id="@+id/navvoituretext" android:layout_width="fill_parent" android:layout_height="fill_parent"
36 android:textsize="16px" android:textstyle="bold" android:text="navigation Voiture" android:textcolor="#000000" /> </LinearLayout> </LinearLayout> </LinearLayout> <!-- Onglet compléments d'information --> <LinearLayout android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent" android:scrollbars="vertical" android:id="@+id/autres"> <!-- Titre compléments d'information --> <TextView android:id="@+id/loctext" android:layout_width="wrap_content" android:layout_height="40px" android:text="complément d'information" android:layout_alignparenttop="true" android:gravity="center" android:layout_gravity="center_horizontal" android:textcolor="#000000" android:textsize="18px"> </TextView> <!-- téléphoner --> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageButton android:id="@+id/boutontelephoner" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10px" android:src="@drawable/phonebutton" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingleft="10px" android:layout_weight="1"> <TextView android:id="@+id/phonetext" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textsize="16px" android:textstyle="bold" android:text="appeler ce bâtiment" android:textcolor="#000000" /> </LinearLayout> </LinearLayout> <!-- accès au site ou menu du ru --> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android"
android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <Button android:id="@+id/siteinternet" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10px" /> </LinearLayout> </LinearLayout> </FrameLayout> </LinearLayout> </TabHost> </LinearLayout> 1.6 GEOLOCALISATION.XML : AFFICHAGE DE LA PAGE DE GEOLOCALISATION <?xml version="1.0" encoding="utf-8"?> <!-- Page géolocalisation --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#fff"> <!-- panel du haut --> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center" android:padding="1px" > <!-- barre de boutons --> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center"> <Button android:id="@+id/lieux" android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@android:drawable/ic_menu_search" /> </LinearLayout> <!-- bouton pour avoir les lieux --> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center"> <Button android:id="@+id/itineraire" android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@android:drawable/ic_menu_directions" /> </LinearLayout> <!-- bouton pour me localiser --> 37
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center"> <Button android:id="@+id/localisemoi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:drawable/ic_menu_crop" /> </LinearLayout> <!-- bouton pour effacer les résultats --> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center"> <Button android:id="@+id/reinitialiser" android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@android:drawable/ic_menu_close_clear _cancel" /> </LinearLayout> </LinearLayout> <!-- Google map --> <com.google.android.maps.mapview android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:apikey="@string/key_map" android:layout_below="@+id/lieux" /> </LinearLayout> 1.7 BALLOON_OVERLAY.XML : OVERLAY SUR LA MAP <?xml version="1.0" encoding="utf-8"?> <!-- Représente la figure lors d'un click sur un lieu de la carte ou sur sa position --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingbottom="35dip" android:paddingleft="10dip" android:minwidth="200dip" android:id="@+id/balloon_main_layout" android:background="@drawable/balloon_overlay_bg_selector" android:paddingtop="0dip" android:paddingright="0dip"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_weight="1" android:paddingtop="10dip" 38
android:id="@+id/balloon_inner_layout"> <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/balloon_item_title" android:text="balloon_item_title" android:textsize="16dip" android:textcolor="#ff000000"></textview> <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/balloon_item_snippet" android:text="balloon_item_snippet" android:textsize="12dip"></textview> </LinearLayout> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/balloon_overlay_close" android:id="@+id/close_img_button" android:paddingleft="10dip" android:paddingbottom="10dip" android:paddingright="8dip" android:paddingtop="8dip"></imageview> </LinearLayout> 1.8 ITINERAIRE.XML : POP-UP SUR LA MAP <?xml version="1.0" encoding="utf-8"?> <!-- Popup permettant le choix du lieu de destination, le mode de déplacement et le mode d'affichage(navigation via GPS ou itineraire via maps) --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/layout_root"> <LinearLayout android:id="@+id/linearlayout01" android:layout_width="fill_parent" android:layout_height="50px"> <TextView android:layout_width="wrap_content" android:text="point de départ :" android:layout_height="wrap_content" android:layout_below="@+id/linearlayout01" android:id="@+id/textview01"></textview> <EditText android:id="@+id/edittextmaposition" android:enabled="false" android:editable="false" android:text="ma position" android:layout_width="fill_parent" android:layout_height="50px" android:layout_below="@+id/linearlayout01" android:layout_torightof="@+id/textview01"></edittext> </LinearLayout> <LinearLayout android:id="@+id/linearlayout02" android:layout_width="fill_parent" android:layout_height="50px" android:layout_below="@+id/linearlayout01"> <TextView android:layout_width="wrap_content" android:text="destination :" android:layout_height="wrap_content" android:layout_below="@+id/textview01" android:id="@+id/textview02"></textview> <AutoCompleteTextView android:id="@+id/autocomplete_country" android:layout_width="fill_parent" android:layout_height="50px" android:layout_marginleft="22px" android:completionthreshold="1" android:layout_below="@+id/textview01" android:layout_torightof="@+id/textview02"/> </LinearLayout> 39
<LinearLayout android:id="@+id/linearlayout03" android:layout_width="wrap_content" android:layout_height="80px" android:layout_below="@+id/linearlayout02"> <TextView android:layout_width="wrap_content" android:layout_margintop="27px" android:text="mode de déplacement :" android:layout_height="wrap_content" android:layout_below="@+id/textview01" android:id="@+id/textview02"></textview> <RadioGroup android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RadioButton android:layout_width="wrap_content" android:id="@+id/radiobuttonpieton" android:text="piéton" android:checked="true" android:layout_height="35px" android:layout_below="@+id/linearlayout02" android:layout_torightof="@+id/linearlayout03"></radiobutton> <RadioButton android:layout_width="wrap_content" android:id="@+id/radiobuttonvoiture" android:text="voiture" android:layout_height="35px" ></RadioButton> </RadioGroup> </LinearLayout> <LinearLayout android:id="@+id/linearlayout04" android:layout_width="wrap_content" android:layout_height="50px" android:layout_below="@+id/linearlayout03"> <Button android:id="@+id/buttonnavigation" android:layout_width="wrap_content" android:layout_height="50px" android:text="navigation" android:layout_below="@+id/linearlayout03"/> <Button android:id="@+id/buttonitineraire" android:layout_width="wrap_content" android:layout_height="50px" android:text="itinéraire" android:layout_below="@+id/linearlayout03"/> </LinearLayout> </RelativeLayout> 1.9 PHONEBUTTON.XML : EXEMPLE D UN IMAGE BUTTON PERSONNALISE <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/phone" android:state_pressed="true" /> <item android:drawable="@drawable/phone" android:state_focused="true" /> <item android:drawable="@drawable/phone" /> </selector> 2. COUCHE MODELE 2.1 BATIMENT.JAVA : CLASSE REPRESENTANT L OBJET BATIMENT package com.ucampus.model; // Classe qui repr 鳥 nte un bment public class Batiment { private int idcategorie; 40
private int idbatiment; private String name; private String numero; private String horaires; private String image; private String adresse; //Coordonn 饳 GPS private String latitude; private String longitude; private String siteinternet; public Batiment(int idcategorie,int idbatiment, String namebat, String numerobat, String horaires, String image, String adresse, String latitude, String longitude,string siteinternet) { super(); this.idcategorie = idcategorie; this.idbatiment=idbatiment; this.name = namebat; this.numero = numerobat; this.horaires = horaires; this.image = image; this.adresse = adresse; this.latitude = latitude; this.longitude = longitude; this.siteinternet=siteinternet; public Batiment(){ public int getidbatiment() { return idbatiment; public void setid(int idbatiment) { this.idbatiment = idbatiment; public String getname() { return name; public void setname(string namebat) { this.name = namebat; public String getnumero() { return numero; public void setnumero(string numero) { this.numero = numero; public String getlatitude() { return latitude; public void setlatitude(string latitude) { this.latitude = latitude; 41
public String getlongitude() { return longitude; public void setlongitude(string longitude) { this.longitude = longitude; public String getsiteinternet() { return siteinternet; public void setsiteinternet(string siteinternet) { this.siteinternet = siteinternet; public int getidcategorie() { return idcategorie; public void setidcategorie(int idcategorie) { this.idcategorie = idcategorie; public String gethoraires() { return horaires; public void sethoraires(string horaires) { this.horaires = horaires; public String getimage() { return image; public void setimage(string image) { this.image = image; public String getadresse() { return adresse; public void setadresse(string adresse) { this.adresse = adresse; @Override public String tostring() { return "Batiment [idbatiment=" + idbatiment + ", idcategorie=" + idcategorie + ", namebat=" + name + ", numerobat=" + numero + ", horaires=" + horaires + ", image=" + image + ", adresse=" + adresse + ", latitude=" + latitude + ", longitude=" + longitude + ", siteinternet=" + siteinternet + "]"; 42
2.2 CATEGORIE.JAVA : CLASSE REPRESENTANT L OBJET CATEGORIE package com.ucampus.model; //Catérie de lieu public class Categorie { private int id; private String namecategorie; //Icone qui repr 鳥 nte la cat 駯 rie private String iconcategorie; public Categorie(String namecategorie, String iconcategorie) { super(); this.namecategorie = namecategorie; this.iconcategorie=iconcategorie; public Categorie(){ public int getid() { return id; public void setid(int id) { this.id = id; public String getnamecategorie() { return namecategorie; public void setnamecategorie(string namecategorie) { this.namecategorie = namecategorie; public String geticoncategorie() { return iconcategorie; public void seticoncategorie(string iconcategorie) { this.iconcategorie = iconcategorie; @Override public String tostring() { return "Categorie [id=" + id + ", iconcategorie=" + iconcategorie + ", namecategorie=" + namecategorie + "]"; 43
3. COUCHE DAO 3.1 BATIMENTDATABASE.JAVA : CREATION DE LA BASE DE BATIMENT AVEC SQLITE package com.ucampus.database; import android.content.context; import android.database.sqlite.sqlitedatabase; import android.database.sqlite.sqlitedatabase.cursorfactory; import android.database.sqlite.sqliteopenhelper; public class BatimentDataBase extends SQLiteOpenHelper { private static final String TABLE_BAT = "table_batiment"; private static final String COL_ID = "ID_BAT"; private static final String COL_ID_CATEGORIE = "ID_CATEGORIE_BAT"; private static final String COL_NAME = "NAME_BAT"; private static final String COL_NUMERO = "NUMERO_BAT"; private static final String COL_HORAIRES = "HORAIRES_BAT"; private static final String COL_IMAGE = "IMAGE_BAT"; private static final String COL_ADRESSE = "ADRESSE_BAT"; private static final String COL_LATITUDE = "LATITUDE_BAT"; private static final String COL_LONGITUDE= "LONGITUDE_BAT"; private static final String COL_SITEINTERNET= "SITEINTERNET_BAT"; //requete pour la création de la table private static final String CREATE_BDD = "CREATE TABLE " + TABLE_BAT + " (" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COL_ID_CATEGORIE + " INTEGER NOT NULL, " + COL_NAME + " TEXT NOT NULL, " + COL_NUMERO + " TEXT NOT NULL," + COL_HORAIRES + " TEXT NOT NULL," + COL_IMAGE + " TEXT NOT NULL," + COL_ADRESSE + " TEXT NOT NULL," + COL_LATITUDE + " TEXT NOT NULL," + COL_LONGITUDE + " TEXT NOT NULL," + COL_SITEINTERNET + " TEXT NOT NULL);"; public BatimentDataBase(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub //on cree la table @Override public void oncreate(sqlitedatabase db) { // TODO Auto-generated method stub db.execsql(create_bdd); //a chaque update de la table @Override public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { 44
// TODO Auto-generated method stub db.execsql("drop TABLE " + TABLE_BAT + ";"); oncreate(db); 3.2 CATEGORIEDATABASE.JAVA : CREATION DE LA BASE DE CATEGORIE AVEC SQLITE package com.ucampus.database; import android.content.context; import android.database.sqlite.sqlitedatabase; import android.database.sqlite.sqlitedatabase.cursorfactory; import android.database.sqlite.sqliteopenhelper; public class CategorieDataBase extends SQLiteOpenHelper { private static final String TABLE_BAT = "table_categorie"; private static final String COL_ID = "ID_CAT"; private static final String COL_NAME = "NAME_CAT"; private static final String COL_ICON = "ICON_CAT"; //requete pour la création de la table private static final String CREATE_BDD = "CREATE TABLE " + TABLE_BAT + " (" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COL_NAME + " TEXT NOT NULL, " + COL_ICON + " TEXT NOT NULL);"; public CategorieDataBase(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub //on cree la table @Override public void oncreate(sqlitedatabase db) { // TODO Auto-generated method stub db.execsql(create_bdd); //a chaque update de la table @Override public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { // TODO Auto-generated method stub db.execsql("drop TABLE " + TABLE_BAT + ";"); oncreate(db); 45
3.3 BATIMENTDAO.JAVA : CONNEXION ET CRUD SUR LA BASE DES BATIMENTS package com.ucampus.dao; import java.util.arraylist; import android.content.contentvalues; import android.content.context; import android.database.cursor; import android.database.sqlite.sqlitedatabase; import com.ucampus.database.batimentdatabase; import com.ucampus.model.batiment; public class BatimentDAO { private static final int VERSION_BDD = 1; private static final String NOM_BDD = "ucampusbat.db"; private static final String TABLE_BAT = "table_batiment"; private static final String COL_ID_BAT = "ID_BAT"; private static final int NUM_ID = 0; private static final String COL_ID_CATEGORIE = "ID_CATEGORIE_BAT"; private static final int NUM_ID_CATEGORIE = 1; private static final String COL_NAME = "NAME_BAT"; private static final int NUM_COL_NAME = 2; private static final String COL_NUMERO = "NUMERO_BAT"; private static final int NUM_COL_NUMERO = 3; private static final String COL_HORAIRES = "HORAIRES_BAT"; private static final int NUM_COL_HORAIRES = 4; private static final String COL_IMAGE = "IMAGE_BAT"; private static final int NUM_COL_IMAGE = 5; private static final String COL_ADRESSE = "ADRESSE_BAT"; private static final int NUM_COL_ADRESSE = 6; private static final String COL_LATITUDE = "LATITUDE_BAT"; private static final int NUM_COL_LATITUDE = 7; private static final String COL_LONGITUDE = "LONGITUDE_BAT"; private static final int NUM_COL_LONGITUDE = 8; private static final String COL_SITEINTERNET = "SITEINTERNET_BAT"; private static final int NUM_COL_SITEINTERNET = 9; private SQLiteDatabase bdd; private BatimentDataBase mabatimentdatabase; null, public BatimentDAO(Context context) { // On créer la BDD et sa table mabatimentdatabase = new BatimentDataBase(context, NOM_BDD, VERSION_BDD); 46 public void open() { // on ouvre la BDD en écriture bdd = mabatimentdatabase.getwritabledatabase(); public void close() { // on ferme l'accès à la BDD
bdd.close(); public SQLiteDatabase getbdd() { return bdd; de la public long insertbatiment(batiment b) { // Création d'un ContentValues (fonctionne comme une HashMap) ContentValues values = new ContentValues(); // on lui ajoute une valeur associé à une clé (qui est le nom // colonne dans laquelle on veut mettre la valeur) values.put(col_name, b.getname()); values.put(col_numero, b.getnumero()); values.put(col_id_categorie, b.getidcategorie()); values.put(col_horaires, b.gethoraires()); values.put(col_image, b.getimage()); values.put(col_adresse, b.getadresse()); values.put(col_latitude, b.getlatitude()); values.put(col_longitude, b.getlongitude()); values.put(col_siteinternet, b.getsiteinternet()); values.put(col_id_bat, b.getidbatiment()); return bdd.insert(table_bat, null, values); de la null); 47 public long updatebatiment(int id, Batiment b) { // Création d'un ContentValues (fonctionne comme une HashMap) ContentValues values = new ContentValues(); // on lui ajoute une valeur associé à une clé (qui est le nom // colonne dans laquelle on veut mettre la valeur) values.put(col_name, b.getname()); values.put(col_numero, b.getnumero()); values.put(col_id_categorie, b.getidcategorie()); values.put(col_horaires, b.gethoraires()); values.put(col_image, b.getimage()); values.put(col_adresse, b.getadresse()); values.put(col_latitude, b.getlatitude()); values.put(col_longitude, b.getlongitude()); values.put(col_siteinternet, b.getsiteinternet()); values.put(col_id_bat, b.getidbatiment()); return bdd.update(table_bat, values, COL_ID_BAT + " = " + id, public int removebatimentwithid(int id) { // Suppression d'un batiment de la BDD grâce à l'id return bdd.delete(table_bat, COL_ID_BAT + " = " + id, null); public ArrayList<Batiment> getallbatiment() { ArrayList<Batiment> allbatiments = new ArrayList<Batiment>(); Cursor c = bdd.query(table_bat, new String[] { COL_ID_BAT, COL_ID_CATEGORIE, COL_NAME, COL_NUMERO, COL_HORAIRES, COL_IMAGE, COL_ADRESSE, COL_LATITUDE, COL_LONGITUDE, COL_SITEINTERNET, null, null, null, null, null); if (c.getcount() == 0) {
contenues return null; else { while (c.movetonext()) { Batiment batiment = new Batiment(); // on lui affecte toutes les infos grâce aux infos // dans le Cursor batiment.setid(c.getint(num_id)); batiment.setname(c.getstring(num_col_name)); batiment.setnumero(c.getstring(num_col_numero)); 48 batiment.setidcategorie(c.getint(num_id_categorie)); batiment.sethoraires(c.getstring(num_col_horaires)); batiment.setimage(c.getstring(num_col_image)); batiment.setadresse(c.getstring(num_col_adresse)); batiment.setlatitude(c.getstring(num_col_latitude)); batiment.setlongitude(c.getstring(num_col_longitude)); batiment.setsiteinternet(c.getstring(num_col_siteinternet)); allbatiments.add(batiment); c.close(); return allbatiments; public Batiment getbatimentwithname(string name) { // Récupère dans un Cursor les valeur correspondant à un batiment // contenu dans la BDD Cursor c = bdd.query(table_bat, new String[] { COL_ID_BAT, COL_ID_CATEGORIE, COL_NAME, COL_NUMERO, COL_HORAIRES, COL_IMAGE, COL_ADRESSE, COL_LATITUDE, COL_LONGITUDE, COL_SITEINTERNET, COL_NAME + " LIKE \"" + name + "\"", null, null, null, null); return cursortobatiment(c); public ArrayList<Batiment> getbatimentwithcategorie(int catid) { ArrayList<Batiment> allbatiments = new ArrayList<Batiment>(); // Récupère dans un Cursor les valeur correspondant à un batiment // contenu dans la BDD Cursor c = bdd.query(table_bat, new String[] { COL_ID_BAT, COL_ID_CATEGORIE, COL_NAME, COL_NUMERO, COL_HORAIRES, COL_IMAGE, COL_ADRESSE, COL_LATITUDE, COL_LONGITUDE, COL_SITEINTERNET, COL_ID_CATEGORIE + " LIKE \"" + catid + "\"", null, null, null, null); if (c.getcount() == 0) { return null; else { while (c.movetonext()) { Batiment batiment = new Batiment();
contenues // on lui affecte toutes les infos grâce aux infos // dans le Cursor batiment.setid(c.getint(num_id)); batiment.setname(c.getstring(num_col_name)); batiment.setnumero(c.getstring(num_col_numero)); batiment.setidcategorie(c.getint(num_id_categorie)); batiment.sethoraires(c.getstring(num_col_horaires)); batiment.setimage(c.getstring(num_col_image)); batiment.setadresse(c.getstring(num_col_adresse)); batiment.setlatitude(c.getstring(num_col_latitude)); batiment.setlongitude(c.getstring(num_col_longitude)); batiment.setsiteinternet(c.getstring(num_col_siteinternet)); allbatiments.add(batiment); c.close(); return allbatiments; private Batiment cursortobatiment(cursor c) { // si aucun élément n'a été retourné dans la requête, on renvoie null if (c.getcount() == 0) return null; dans le // Sinon on se place sur le premier élément c.movetofirst(); // On créé un batiment Batiment batiment = new Batiment(); // on lui affecte toutes les infos grâce aux infos contenues // Cursor batiment.setid(c.getint(num_id)); batiment.setname(c.getstring(num_col_name)); batiment.setnumero(c.getstring(num_col_numero)); batiment.setidcategorie(c.getint(num_id_categorie)); batiment.sethoraires(c.getstring(num_col_horaires)); batiment.setimage(c.getstring(num_col_image)); batiment.setadresse(c.getstring(num_col_adresse)); batiment.setlatitude(c.getstring(num_col_latitude)); batiment.setlongitude(c.getstring(num_col_longitude)); batiment.setsiteinternet(c.getstring(num_col_siteinternet)); // On ferme le cursor c.close(); // On retourne le batiment return batiment; 49
3.4 CATEGORIEDAO.JAVA : CONNEXION ET CRUD SUR LA BASE DES CATEGORIES package com.ucampus.dao; import java.util.arraylist; import android.content.contentvalues; import android.content.context; import android.database.cursor; import android.database.sqlite.sqlitedatabase; import com.ucampus.database.categoriedatabase; import com.ucampus.model.categorie; public class CategorieDAO { private static final int VERSION_BDD = 1; private static final String NOM_BDD = "ucampuscat.db"; private static final String TABLE_BAT = "table_categorie"; private static final String COL_ID = "ID_CAT"; private static final int NUM_ID = 0; private static final String COL_NAME = "NAME_CAT"; private static final int NUM_COL_NAME = 1; private static final String COL_ICON = "ICON_CAT"; private static final int NUM_COL_ICON = 2; private SQLiteDatabase bdd; private CategorieDataBase macategoriedatabase; public CategorieDAO(Context context){ //On créer la BDD et sa table macategoriedatabase = new CategorieDataBase(context, NOM_BDD, null, VERSION_BDD); public void open(){ //on ouvre la BDD en écriture bdd = macategoriedatabase.getwritabledatabase(); public void close(){ //on ferme l'accès à la BDD bdd.close(); public SQLiteDatabase getbdd() { return bdd; public long insertcategorie(categorie c){ //Création d'un ContentValues (fonctionne comme une HashMap) ContentValues values = new ContentValues(); //on lui ajoute une valeur associé à une clé (qui est le nom de la colonne dans laquelle on veut mettre la valeur) values.put(col_name, c.getnamecategorie()); values.put(col_icon, c.geticoncategorie()); 50
return bdd.insert(table_bat, null, values); public long updatecategorie(int id, Categorie c){ //Création d'un ContentValues (fonctionne comme une HashMap) ContentValues values = new ContentValues(); //on lui ajoute une valeur associé à une clé (qui est le nom de la colonne dans laquelle on veut mettre la valeur) values.put(col_name, c.getnamecategorie()); values.put(col_icon, c.geticoncategorie()); return bdd.update(table_bat, values, COL_ID + " = " +id, null); public int removecategoriewithid(int id){ //Suppression d'une catégorie de la BDD grâce à l'id return bdd.delete(table_bat, COL_ID + " = " +id, null); public ArrayList<Categorie> getallcategories(){ ArrayList<Categorie> allcategories = new ArrayList<Categorie>(); Cursor c = bdd.query(table_bat, new String[] {COL_ID, COL_NAME, COL_ICON, null, null, null, null, null); if (c.getcount() == 0){ return null; else{ while (c.movetonext()){ Categorie cat = new Categorie(); //on lui affecte toutes les infos grâce aux infos contenues dans le Cursor cat.setid(c.getint(num_id)); cat.setnamecategorie(c.getstring(num_col_name)); cat.seticoncategorie(c.getstring(num_col_icon)); allcategories.add(cat); c.close(); return allcategories; public Categorie getcategoriewithname(string name){ //Récupère dans un Cursor les valeur correspondant à une catégorie contenue dans la BDD Cursor c = bdd.query(table_bat, new String[] {COL_ID, COL_NAME, COL_ICON, COL_NAME + " LIKE \"" + name +"\"", null, null, null, null); return cursortobcategorie(c); public Categorie getcategoriebyid(int id){ //Récupère dans un Cursor les valeur correspondant à une categorie contenue dans la BDD Cursor c = bdd.query(table_bat, new String[] {COL_ID, COL_NAME,COL_ICON, COL_ID + " LIKE \"" + id +"\"", null, null, null, null); return cursortobcategorie(c); null private Categorie cursortobcategorie(cursor c) { //si aucun élément n'a été retourné dans la requête, on renvoie if (c.getcount() == 0) 51
return null; //Sinon on se place sur le premier élément c.movetofirst(); //On créé une categorie Categorie cat = new Categorie(); //on lui affecte toutes les infos grâce aux infos contenues dans le Cursor cat.setid(c.getint(num_id)); cat.setnamecategorie(c.getstring(num_col_name)); cat.seticoncategorie(c.getstring(num_col_icon)); //On ferme le cursor c.close(); //On retourne la categorie return cat; 4. COUCHE UTILITAIRES 4.1 INSERTBDD.JAVA : CLASSE D INSERTION DANS LMA BASE package com.ucampus.utils; import android.content.context; import com.google.android.maps.geopoint; import com.ucampus.dao.batimentdao; import com.ucampus.dao.categoriedao; import com.ucampus.model.batiment; import com.ucampus.model.categorie; public class InsertBDD { final BatimentDAO bbdd; final CategorieDAO cbdd; 52 //première version qui n'utilise pas de Parser BDD public InsertBDD(Context c) { super(); //Insertion des catégories this.cbdd = new CategorieDAO(c); cbdd.open(); if (cbdd.getallcategories() == null) { Categorie cat; // A renseigner pour créer une catégorie : // Nom de la catégorie // icone qui represente la catégorie cat = new Categorie("Restaurants","cook"); cbdd.insertcategorie(cat); cat = new Categorie("Santé","health"); cbdd.insertcategorie(cat); cat = new Categorie("Salle de sport","sports"); cbdd.insertcategorie(cat); cbdd.close();
53 this.bbdd = new BatimentDAO(c); bbdd.open(); if (bbdd.getallbatiment()== null) { // A renseigner pour créer un bâtiement : // Id de la catégorie // Id du bâtiment // Nom du bâtiment // Numéro de téléphone // Horaires d'ouverture // Image // Adresse // Latitude // longitude // Site internet Batiment b; // Catégorie : Restaurants Universitaire b = new Batiment(1,1,"Le Barrois","03 20 33 61 23","11h15 à 13h30 ","imgm5","cité Scientifique","50611027","3144468","http://www.crous-lille.fr/adminsite/restauration_menu_print_w.php?ru=26&midi=1&soir=1&nb_w=2"); bbdd.insertbatiment(b); b = new Batiment(1,2,"Le Pariselle","03 20 43 43 85","11h30 à 13h45 et 18h30 à 19h45","imgM3","Cité Scientifique - Boulevard Langevin","50608186","3147195","http://www.crous-lille.fr/adminsite/restauration_menu_print_w.php?ru=19&midi=1&soir=1&nb_w=2"); bbdd.insertbatiment(b); b = new Batiment(1,3,"Le Sully","03 20 43 44 51","11h15 à 13h30 ","imgm3","cité Scientifique - Boulevard Langevin","50605594","3136443","http://www.crous-lille.fr/adminsite/restauration_menu_print_w.php?ru=25&midi=1&soir=1&nb_w=2"); bbdd.insertbatiment(b); // Catégorie : Santé b = new Batiment(2,4,"SIUMPPS","03 20 43 65 50","du lundi au jeudi de 8h30 à 17h00 et le vendredi de 8h30 à 16h00 ","imgm3","le Service Inter-Universitaire de Médecine Préventive et de Promotion de la Sante (SIUMPPS) situé, pour l'université Lille 1, à la Maison Universitaire de la Santé face au Bâtiment A3, à côté du M1, Cité Scientifique, 59650 VILLENEUVE D ASCQ","50608335","3138784","http://www.univlille1.fr/campus/Sante"); bbdd.insertbatiment(b); // Catégorie : Salle de sport b = new Batiment(3,5,"COSEC","03 20 33 62 00","Veuillez consulter le site internet de l'université ","imgm3","université Lille I Bvd Paul Langevin -59655 Villeneuve d'ascq","50606874","3145176","http://suaps.univ-lille1.fr/asso- Sportive/Asso+des+Etudiants+de+Lille1/"); bbdd.insertbatiment(b); b = new Batiment(3,6,"Halle Grémeaux","03 20 33 62 00","Veuillez consulter le site internet de l'université ","imgm3","université Lille I Rue Paul Langevin - 59650 Villeneuve d'ascq","50607554","3134383","http://suaps.univ-lille1.fr/asso- Sportive/Asso+des+Etudiants+de+Lille1/"); bbdd.insertbatiment(b); b = new Batiment(3,7,"Halle Vallin","03 20 33 62 00","Veuillez consulter le site internet de l'université ","imgm3","université Lille I Rue Paul Langevin - 59650 Villeneuve d'ascq","50609779","3136005","http://suaps.univ-lille1.fr/asso- Sportive/Asso+des+Etudiants+de+Lille1/");
bbdd.insertbatiment(b); bbdd.close(); 5. COUCHE ANDROID 5.1 HOME.JAVA : LA PAGE D ACCUEIL package com.ucampus; import android.app.activity; import android.app.alertdialog; import android.content.context; import android.content.dialoginterface; import android.content.intent; import android.location.locationmanager; import android.net.connectivitymanager; import android.net.networkinfo; import android.net.wifi.wifimanager; import android.os.bundle; import android.os.vibrator; import android.view.menu; import android.view.menuinflater; import android.view.menuitem; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.toast; import com.ucampus.dao.batimentdao; import com.ucampus.utils.insertbdd; public class Home extends Activity { private Button localisationhome; private Button search; /** Called when the activity is first created. */ @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); //insertion dans la base si il n'y a rien dedans InsertBDD i = new InsertBDD(this); //listener et action sur le button localidation localisationhome = (Button) findviewbyid(r.id.localisationhome); localisationhome.setonclicklistener(new OnClickListener() { public void onclick(view v) { 54 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); //Test si GPS est activé
55 if (isgpson()) { //Test si 3G est activée if (is3gorwifion()) { Intent intent = new Intent(Home.this,Geolocalisation.class); startactivity(intent); else { create3gwifidisabledalert(); else { creategpsdisabledalert(); ); //listener et action sur le button recherche de lieu search = (Button) findviewbyid(r.id.searchhome); search.setonclicklistener(new OnClickListener() { public void onclick(view v) { ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); Intent intent = new Intent(Home.this, CatList.class); startactivity(intent); ); // Test si l'acces à internet (WIFI ou 3G) est activé private Boolean is3gorwifion() { ConnectivityManager connectivitymanager = (ConnectivityManager) getsystemservice(context.connectivity_service); NetworkInfo networkinfo = connectivitymanager.getactivenetworkinfo(); if (networkinfo == null) { WifiManager wifi = (WifiManager) getsystemservice(context.wifi_service); if (!wifi.iswifienabled()) { return false; else { return true; else { return true; // Test si le GPS est activé private Boolean isgpson() { LocationManager locmanager = (LocationManager) getsystemservice(location_service); if (!locmanager.isproviderenabled(locationmanager.gps_provider)) { return false; else { return true; // On propose à l'utilisateur d'activer son gps private void create3gwifidisabledalert() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setmessage( "Veuillez activer votre 3G (manuellement) ou votre WIFI! Souhaitez-vous activer WIFI?")
.setcancelable(false).setpositivebutton("oui", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { Intent connectingoptionsintent = new Intent( android.provider.settings.action_wifi_settings); startactivity(connectingoptionsintent); ); builder.setnegativebutton("non", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { dialog.cancel(); ); AlertDialog alert = builder.create(); alert.show(); // On informe l'utilisateur qu'il doit activer sa 3G ou son Wifi private void creategpsdisabledalert() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setmessage("votre GPS est désactivé! Souhaitez-vous l'activer?").setcancelable(false).setpositivebutton("oui", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { Intent gpsoptionsintent = new Intent( android.provider.settings.action_location_source_settings); startactivity(gpsoptionsintent); ); builder.setnegativebutton("non", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { dialog.cancel(); ); AlertDialog alert = builder.create(); alert.show(); //Création du menu public boolean oncreateoptionsmenu(menu menu) { MenuInflater inflater = getmenuinflater(); inflater.inflate(r.menu.menuaccueil, menu); return true; // Appeler lors du click sur le menu public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case R.id.menuPlus: Toast.makeText(this, "En construction", Toast.LENGTH_LONG).show(); break; case R.id.menuReglages: Intent intent = new Intent(Home.this, Reglages.class); startactivity(intent); break; 56
return true; 5.2 CATLIST.JAVA : PAGE DE LISTING DES CATEGORIES package com.ucampus; import java.util.arraylist; import java.util.hashmap; import android.app.activity; import android.content.intent; import android.graphics.drawable.drawable; import android.os.bundle; import android.os.vibrator; import android.util.log; import android.view.menu; import android.view.menuinflater; import android.view.menuitem; import android.view.view; import android.widget.adapterview; import android.widget.listview; import android.widget.simpleadapter; import android.widget.adapterview.onitemclicklistener; import android.widget.toast; import com.ucampus.dao.categoriedao; import com.ucampus.model.categorie; public class CatList extends Activity { private ListView categorieslistview; /** Called when the activity is first created. */ public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.catlist); CategorieDAO cbdd = new CategorieDAO(this); cbdd.open(); //Récupération de la listview créée dans le fichier catlist.xml categorieslistview = (ListView) findviewbyid(r.id.listviewcategories); //Création de la ArrayList qui nous permettra de remplir la listview ArrayList<HashMap<String, String>> listitem = new ArrayList<HashMap<String, String>>(); item //On déclare la HashMap qui contiendra les informations pour un HashMap<String, String> map; ArrayList<Categorie> allc = cbdd.getallcategories(); for (Categorie c : allc) { 57
//Création d'une HashMap pour insérer les informations du premier item de notre listview map = new HashMap<String, String>(); //on insère un élément titre que l'on récupérera dans le textview titre créé dans le fichier affichageitem.xml map.put("titre",c.getnamecategorie() ); //on insère un élément description que l'on récupérera dans le textview description créé dans le fichier affichageitem.xml map.put("description", "Tous les batiment de la catégorie "+c.getnamecategorie()); //on récupère l'id de l'iamge dans les ressources du projet (les images dans les apk sont compilées...) int resid = getresources().getidentifier(c.geticoncategorie(), "drawable", "com.ucampus"); map.put("img", String.valueOf(resID)); //enfin on ajoute cette hashmap dans la arraylist listitem.add(map); //Création d'un SimpleAdapter qui se chargera de mettre les items présent dans notre list (listitem) dans la vue affichageitem SimpleAdapter mschedule = new SimpleAdapter (this.getbasecontext(), listitem, R.layout.affichageitem, new String[] {"img", "titre", "description", new int[] {R.id.img, R.id.titre, R.id.description); { long id) { 58 //On attribut à notre listview l'adapter que l'on vient de créer categorieslistview.setadapter(mschedule); //On met un écouteur d'évènement sur notre listview categorieslistview.setonitemclicklistener(new OnItemClickListener() @SuppressWarnings("unchecked") public void onitemclick(adapterview<?> a, View v, int position, ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); //on récupère la HashMap contenant les infos de notre item (titre, description, img) HashMap<String, String> map = (HashMap<String, String>) categorieslistview.getitematposition(position); Intent intent = new Intent(CatList.this, BatList.class); intent.putextra("catname", map.get("titre")); CatList.this.startActivity(intent); ); cbdd.close(); public boolean oncreateoptionsmenu(menu menu) { MenuInflater inflater = getmenuinflater(); inflater.inflate(r.menu.menulistecategorie, menu); return true; public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case R.id.menuAccueil:
Intent intent2 = new Intent(CatList.this, Home.class); startactivity(intent2); this.finish(); break; case R.id.menuPlus: Toast.makeText(this, "En construction", Toast.LENGTH_LONG).show(); break; case R.id.menuLocalisation: Intent intent = new Intent(CatList.this, Geolocalisation.class); startactivity(intent); this.finish(); break; case R.id.menuReglages: Intent intent3 = new Intent(CatList.this, Reglages.class); startactivity(intent3);this.finish(); break; return true; 5.3 BATLIST.JAVA : PAGE DE LISTING DES BATIMENTS package com.ucampus; import java.util.arraylist; import java.util.hashmap; import android.app.activity; import android.app.listactivity; import android.content.intent; import android.os.bundle; import android.os.vibrator; import android.util.log; import android.view.menu; import android.view.menuinflater; import android.view.menuitem; import android.view.view; import android.widget.adapterview; import android.widget.adapterview.onitemclicklistener; import android.widget.arrayadapter; import android.widget.listview; import android.widget.simpleadapter; import android.widget.textview; import android.widget.toast; import com.ucampus.dao.batimentdao; import com.ucampus.dao.categoriedao; import com.ucampus.model.batiment; import com.ucampus.model.categorie; public class BatList extends Activity { private ArrayList<String> leslieux = new ArrayList<String>(); 59 private ListView categorieslistview;
private TextView titlelist; /** Called when the activity is first created. */ public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.batlist); final BatimentDAO bbdd = new BatimentDAO(this); final String catname = this.getintent().getextras().getstring("catname"); bbdd.open(); // récupération de la catégorie choisie CategorieDAO cbdd = new CategorieDAO(this); cbdd.open(); Categorie categorie = cbdd.getcategoriewithname(catname); cbdd.close(); // Récupération de la listview créée dans le fichier catlist.xml categorieslistview = (ListView) findviewbyid(r.id.listviewbatiments); // Création de la ArrayList qui nous permettra de remplir la listview ArrayList<HashMap<String, String>> listitem = new ArrayList<HashMap<String, String>>(); un item // On déclare la HashMap qui contiendra les informations pour HashMap<String, String> map; final ArrayList<String> allbname = new ArrayList<String>(); ArrayList<Batiment> allb = bbdd.getbatimentwithcategorie(categorie.getid()); for (Batiment b : allb) { // Création d'une HashMap pour insérer les informations du premier item de notre listview map = new HashMap<String, String>(); // on insère un élément titre que l'on récupérera dans le textview titre créé dans le fichier affichageitem.xml map.put("titre", b.getname()); // on insère un élément description que l'on récupérera dans le textview description créé dans le fichier affichageitem.xml map.put("description", b.getadresse()); //on récupère l'id de l'iamge dans les ressources du projet (les images dans les apk sont compilées...) int resid = getresources().getidentifier(categorie.geticoncategorie(), "drawable", "com.ucampus"); map.put("img", String.valueOf(resID)); // enfin on ajoute cette hashmap dans la arraylist listitem.add(map); allbname.add(b.getname()); 60 // Ajout de l'option tous les batiments map = new HashMap<String, String>(); map.put("titre", catname+" : tous les bâtiments"); map.put("description", "");
allbname.add(catname+ " : tous les bâtiments"); String[] BATS = new String[allBName.size()]; allbname.toarray(bats); int resid = getresources().getidentifier(categorie.geticoncategorie(), "drawable", "com.ucampus"); map.put("img", String.valueOf(resID)); listitem.add(map); // Création d'un SimpleAdapter qui se chargera de mettre les items présent dans notre list (listitem) dans la vue affichageitem SimpleAdapter mschedule = new SimpleAdapter(this.getBaseContext(), listitem, R.layout.affichageitem, new String[] { "img", "titre", "description", new int[] { R.id.img, R.id.titre, R.id.description ); créer // On attribut à notre listview l'adapter que l'on vient de categorieslistview.setadapter(mschedule); 61 //Affichage du titre de la page en fonction de la catégorie titlelist = (TextView) findviewbyid(r.id.titlebatlist); titlelist.settext(catname); categorieslistview.setonitemclicklistener(new OnItemClickListener() { @SuppressWarnings("unchecked") public void onitemclick(adapterview<?> a, View v, int position, long id) { ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); // on récupère la HashMap contenant les infos de notre item // (titre, description, img) HashMap<String, String> map = (HashMap<String, String>) categorieslistview.getitematposition(position); //permet d'afficher tous les bâtiments de la catégorie if (map.get("titre").contains(" : tous les bâtiments")) { allbname.remove(allbname.size()-1); leslieux.addall(allbname); Log.e("les batiments : ",leslieux.tostring()); Intent intent = new Intent(BatList.this,Geolocalisation.class); intent.putextra("categoriedelieux", catname); intent.putstringarraylistextra("lieu", leslieux); bbdd.close(); BatList.this.startActivity(intent); else { Intent intent = new Intent(BatList.this, ViewBatiment.class); intent.putextra("batname", map.get("titre")); bbdd.close(); BatList.this.startActivity(intent);
); public boolean oncreateoptionsmenu(menu menu) { MenuInflater inflater = getmenuinflater(); inflater.inflate(r.menu.menulistecategorie, menu); return true; public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case R.id.menuAccueil: Intent intent = new Intent(BatList.this, Home.class); startactivity(intent); this.finish(); break; case R.id.menuPlus: Toast.makeText(this, "En construction", Toast.LENGTH_LONG).show(); break; case R.id.menuLocalisation: Intent intent2 = new Intent(BatList.this, Geolocalisation.class); startactivity(intent2); this.finish(); break; case R.id.menuReglages: Intent intent3 = new Intent(BatList.this, Reglages.class); startactivity(intent3); this.finish(); break; return true; 5.4 VIEWBATIMENT.JAVA : FICHE DETAILLEE DU BATIMENT package com.ucampus; import java.util.arraylist; import android.app.activity; import android.app.alertdialog; import android.content.context; import android.content.dialoginterface; import android.content.intent; import android.location.locationmanager; import android.net.connectivitymanager; import android.net.networkinfo; import android.net.uri; import android.net.wifi.wifimanager; import android.os.bundle; import android.os.vibrator; import android.util.log; import android.view.menu; 62
import android.view.menuinflater; import android.view.menuitem; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.imagebutton; import android.widget.tabhost; import android.widget.tabhost.ontabchangelistener; import android.widget.tabhost.tabspec; import android.widget.textview; import android.widget.toast; import com.google.android.maps.geopoint; import com.google.android.maps.overlayitem; import com.ucampus.dao.batimentdao; import com.ucampus.dao.categoriedao; import com.ucampus.model.batiment; public class ViewBatiment extends Activity { private ArrayList<String> leslieux = new ArrayList<String>(); private String numerotelephone; private String uristring; private TabHost montabhost; 63 /** Called when the activity is first created. */ @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.viewbatiment); /** Ajout des onglets **/ montabhost = (TabHost) findviewbyid(r.id.tabhost01); montabhost.setup(); /** Ajout des 3 onglets **/ TabSpec spec = montabhost.newtabspec("onglet_info"); spec.setindicator("",getresources().getdrawable(r.drawable.info)); spec.setcontent(r.id.general_info); montabhost.addtab(spec); montabhost.addtab(montabhost.newtabspec("onglet_loc_maps").setindicat or("",getresources().getdrawable(r.drawable.map)).setcontent(r.id.loc_maps) ); montabhost.addtab(montabhost.newtabspec("onglet_autres").setindicator ("",getresources().getdrawable(r.drawable.plus)).setcontent(r.id.autres)); String batname = this.getintent().getextras().getstring("batname"); final BatimentDAO bbdd = new BatimentDAO(this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(this); cbdd.open(); final Batiment b = bbdd.getbatimentwithname(batname); //mise à jour du texte dans la fiche du batiment TextView tw = (TextView) findviewbyid(r.id.name); tw.settext(b.getname()); tw = (TextView) findviewbyid(r.id.numero); tw.settext(b.getnumero());
numerotelephone = b.getnumero(); tw = (TextView) findviewbyid(r.id.ouverture); tw.settext(b.gethoraires()); tw = (TextView) findviewbyid(r.id.adresse); tw.settext(b.getadresse()); // url du site internet uristring = b.getsiteinternet(); // Mise à jour du label du bouton Button boutonsiteinternet = (Button) findviewbyid(r.id.siteinternet); //Si c'est un restaurant on changre le texte du bouton if (b.getidcategorie()==1){ boutonsiteinternet.settext("menu du RU"); else{ boutonsiteinternet.settext("site internet"); cbdd.close(); bbdd.close(); //Action lors du click sur le bouton de localisation d'un bâtiment ImageButton boutonlocalise = (ImageButton) findviewbyid(r.id.localise); boutonlocalise.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { //Test si le GPS est activé if (isgpson()) { //Test si la 3G est activée if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); Intent intent = new Intent(ViewBatiment.this, Geolocalisation.class); //Ajout de la catégorie de lieu à afficher dans les parametres du intent intent.putextra("categoriedelieux", cbdd.getcategoriebyid(b.getidcategorie()).getnamecategorie()); parametres du intent leslieux); leslieux.add(b.getname()); //Ajout des lieux à afficher dans les intent.putstringarraylistextra("lieu", cbdd.close(); bbdd.close(); //Vibrateur pour informer du click 64 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); else { creategpsdisabledalert();
); //Affichage du site du bâtiment (ou du menu du RU) boutonsiteinternet.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ Log.e("internet","internet"+uriString); Uri intenturi = Uri.parse(uriString); Intent intent = new Intent(); intent.setaction(intent.action_view); intent.setdata(intenturi); ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); ); //lancement du mode itinéraire piéton ImageButton boutonitinerairepieton = (ImageButton) findviewbyid(r.id.itinerairepieton); boutonitinerairepieton.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (isgpson()) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); Intent intent = new Intent(ViewBatiment.this, Geolocalisation.class); intent.putextra("categoriedelieux", cbdd.getcategoriebyid(b.getidcategorie()).getnamecategorie()); b.getname()); "pieton"); intent.putextra("lieudestination", intent.putextra("modedeplacement", cbdd.close(); bbdd.close(); 65 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); else { creategpsdisabledalert();
); //lancement du mode itinéraire voiture ImageButton boutonitinerairevoiture = (ImageButton) findviewbyid(r.id.itinerairevoiture); boutonitinerairevoiture.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (isgpson()) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); Intent intent = new Intent(ViewBatiment.this, Geolocalisation.class); intent.putextra("categoriedelieux", cbdd.getcategoriebyid(b.getidcategorie()).getnamecategorie()); b.getname()); "voiture"); intent.putextra("lieudestination", intent.putextra("modedeplacement", cbdd.close(); bbdd.close(); 66 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); else { creategpsdisabledalert(); ); //lancement du mode navigation piéton ImageButton boutonnavigationpieton = (ImageButton) findviewbyid(r.id.navigationpieton); boutonnavigationpieton.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (isgpson()) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this);
cbdd.open(); GeoPoint point = new GeoPoint( Integer.parseInt(b.getLatitude()), Integer.parseInt(b.getLongitude())); OverlayItem(point, cbdd OverlayItem overlayitem = new.getcategoriebyid(b.getidcategorie()).getnamecategorie(), null); Intent(Intent.ACTION_VIEW, Uri Intent i = new.parse("google.navigation:q=" overlayitem.routableaddress() + "&mode=w")); cbdd.close(); bbdd.close(); + ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(i); else { creategpsdisabledalert(); ); //lancement du mode navigation voiture ImageButton boutonnavigationvoiture = (ImageButton) findviewbyid(r.id.navigationvoiture); boutonnavigationvoiture.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (isgpson()) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); GeoPoint point = new GeoPoint( Integer.parseInt(b.getLatitude()), Integer.parseInt(b.getLongitude())); OverlayItem(point, cbdd OverlayItem overlayitem = new.getcategoriebyid(b.getidcategorie()).getnamecategorie(), null); Intent(Intent.ACTION_VIEW, Uri Intent i = new 67
.parse("google.navigation:q=" overlayitem.routableaddress())); cbdd.close(); bbdd.close(); + 68 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(i); else { creategpsdisabledalert(); ); //action pour téléphoner au bâtiment ImageButton boutontelephoner = (ImageButton) findviewbyid(r.id.boutontelephoner); boutontelephoner.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); startactivityforresult( new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + numerotelephone)), 1); cbdd.close(); bbdd.close(); ); // Test si le GPS est activé private Boolean isgpson() { LocationManager locmanager = (LocationManager) getsystemservice(location_service); if (!locmanager.isproviderenabled(locationmanager.gps_provider)) { return false; else { return true; // On informe l'utilisateur qu'il doit activer sa 3G ou son Wifi private void creategpsdisabledalert() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setmessage("votre GPS est désactivé! Souhaitez-vous l'activer?").setcancelable(false).setpositivebutton("oui", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) {
new Intent( Intent gpsoptionsintent = 69 android.provider.settings.action_location_source_settings); startactivity(gpsoptionsintent); ); builder.setnegativebutton("non", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { dialog.cancel(); ); AlertDialog alert = builder.create(); alert.show(); // Test si l'acces à internet (WIFI ou 3G) est activé private Boolean is3gorwifion() { ConnectivityManager connectivitymanager = (ConnectivityManager) getsystemservice(context.connectivity_service); NetworkInfo networkinfo = connectivitymanager.getactivenetworkinfo(); if (networkinfo == null) { WifiManager wifi = (WifiManager) getsystemservice(context.wifi_service); if (!wifi.iswifienabled()) { return false; else { return true; else { return true; // On propose à l'utilisateur d'activer son gps private void create3gwifidisabledalert() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setmessage( "Veuillez activer votre 3G (manuellement) ou votre WIFI! Souhaitez-vous activer WIFI?").setCancelable(false).setPositiveButton("Oui", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { Intent connectingoptionsintent = new Intent( android.provider.settings.action_wifi_settings); startactivity(connectingoptionsintent); ); builder.setnegativebutton("non", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { dialog.cancel();
); AlertDialog alert = builder.create(); alert.show(); //Gestion du menu public boolean oncreateoptionsmenu(menu menu) { MenuInflater inflater = getmenuinflater(); inflater.inflate(r.menu.menulistecategorie, menu); return true; public boolean onoptionsitemselected(menuitem item) { ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); switch (item.getitemid()) { case R.id.menuAccueil: Intent intent2 = new Intent(ViewBatiment.this, Home.class); startactivity(intent2); this.finish(); break; case R.id.menuPlus: Toast.makeText(this, "En construction", Toast.LENGTH_LONG).show(); break; case R.id.menuLocalisation: Intent intent = new Intent(ViewBatiment.this, Geolocalisation.class); startactivity(intent); this.finish(); break; case R.id.menuReglages: Intent intent3 = new Intent(ViewBatiment.this, Reglages.class); startactivity(intent3); this.finish(); break; return true; package com.ucampus; import java.util.arraylist; import android.app.activity; import android.app.alertdialog; import android.content.context; import android.content.dialoginterface; import android.content.intent; import android.location.locationmanager; import android.net.connectivitymanager; import android.net.networkinfo; import android.net.uri; import android.net.wifi.wifimanager; import android.os.bundle; import android.os.vibrator; import android.util.log; 70
import android.view.menu; import android.view.menuinflater; import android.view.menuitem; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.imagebutton; import android.widget.tabhost; import android.widget.tabhost.ontabchangelistener; import android.widget.tabhost.tabspec; import android.widget.textview; import android.widget.toast; import com.google.android.maps.geopoint; import com.google.android.maps.overlayitem; import com.ucampus.dao.batimentdao; import com.ucampus.dao.categoriedao; import com.ucampus.model.batiment; public class ViewBatiment extends Activity { private ArrayList<String> leslieux = new ArrayList<String>(); private String numerotelephone; private String uristring; private TabHost montabhost; 71 /** Called when the activity is first created. */ @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.viewbatiment); /** Ajout des onglets **/ montabhost = (TabHost) findviewbyid(r.id.tabhost01); montabhost.setup(); /** Ajout des 3 onglets **/ TabSpec spec = montabhost.newtabspec("onglet_info"); spec.setindicator("",getresources().getdrawable(r.drawable.info)); spec.setcontent(r.id.general_info); montabhost.addtab(spec); montabhost.addtab(montabhost.newtabspec("onglet_loc_maps").setindicat or("",getresources().getdrawable(r.drawable.map)).setcontent(r.id.loc_maps) ); montabhost.addtab(montabhost.newtabspec("onglet_autres").setindicator ("",getresources().getdrawable(r.drawable.plus)).setcontent(r.id.autres)); String batname = this.getintent().getextras().getstring("batname"); final BatimentDAO bbdd = new BatimentDAO(this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(this); cbdd.open(); final Batiment b = bbdd.getbatimentwithname(batname); //mise à jour du texte dans la fiche du batiment TextView tw = (TextView) findviewbyid(r.id.name); tw.settext(b.getname()); tw = (TextView) findviewbyid(r.id.numero);
tw.settext(b.getnumero()); numerotelephone = b.getnumero(); tw = (TextView) findviewbyid(r.id.ouverture); tw.settext(b.gethoraires()); tw = (TextView) findviewbyid(r.id.adresse); tw.settext(b.getadresse()); // url du site internet uristring = b.getsiteinternet(); // Mise à jour du label du bouton Button boutonsiteinternet = (Button) findviewbyid(r.id.siteinternet); //Si c'est un restaurant on changre le texte du bouton if (b.getidcategorie()==1){ boutonsiteinternet.settext("menu du RU"); else{ boutonsiteinternet.settext("site internet"); cbdd.close(); bbdd.close(); //Action lors du click sur le bouton de localisation d'un bâtiment ImageButton boutonlocalise = (ImageButton) findviewbyid(r.id.localise); boutonlocalise.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { //Test si le GPS est activé if (isgpson()) { //Test si la 3G est activée if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); Intent intent = new Intent(ViewBatiment.this, Geolocalisation.class); //Ajout de la catégorie de lieu à afficher dans les parametres du intent intent.putextra("categoriedelieux", cbdd.getcategoriebyid(b.getidcategorie()).getnamecategorie()); parametres du intent leslieux); leslieux.add(b.getname()); //Ajout des lieux à afficher dans les intent.putstringarraylistextra("lieu", cbdd.close(); bbdd.close(); //Vibrateur pour informer du click 72 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); else {
); creategpsdisabledalert(); //Affichage du site du bâtiment (ou du menu du RU) boutonsiteinternet.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ Log.e("internet","internet"+uriString); Uri intenturi = Uri.parse(uriString); Intent intent = new Intent(); intent.setaction(intent.action_view); intent.setdata(intenturi); ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); ); //lancement du mode itinéraire piéton ImageButton boutonitinerairepieton = (ImageButton) findviewbyid(r.id.itinerairepieton); boutonitinerairepieton.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (isgpson()) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); Intent intent = new Intent(ViewBatiment.this, Geolocalisation.class); intent.putextra("categoriedelieux", cbdd.getcategoriebyid(b.getidcategorie()).getnamecategorie()); b.getname()); "pieton"); intent.putextra("lieudestination", intent.putextra("modedeplacement", cbdd.close(); bbdd.close(); 73 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); else {
); creategpsdisabledalert(); //lancement du mode itinéraire voiture ImageButton boutonitinerairevoiture = (ImageButton) findviewbyid(r.id.itinerairevoiture); boutonitinerairevoiture.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (isgpson()) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); Intent intent = new Intent(ViewBatiment.this, Geolocalisation.class); intent.putextra("categoriedelieux", cbdd.getcategoriebyid(b.getidcategorie()).getnamecategorie()); b.getname()); "voiture"); intent.putextra("lieudestination", intent.putextra("modedeplacement", cbdd.close(); bbdd.close(); ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); else { creategpsdisabledalert(); ); //lancement du mode navigation piéton ImageButton boutonnavigationpieton = (ImageButton) findviewbyid(r.id.navigationpieton); boutonnavigationpieton.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (isgpson()) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); 74
CategorieDAO(ViewBatiment.this); final CategorieDAO cbdd = new cbdd.open(); GeoPoint point = new GeoPoint( Integer.parseInt(b.getLatitude()), Integer.parseInt(b.getLongitude())); OverlayItem(point, cbdd OverlayItem overlayitem = new.getcategoriebyid(b.getidcategorie()).getnamecategorie(), null); Intent(Intent.ACTION_VIEW, Uri Intent i = new.parse("google.navigation:q=" overlayitem.routableaddress() + "&mode=w")); cbdd.close(); bbdd.close(); + ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(i); else { creategpsdisabledalert(); ); //lancement du mode navigation voiture ImageButton boutonnavigationvoiture = (ImageButton) findviewbyid(r.id.navigationvoiture); boutonnavigationvoiture.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { if (isgpson()) { if (! is3gorwifion()) { create3gwifidisabledalert(); else{ final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); GeoPoint point = new GeoPoint( Integer.parseInt(b.getLatitude()), Integer.parseInt(b.getLongitude())); OverlayItem(point, cbdd OverlayItem overlayitem = new.getcategoriebyid(b.getidcategorie()).getnamecategorie(), null); 75
Intent(Intent.ACTION_VIEW, Uri Intent i = new.parse("google.navigation:q=" overlayitem.routableaddress())); cbdd.close(); bbdd.close(); + 76 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(i); else { creategpsdisabledalert(); ); //action pour téléphoner au bâtiment ImageButton boutontelephoner = (ImageButton) findviewbyid(r.id.boutontelephoner); boutontelephoner.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); final BatimentDAO bbdd = new BatimentDAO(ViewBatiment.this); bbdd.open(); final CategorieDAO cbdd = new CategorieDAO(ViewBatiment.this); cbdd.open(); startactivityforresult( new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + numerotelephone)), 1); cbdd.close(); bbdd.close(); ); // Test si le GPS est activé private Boolean isgpson() { LocationManager locmanager = (LocationManager) getsystemservice(location_service); if (!locmanager.isproviderenabled(locationmanager.gps_provider)) { return false; else { return true; // On informe l'utilisateur qu'il doit activer sa 3G ou son Wifi private void creategpsdisabledalert() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setmessage("votre GPS est désactivé! Souhaitez-vous l'activer?").setcancelable(false).setpositivebutton("oui", new DialogInterface.OnClickListener() {
public void onclick(dialoginterface dialog, int id) { Intent gpsoptionsintent = new Intent( 77 android.provider.settings.action_location_source_settings); startactivity(gpsoptionsintent); ); builder.setnegativebutton("non", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { dialog.cancel(); ); AlertDialog alert = builder.create(); alert.show(); // Test si l'acces à internet (WIFI ou 3G) est activé private Boolean is3gorwifion() { ConnectivityManager connectivitymanager = (ConnectivityManager) getsystemservice(context.connectivity_service); NetworkInfo networkinfo = connectivitymanager.getactivenetworkinfo(); if (networkinfo == null) { WifiManager wifi = (WifiManager) getsystemservice(context.wifi_service); if (!wifi.iswifienabled()) { return false; else { return true; else { return true; // On propose à l'utilisateur d'activer son gps private void create3gwifidisabledalert() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setmessage( "Veuillez activer votre 3G (manuellement) ou votre WIFI! Souhaitez-vous activer WIFI?").setCancelable(false).setPositiveButton("Oui", new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int id) { Intent connectingoptionsintent = new Intent( android.provider.settings.action_wifi_settings); startactivity(connectingoptionsintent); ); builder.setnegativebutton("non", new DialogInterface.OnClickListener() {
public void onclick(dialoginterface dialog, int id) { dialog.cancel(); ); AlertDialog alert = builder.create(); alert.show(); //Gestion du menu public boolean oncreateoptionsmenu(menu menu) { MenuInflater inflater = getmenuinflater(); inflater.inflate(r.menu.menulistecategorie, menu); return true; public boolean onoptionsitemselected(menuitem item) { ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); switch (item.getitemid()) { case R.id.menuAccueil: Intent intent2 = new Intent(ViewBatiment.this, Home.class); startactivity(intent2); this.finish(); break; case R.id.menuPlus: Toast.makeText(this, "En construction", Toast.LENGTH_LONG).show(); break; case R.id.menuLocalisation: Intent intent = new Intent(ViewBatiment.this, Geolocalisation.class); startactivity(intent); this.finish(); break; case R.id.menuReglages: Intent intent3 = new Intent(ViewBatiment.this, Reglages.class); startactivity(intent3); this.finish(); break; return true; 5.5 GEOLOCALISATION.JAVA : GEOLOCALISATION VIA GOOGLE MAPS package com.ucampus; import java.io.ioexception; import java.net.httpurlconnection; import java.net.malformedurlexception; import java.net.url; import java.util.arraylist; import java.util.list; import java.util.timer; import java.util.timertask; 78
import javax.xml.parsers.documentbuilder; import javax.xml.parsers.documentbuilderfactory; import javax.xml.parsers.parserconfigurationexception; import com.ucampus.myitemizedoverlay; import org.w3c.dom.document; import org.xml.sax.saxexception; import android.app.alertdialog; import android.app.dialog; import android.app.progressdialog; import android.content.context; import android.content.dialoginterface; import android.content.intent; import android.graphics.color; import android.graphics.drawable.drawable; import android.location.location; import android.location.locationlistener; import android.location.locationmanager; import android.net.connectivitymanager; import android.net.networkinfo; import android.net.uri; import android.net.wifi.wifimanager; import android.os.bundle; import android.os.vibrator; import android.text.editable; import android.text.textwatcher; import android.util.log; import android.widget.arrayadapter; import android.widget.autocompletetextview; import android.widget.button; import android.widget.imagebutton; import android.widget.radiobutton; import android.widget.toast; import android.view.menu; import android.view.menuinflater; import android.view.menuitem; import android.view.view; import android.view.view.onclicklistener; import com.google.android.maps.geopoint; import com.google.android.maps.mapactivity; import com.google.android.maps.mapcontroller; import com.google.android.maps.mapview; import com.google.android.maps.overlay; import com.google.android.maps.overlayitem; import com.ucampus.r; import com.ucampus.dao.batimentdao; import com.ucampus.dao.categoriedao; import com.ucampus.model.batiment; import com.ucampus.model.categorie; public class Geolocalisation extends MapActivity { 79 private MapController mapcontroller; private MapView mapview; private LocationManager locationmanager;
80 private MyItemizedOverlay myitemizedoverlay; private MyItemizedOverlay itemizedoverlaymetro; private MyItemizedOverlay itemizedoverlayrestaurant; private MyItemizedOverlay itemizedoverlaysante; private MyItemizedOverlay itemizedoverlaysport; private Drawable iconmoi; private Drawable metro; private Drawable restaurants; private Drawable sante; private Drawable sport; private List<Overlay> mapoverlays; private Button lieux; private Button reinitialiser; private Button localisemoi; private Button itineraire; private GeoPoint myposition=null; private static String[] batiments ; private OverlayItem myoverlayitem; private static int EARTH_RADIUS_KM = 6371; public static int MILLION = 1000000; private ProgressDialog myprogressdialog; public void oncreate(bundle bundle) { super.oncreate(bundle); setcontentview(r.layout.geolocalisation); mapview = (MapView) findviewbyid(r.id.mapview); mapview.setbuiltinzoomcontrols(true); // Autoriser StreetView mapview.setstreetview(true); // Représenter le traffic mapview.settraffic(true); mapcontroller = mapview.getcontroller(); mapcontroller.setzoom(16); // Icônes de chaque catégorie iconmoi = this.getresources().getdrawable(r.drawable.pegman); metro = this.getresources().getdrawable(r.drawable.metro); restaurants= this.getresources().getdrawable(r.drawable.cook); sante= this.getresources().getdrawable(r.drawable.health); sport = this.getresources().getdrawable(r.drawable.sports); // Liste des bâtiments que l'utilisateur souhaite afficher myitemizedoverlay= new MyItemizedOverlay(iconMoi,mapView); itemizedoverlaymetro= new MyItemizedOverlay(metro,mapView); itemizedoverlayrestaurant= new MyItemizedOverlay(restaurants,mapView); itemizedoverlaysante = new MyItemizedOverlay(sante,mapView); itemizedoverlaysport = new MyItemizedOverlay(sport,mapView); // On recuperer tous les bâtiments de la BDD pour l'autocompression dans la popup d'itineraire et de navigation final BatimentDAO bbdd1 = new BatimentDAO(this); bbdd1.open(); ArrayList<Batiment> allb = bbdd1.getallbatiment(); final ArrayList<String> allbname = new ArrayList<String>(); for (Batiment b : allb) { allbname.add(b.getname());
batiments = new String[allBName.size()]; allbname.toarray(batiments); bbdd1.close(); locateme(); initbutton(); // Afficher les lieux choisis try{ addpoint(this.getintent().getextras().getstring("categoriedelieux"),t his.getintent().getstringarraylistextra("lieu")); catch (NullPointerException ex){ // itineraire try{ String destination = this.getintent().getextras().getstring("lieudestination"); String categoriedelieux = this.getintent().getextras().getstring("categoriedelieux"); String modedeplacement = this.getintent().getextras().getstring("modedeplacement"); final BatimentDAO bbdd = new BatimentDAO(this); bbdd.open(); Batiment b = bbdd.getbatimentwithname(destination); GeoPoint point = new GeoPoint(Integer.parseInt(b.getLatitude()),Integer.parseInt(b.getLongitude( ))); bbdd.close(); add1point(categoriedelieux,destination); //Trace le trait DrawPath(myPosition,point,Color.BLUE,mapView,modeDeplacement); catch (NullPointerException ex){ // Initialisation des buttons private void initbutton() { // Afficher la catégorie des lieux this.lieux = (Button)this.findViewById(R.id.lieux); this.lieux.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { Intent intent = new Intent(Geolocalisation.this, CatList.class); 81 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); startactivity(intent); ); // Afficher la popup d'itineraire ou de navigation this.itineraire = (Button)this.findViewById(R.id.itineraire); this.itineraire.setonclicklistener(new OnClickListener() {
public void onclick(view arg0) { ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); createpopupitineraire(); ); //Me localiser : centrer la carte sur ma position this.localisemoi = (Button)this.findViewById(R.id.localiseMoi); this.localisemoi.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { // TODO Auto-generated method stub ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); if (myposition!= null){ Toast.makeText(Geolocalisation.this, "Ma position", Toast.LENGTH_SHORT).show(); locateme(); ); //Réinitialiser la carte this.reinitialiser = (Button)this.findViewById(R.id.reinitialiser); this.reinitialiser.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { 82 ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(100); deleteallpoints(); ); // Creer la popup pour l'itineraire ou la naviagation public void createpopupitineraire() { Context mcontext = Geolocalisation.this; final Dialog dialog = new Dialog(mContext); dialog.setcontentview(r.layout.itineraire); dialog.settitle("détermination de l'itinéraire"); //Auto compression sur les bâtiments AutoCompleteTextView textview = (AutoCompleteTextView) dialog.findviewbyid(r.id.autocomplete_country); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.r.layout.simple_dropdown_item_1line, batiments); textview.setadapter(adapter); Button annuler = (Button) dialog.findviewbyid(r.id.buttonannuler); annuler.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { dialog.cancel();
); //Récupération des informations pour la navigation mode destination Button navigation = (Button)dialog.findViewById(R.id.ButtonNavigation); navigation.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { RadioButton radiobuttonpieton, radiobuttonvoiture; radiobuttonpieton = (RadioButton)dialog.findViewById(R.id.RadioButtonPieton); radiobuttonvoiture = (RadioButton)dialog.findViewById(R.id.RadioButtonVoiture); Editable destination =((AutoCompleteTextView) dialog.findviewbyid(r.id.autocomplete_country)).gettext(); if ((destination == null) (destination.length() == 0)){ Toast.makeText(Geolocalisation.this, "Veuillez renseigner la destination!", Toast.LENGTH_LONG).show(); else{ final BatimentDAO bbdd = new BatimentDAO(Geolocalisation.this); bbdd.open(); Batiment b = bbdd.getbatimentwithname(destination.tostring()); if (b!= null){ dialog.cancel(); //Lancer Google Navigation (GPS) if(radiobuttonpieton.ischecked()){ navigation("pieton",destination); else{ 83 navigation("voiture",destination); else{ destination.clear(); Toast.makeText(Geolocalisation.this, "Destination inconnue! Veuillez sélectionner votre destination dans la liste des lieux proposés.", Toast.LENGTH_LONG).show(); ); //Manque : effacer les anciens itineraires! // Afficher itineraire sur la carte via un trait bleu Button itinerairemaps = (Button)dialog.findViewById(R.id.ButtonItineraire); itinerairemaps.setonclicklistener(new OnClickListener() { public void onclick(view arg0) { //Mode de déplacement RadioButton radiobuttonpieton, radiobuttonvoiture; radiobuttonpieton = (RadioButton)dialog.findViewById(R.id.RadioButtonPieton);
radiobuttonvoiture = (RadioButton)dialog.findViewById(R.id.RadioButtonVoiture); Editable destination =((AutoCompleteTextView) dialog.findviewbyid(r.id.autocomplete_country)).gettext(); if ((destination == null) (destination.length() == 0)){ Toast.makeText(Geolocalisation.this, "Veuillez renseigner la destination!", Toast.LENGTH_LONG).show(); else{ final BatimentDAO bbdd = new BatimentDAO(Geolocalisation.this); bbdd.open(); if (bbdd.getbatimentwithname(destination.tostring())!= null){ dialog.cancel(); try{ myprogressdialog = ProgressDialog.show(Geolocalisation.this,"Calcul de l'itinéraire en cours...", "Recherche du parcours le plus rapide...", true); Batiment b = bbdd.getbatimentwithname(destination.tostring()); GeoPoint point = new GeoPoint(Integer.parseInt(b.getLatitude()),Integer.parseInt(b.getLongitude( ))); bbdd.close(); CategorieDAO cbdd = new CategorieDAO(Geolocalisation.this); cbdd.open(); Categorie categorie = cbdd.getcategoriebyid(b.getidcategorie()); cbdd.close(); //Ajout du bâtiment de destination sur la carte add1point(categorie.getnamecategorie(),destination.tostring()); if(radiobuttonvoiture.ischecked()){ DrawPath(myPosition,point,Color.BLUE,mapView,"voiture"); else{ DrawPath(myPosition,point,Color.BLUE,mapView,"pieton"); catch (Exception e) { // Dismiss the Dialog myprogressdialog.dismiss(); else{ bbdd.close(); destination.clear(); Toast.makeText(Geolocalisation.this, "Destination inconnue! Veuillez sélectionner votre destination dans la liste des lieux proposés.", Toast.LENGTH_LONG).show(); ); dialog.show(); 84
// Lance google navigation (GPS) avec l'adresse de destination et le mode de déplacement public void navigation(string mode, Editable destination) { Intent i; final BatimentDAO bbdd = new BatimentDAO(Geolocalisation.this); bbdd.open(); Batiment b = bbdd.getbatimentwithname(destination.tostring()); GeoPoint point = new GeoPoint(Integer.parseInt(b.getLatitude()),Integer.parseInt(b.getLongitude( ))); bbdd.close(); CategorieDAO cbdd = new CategorieDAO(Geolocalisation.this); cbdd.open(); Categorie categorie = cbdd.getcategoriebyid(b.getidcategorie()); cbdd.close(); OverlayItem overlayitem = new OverlayItem(point, categorie.getnamecategorie(),null); if(mode=="pieton"){ i = new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=" + overlayitem.routableaddress()+"&mode=w")); else{ i = new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=" + overlayitem.routableaddress())); startactivity(i); 85 // Creation du menu public boolean oncreateoptionsmenu(menu menu) { MenuInflater inflater = getmenuinflater(); inflater.inflate(r.menu.menugeolocalisation, menu); return true; //Appeler lors d'un click sur le menu public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case R.id.menuPlus: Toast.makeText(this, "En construction", Toast.LENGTH_LONG).show(); break; case R.id.menuLieux: Intent intent = new Intent(Geolocalisation.this, CatList.class); startactivity(intent); break; case R.id.menuItineraire: createpopupitineraire(); break; case R.id.menuReinitialiser: deleteallpoints(); break; case R.id.menuReglages: Intent intent2 = new Intent(Geolocalisation.this, Reglages.class); startactivity(intent2); break;
return true; // Localise moi : On enregistre ma position dans le GeoPoint myposition on met un listener sur le locationmanager pour que lorsqu'on bouge de au minimun 2 m // on met à jour myposition [onlocationchanged(location location)] private void locateme() { locationmanager = (LocationManager) getsystemservice(context.location_service); 1, locationmanager.requestlocationupdates(locationmanager.gps_provider, 1, new GeoUpdateHandler()); mapoverlays = mapview.getoverlays(); if (locationmanager.getlastknownlocation(locationmanager.gps_provider)!= null){ int lat = (int) (locationmanager.getlastknownlocation(locationmanager.gps_provider).getlati tude() * 1E6); int lng = (int) (locationmanager.getlastknownlocation(locationmanager.gps_provider).getlong itude() * 1E6); myposition = new GeoPoint(lat, lng); myoverlayitem = new OverlayItem(myPosition, "Moi",null); myitemizedoverlay.addoverlay(myoverlayitem); mapoverlays.add(myitemizedoverlay); mapcontroller.animateto(myposition); // Dessine un trait entre 2 points private void DrawPath(GeoPoint src,geopoint dest, int color, MapView mmapview01, String modededeplacement) { // connect to map web service StringBuilder urlstring = new StringBuilder(); if(modededeplacement.equals("pieton")){ w"); urlstring.append("http://maps.google.com/maps?f=d&hl=fr&via=1&dirflg= else{ urlstring.append("http://maps.google.com/maps?f=d&hl=fr&"); // urlstring.append("http://maps.google.com/maps?f=d&hl=fr&"); urlstring.append("&saddr=");//from urlstring.append( Double.toString((double)src.getLatitudeE6()/1.0E6 )); urlstring.append(","); urlstring.append( Double.toString((double)src.getLongitudeE6()/1.0E6 )); 86
urlstring.append("&daddr=");//to urlstring.append( Double.toString((double)dest.getLatitudeE6()/1.0E6 )); urlstring.append(","); urlstring.append( Double.toString((double)dest.getLongitudeE6()/1.0E6 )); urlstring.append("&ie=utf8&0&om=0&output=kml"); // get the kml (XML) doc. And parse it to get the coordinates(direction route). Document doc = null; HttpURLConnection urlconnection= null; URL url = null; try { url = new URL(urlString.toString()); urlconnection=(httpurlconnection)url.openconnection(); urlconnection.setrequestmethod("get"); urlconnection.setdooutput(true); urlconnection.setdoinput(true); urlconnection.connect(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newdocumentbuilder(); doc = db.parse(urlconnection.getinputstream()); if(doc.getelementsbytagname("geometrycollection").getlength()>0) { //String path = doc.getelementsbytagname("geometrycollection").item(0).getfirstchild().getf irstchild().getnodename(); String path = doc.getelementsbytagname("geometrycollection").item(0).getfirstchild().getf irstchild().getfirstchild().getnodevalue() ; String [] pairs = path.split(" "); String[] lnglat = pairs[0].split(","); // lnglat[0]=longitude lnglat[1]=latitude lnglat[2]=height // src GeoPoint startgp = new GeoPoint((int)(Double.parseDouble(lngLat[1])*1E6),(int)(Double.parseDouble( lnglat[0])*1e6)); // mmapview01.getoverlays().add(new MyOverLay(startGP,startGP,1)); GeoPoint gp1; GeoPoint gp2 = startgp; for(int i=1;i<pairs.length;i++) // the last one would be crash { lnglat = pairs[i].split(","); gp1 = gp2; // watch out! For GeoPoint, first:latitude, second:longitude gp2 = new GeoPoint((int)(Double.parseDouble(lngLat[1])*1E6),(int)(Double.parseDouble( lnglat[0])*1e6)); mmapview01.getoverlays().add(new MyOverLay(gp1,gp2,2,color)); 87
// mmapview01.getoverlays().add(new MyOverLay(dest,dest, 3)); // use the default color distancekm(myposition, dest); catch (MalformedURLException e) { e.printstacktrace(); catch (IOException e) { e.printstacktrace(); catch (ParserConfigurationException e) { e.printstacktrace(); catch (SAXException e) { e.printstacktrace(); /** * Computes the distance in kilometers between two points on Earth. * * @param lat1 Latitude of the first point * @param lon1 Longitude of the first point * @param lat2 Latitude of the second point * @param lon2 Longitude of the second point * @return Distance between the two points in kilometers. */ public static double distancekm(double lat1, double lon1, double lat2, double lon2) { double lat1rad = Math.toRadians(lat1); double lat2rad = Math.toRadians(lat2); double deltalonrad = Math.toRadians(lon2 - lon1); return Math.acos(Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad)) * EARTH_RADIUS_KM; Earth. /** * Computes the distance in kilometers between two points on * * @param p1 First point * @param p2 Second point * @return Distance between the two points in kilometers. */ public void distancekm(geopoint p1, GeoPoint p2) { double lat1 = p1.getlatitudee6() / (double)million; double lon1 = p1.getlongitudee6() / (double)million; double lat2 = p2.getlatitudee6() / (double)million; double lon2 = p2.getlongitudee6() / (double)million; 88
double distancetotale = distancekm(lat1, lon1, lat2, lon2); String distancetotalestring= (distancetotale+"").substring(0, 4); Toast.makeText(this, "Distance : " + distancetotalestring + " km.", Toast.LENGTH_SHORT).show(); // Réinitialisation des objetcs contenant les bâtiments public void deleteallpoints() { mapoverlays.remove(itemizedoverlaymetro); mapoverlays.remove(itemizedoverlayrestaurant); mapoverlays.remove(itemizedoverlaysante); mapoverlays.remove(itemizedoverlaysport); itemizedoverlaymetro.removeoverlayall(); itemizedoverlayrestaurant.removeoverlayall(); itemizedoverlaysante.removeoverlayall(); itemizedoverlaysport.removeoverlayall(); super.finish(); Intent intent = new Intent(Geolocalisation.this,Geolocalisation.class); startactivity(intent); // Ajout des bâtiments à afficher dans la liste public void addpoint(string lieuxaafficher,arraylist<string> leslieux) { // On recupere tous les lieux pour les afficher mapoverlays = mapview.getoverlays(); OverlayItem overlayitem ; GeoPoint point = null ; final BatimentDAO batbdd = new BatimentDAO(this); batbdd.open(); for (String lieu : leslieux) { Batiment b = batbdd.getbatimentwithname(lieu); point = new GeoPoint(Integer.parseInt(b.getLatitude()),Integer.parseInt(b.getLongitude( ))); if(lieuxaafficher.equals("metros")){ overlayitem = new OverlayItem(point, "Métro",lieu); itemizedoverlaymetro.addoverlay(overlayitem); else if(lieuxaafficher.equals("restaurants")){ overlayitem = new OverlayItem(point, "Restaurant",lieu); itemizedoverlayrestaurant.addoverlay(overlayitem); else if (lieuxaafficher.equals("santé")){ overlayitem = new OverlayItem(point, "Santé",lieu); itemizedoverlaysante.addoverlay(overlayitem); else if (lieuxaafficher.equals("salle de sport")){ overlayitem = new OverlayItem(point, "Salle de sport",lieu); itemizedoverlaysport.addoverlay(overlayitem); 89 batbdd.close(); if(lieuxaafficher.equals("metros")){ mapoverlays.add(itemizedoverlaymetro);
else if(lieuxaafficher.equals("restaurants")){ mapoverlays.add(itemizedoverlayrestaurant); else if(lieuxaafficher.equals("santé")){ mapoverlays.add(itemizedoverlaysante); else if(lieuxaafficher.equals("salle de sport")){ mapoverlays.add(itemizedoverlaysport); if (point!= null){ mapcontroller.animateto(point); // Ajouter le lieu de la destination de l'itineraire public void add1point(string lieuxaafficher,string lelieu) { // On recupere le lieu pour l'afficher mapoverlays = mapview.getoverlays(); OverlayItem overlayitem ; final BatimentDAO bbdd = new BatimentDAO(this); bbdd.open(); Batiment b = bbdd.getbatimentwithname(lelieu); GeoPoint point = new GeoPoint(Integer.parseInt(b.getLatitude()),Integer.parseInt(b.getLongitude( ))); //Ajout du batiment de destination dans la bonne liste if(lieuxaafficher.equals("metros")){ overlayitem = new OverlayItem(point, "Métro",leLieu); itemizedoverlaymetro.addoverlay(overlayitem); else if(lieuxaafficher.equals("restaurants")){ overlayitem = new OverlayItem(point, "Restaurant",leLieu); itemizedoverlayrestaurant.addoverlay(overlayitem); else if(lieuxaafficher.equals("santé")){ overlayitem = new OverlayItem(point, "Santé",leLieu); itemizedoverlaysante.addoverlay(overlayitem); else if (lieuxaafficher.equals("salle de sport")){ overlayitem = new OverlayItem(point, "Salle de sport",lelieu); itemizedoverlaysport.addoverlay(overlayitem); 90 if(lieuxaafficher.equals("metros")){ mapoverlays.add(itemizedoverlaymetro); else if(lieuxaafficher.equals("restaurants")){ mapoverlays.add(itemizedoverlayrestaurant); else if(lieuxaafficher.equals("santé")){ mapoverlays.add(itemizedoverlaysante); else if(lieuxaafficher.equals("salle de sport")){ mapoverlays.add(itemizedoverlaysport); bbdd.close(); //Centrer la carte sur le bâtiment de destination mapcontroller.animateto(myposition); @Override protected boolean isroutedisplayed() { return false; // Classe interne qui permet de mettre à jour sa position quand les coordonées GPS changent
public class GeoUpdateHandler implements LocationListener { // Mise à jour de myposition public void onlocationchanged(location location) { mapoverlays = mapview.getoverlays(); if (myposition!= null) { myitemizedoverlay.removeoverlay(myoverlayitem); mapoverlays.remove(myitemizedoverlay); int lat = (int) (location.getlatitude() * 1E6); int lng = (int) (location.getlongitude() * 1E6); myposition = new GeoPoint(lat, lng); myoverlayitem = new OverlayItem(myPosition, "Moi",null); myitemizedoverlay.addoverlay(myoverlayitem); mapoverlays.add(myitemizedoverlay); // mapcontroller.animateto(myposition); mapcontroller.setcenter(point); public void onproviderdisabled(string provider) { public void onproviderenabled(string provider) { extras) { public void onstatuschanged(string provider, int status, Bundle 5.6 MYITEMIZEDOVERLAY.JAVA : CONTIENT LES OVERLAY D UNE CATEGORIE package com.ucampus; import java.util.arraylist; import android.content.context; import android.graphics.drawable.drawable; import android.widget.toast; import com.google.android.maps.mapview; import com.google.android.maps.overlayitem; import com.ucampus.balloonitemizedoverlay; // Liste des OverlayItem d'une categorie // 1 catégorie = 1 MyItemizedOverlay donc = 1 liste d'overlayitem public class MyItemizedOverlay extends BalloonItemizedOverlay<OverlayItem> { private ArrayList<OverlayItem> m_overlays = new ArrayList<OverlayItem>(); private Context c; public MyItemizedOverlay(Drawable defaultmarker, MapView mapview) { super(boundcenter(defaultmarker), mapview); c = mapview.getcontext(); 91
// add OverlayItems to the ArrayList public void addoverlay(overlayitem overlay) { m_overlays.add(overlay); populate(); @Override protected OverlayItem createitem(int i) { return m_overlays.get(i); // remove OverlayItems to the ArrayList public void removeoverlay(overlayitem overlay) { m_overlays.remove(overlay); populate(); // remove all OverlayItems to the ArrayList public void removeoverlayall() { m_overlays.clear(); populate(); @Override public int size() { return m_overlays.size(); @Override protected boolean onballoontap(int index) { // Toast.makeText(c, "onballoontap for overlay index " + index, // Toast.LENGTH_LONG).show(); return true; 5.7 BALLOONITEMIZEDOVERLAY.JAVA : APPARAIT LORS D UN CLICK SUR UN BATIMENT package com.ucampus; import java.lang.reflect.method; import java.util.list; import android.graphics.drawable.drawable; import android.util.log; import android.view.motionevent; import android.view.view; import android.view.view.ontouchlistener; import android.view.viewgroup.layoutparams; import com.google.android.maps.geopoint; import com.google.android.maps.itemizedoverlay; import com.google.android.maps.mapcontroller; import com.google.android.maps.mapview; import com.google.android.maps.overlay; 92
import com.google.android.maps.overlayitem; public abstract class BalloonItemizedOverlay<Item> extends ItemizedOverlay<OverlayItem> { private MapView mapview; private BalloonOverlayView balloonview; private View clickregion; private int viewoffset; final MapController mc; /** * Create a new BalloonItemizedOverlay * * @param defaultmarker - A bounded Drawable to be drawn on the map for each item in the overlay. * @param mapview - The view upon which the overlay items are to be drawn. */ public BalloonItemizedOverlay(Drawable defaultmarker, MapView mapview) { super(defaultmarker); this.mapview = mapview; viewoffset = 0; mc = mapview.getcontroller(); /** * Set the horizontal distance between the marker and the bottom of the information * balloon. The default is 0 which works well for center bounded markers. If your * marker is center-bottom bounded, call this before adding overlay items to ensure * the balloon hovers exactly above the marker. * * @param pixels - The padding between the center point and the bottom of the * information balloon. */ public void setballoonbottomoffset(int pixels) { viewoffset = pixels; /** * Override this method to handle a "tap" on a balloon. By default, does nothing * and returns false. * * @param index - The index of the item whose balloon is tapped. * @return true if you handled the tap, otherwise false. */ protected boolean onballoontap(int index) { return false; 93 /* (non-javadoc) * @see com.google.android.maps.itemizedoverlay#ontap(int) */
@Override protected final boolean ontap(int index) { boolean isrecycled; final int thisindex; GeoPoint point; thisindex = index; point = createitem(index).getpoint(); if (balloonview == null) { balloonview = new BalloonOverlayView(mapView.getContext(), viewoffset); clickregion = (View) balloonview.findviewbyid(r.id.balloon_inner_layout); isrecycled = false; else { isrecycled = true; balloonview.setvisibility(view.gone); List<Overlay> mapoverlays = mapview.getoverlays(); if (mapoverlays.size() > 1) { hideotherballoons(mapoverlays); balloonview.setdata(createitem(index)); MapView.LayoutParams params = new MapView.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, point, MapView.LayoutParams.BOTTOM_CENTER); params.mode = MapView.LayoutParams.MODE_MAP; setballoontouchlistener(thisindex); balloonview.setvisibility(view.visible); if (isrecycled) { balloonview.setlayoutparams(params); else { mapview.addview(balloonview, params); mc.animateto(point); return true; /** * Sets the visibility of this overlay's balloon view to GONE. */ private void hideballoon() { if (balloonview!= null) { balloonview.setvisibility(view.gone); /** 94
* Hides the balloon view for any other BalloonItemizedOverlay instances * that might be present on the MapView. * * @param overlays - list of overlays (including this) on the MapView. */ private void hideotherballoons(list<overlay> overlays) { for (Overlay overlay : overlays) { if (overlay instanceof BalloonItemizedOverlay<?> && overlay!= this) { ((BalloonItemizedOverlay<?>) overlay).hideballoon(); the /** * Sets the ontouchlistener for the balloon being displayed, calling * overridden onballoontap if implemented. * * @param thisindex - The index of the item whose balloon is tapped. */ private void setballoontouchlistener(final int thisindex) { try { @SuppressWarnings("unused") Method m = this.getclass().getdeclaredmethod("onballoontap", int.class); clickregion.setontouchlistener(new OnTouchListener() { public boolean ontouch(view v, MotionEvent event) { View l = ((View) v.getparent()).findviewbyid(r.id.balloon_main_layout); Drawable d = l.getbackground(); if (event.getaction() == MotionEvent.ACTION_DOWN) { int[] states = {android.r.attr.state_pressed; if (d.setstate(states)) { d.invalidateself(); return true; else if (event.getaction() == MotionEvent.ACTION_UP) { int newstates[] = {; if (d.setstate(newstates)) { d.invalidateself(); // call overridden method onballoontap(thisindex); return true; else { return false; 95
); catch (SecurityException e) { Log.e("BalloonItemizedOverlay", "setballoontouchlistener reflection SecurityException"); return; catch (NoSuchMethodException e) { // method not overridden - do nothing return; 5.8 BALLOONOVERLAYVIEW.JAVA : REPRESENTE LE MARKER LORS D UN CLICK SUR UN BATIMENT package com.ucampus; import android.app.listactivity; import android.content.context; import android.content.intent; import android.view.gravity; import android.view.layoutinflater; import android.view.view; import android.widget.framelayout; import android.widget.imageview; import android.widget.linearlayout; import android.widget.textview; import android.widget.toast; import com.google.android.maps.overlayitem; /** * A view representing a MapView marker information balloon. * */ public class BalloonOverlayView extends FrameLayout { private LinearLayout layout; private TextView title; private TextView snippet; private TextView detail; private Context c; /** * Create a new BalloonOverlayView. * * @param context - The activity context. * @param balloonbottomoffset - The bottom padding (in pixels) to be applied * when rendering this view. */ public BalloonOverlayView(Context context, int balloonbottomoffset) { 96 super(context); c= context; setpadding(10, 0, 10, balloonbottomoffset); layout = new LinearLayout(context); layout.setvisibility(visible);
97 LayoutInflater inflater = (LayoutInflater) context.getsystemservice(context.layout_inflater_service); View v = inflater.inflate(r.layout.balloon_overlay, layout); title = (TextView) v.findviewbyid(r.id.balloon_item_title); snippet = (TextView) v.findviewbyid(r.id.balloon_item_snippet); ImageView close = (ImageView) v.findviewbyid(r.id.close_img_button); close.setonclicklistener(new OnClickListener() { public void onclick(view v) { layout.setvisibility(gone); ); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.gravity = Gravity.NO_GRAVITY; addview(layout, params); /** * Sets the view data from a given overlay item. * * @param item - The overlay item containing the relevant view data * (title and snippet). */ public void setdata(final OverlayItem item) { layout.setvisibility(visible); if (item.gettitle()!= null) { title.setvisibility(visible); title.settext(item.gettitle()); else { title.setvisibility(gone); if (item.getsnippet()!= null) { snippet.setvisibility(visible); if (title.gettext().equals("moi")){ snippet.settext(item.getsnippet()); else{ snippet.settext(item.getsnippet()+ " "+ ">> Plus de détails"); snippet.setonclicklistener(new OnClickListener() { public void onclick(view v) { //Ouvre la fiche détaillée Intent intent = new Intent(c, ViewBatiment.class); intent.putextra("batname", item.getsnippet()); c.startactivity(intent); ); else { snippet.setvisibility(gone);
5.9 MYOVERLAY.JAVA : REPRESENTE UNE SUPERPOSITION SUR LA CARTE package com.ucampus; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.point; import android.graphics.rectf; import android.util.log; import com.google.android.maps.geopoint; import com.google.android.maps.mapview; import com.google.android.maps.overlay; import com.google.android.maps.projection; // Base class representing an overlay which may be displayed on top of a map. public class MyOverLay extends Overlay { private GeoPoint gp1; private GeoPoint gp2; private int mradius=6; private int mode=0; private int defaultcolor; private String text=""; private Bitmap img = null; public MyOverLay(GeoPoint gp1,geopoint gp2,int mode) // GeoPoint is a int. (6E) { this.gp1 = gp1; this.gp2 = gp2; this.mode = mode; defaultcolor = 999; // no defaultcolor public MyOverLay(GeoPoint gp1,geopoint gp2,int mode, int defaultcolor) { this.gp1 = gp1; this.gp2 = gp2; this.mode = mode; this.defaultcolor = defaultcolor; 98 public void settext(string t) { this.text = t; public void setbitmap(bitmap bitmap) {
this.img = bitmap; public int getmode() { return mode; @Override public boolean draw(canvas canvas, MapView mapview, boolean shadow, long when) { Projection projection = mapview.getprojection(); if (shadow == false) { Paint paint = new Paint(); paint.setantialias(true); Point point = new Point(); projection.topixels(gp1, point); // mode=1 start if(mode==1) { if(defaultcolor==999) paint.setcolor(color.blue); else paint.setcolor(defaultcolor); RectF oval=new RectF(point.x - mradius, point.y - mradius, point.x + mradius, point.y + mradius); // start point canvas.drawoval(oval, paint); // mode=2 path else if(mode==2) { if(defaultcolor==999){ paint.setcolor(color.red); else{ paint.setcolor(defaultcolor); Point point2 = new Point(); projection.topixels(gp2, point2); paint.setstrokewidth(5); paint.setalpha(120); canvas.drawline(point.x, point.y, point2.x,point2.y, paint); /* mode=3 end */ else if(mode==3) { /* the last path */ if(defaultcolor==999){ paint.setcolor(color.green); else{ paint.setcolor(defaultcolor); Point point2 = new Point(); projection.topixels(gp2, point2); paint.setstrokewidth(5); paint.setalpha(120); 99
canvas.drawline(point.x, point.y, point2.x,point2.y, paint); RectF oval=new RectF(point2.x - mradius,point2.y - mradius, point2.x + mradius,point2.y + mradius); /* end point */ paint.setalpha(255); canvas.drawoval(oval, paint); return super.draw(canvas, mapview, shadow, when); 100
6. TUTORIAL 6.1 CREER UNE CATEGORIE DE BATIMENT Procédure à suivre lors de l ajout d une catégorie dans la base de données: (En rouge ce qu il faut ajouter): 1. Creer la catégorie dans la classe InsertBDD.java if (cbdd.getallcategories() == null) { Categorie cat;... cat = new Categorie("Salle de sport","sports"); cbdd.insertcategorie(cat); cat = new Catégorie ( NOM CATEGORIE, NOM ICONE ); cbdd.insertcategorie(cat); Il faut ajouter l icône renseigné lors de la création dans les répertoires res\drawable-hdpi, res\drawable-ldpi et res\drawable-mdpi 2. Affecter des bâtiments à cette catégorie if (bbdd.getallbatiment()== null) { Batiment b; // Restaurants Universitaire b = new Batiment(1,1,"Le Barrois","03 20 33 61 23","11h15 à 13h30 ","imgm5","cité Scientifique","50611027","3144468","http://www.crous-lille.fr/adminsite/restauration_menu_print_w.php?ru=26&midi=1&soir=1&nb_w=2"); bbdd.insertbatiment(b); b = new Batiment(ID_DE LA CATEGORIE,ID DU BATIMENT,NOM,TELEPHONE,HORAIRES,IMAGE,ADRESSE,LATITUDE GPS,LONGITUDE GPS,SITE INTERNET); bbdd.insertbatiment(b); 3. Création des objets dans la classe Géolocalisation.java Dans les variables de la classe, il faut créer un objet Drawable et un objet MyItemizedOverlay. Dans la méthode oncreate, il faut renseigner les valeurs de ces objets : iconcategorie= this.getresources().getdrawable(r.drawable.icone CATEGORIE); 101
myitemizedoverlay= new MyItemizedOverlay(iconCategorie,mapView); Il faut compléter les méthodes addpoint et add1point par l ajout du MyItemizedOverlay crée : if(lieuxaafficher.equals("metros")){ overlayitem = new OverlayItem(point, "Métro",lieu); itemizedoverlaymetro.addoverlay(overlayitem); else if(lieuxaafficher.equals("nom CATEGORIE")){ overlayitem = new OverlayItem(point, "NOM CATEGORIE",lieu); myitemizedoverlay.addoverlay(overlayitem); if(lieuxaafficher.equals("metros")){ mapoverlays.add(itemizedoverlaymetro); else if(lieuxaafficher.equals("nom CATEGORIE")){ mapoverlays.add(myitemizedoverlay); Et pour finir il faut ajouter deux lignes dans la méthode deleteallpoints() pour supprimer les lieux: mapoverlays.remove(myitemizedoverlay); myitemizedoverlay.removeoverlayall(); 102