TP02 Le gestionnaire de téléchargements I. Création de l`interface
Transcription
TP02 Le gestionnaire de téléchargements I. Création de l`interface
M2-SILI Développement sous Android TP02 année 2016/2017 Le gestionnaire de téléchargements Pour ce TP il est demandé de réaliser un gestionnaire de téléchargements. L'utilisateur pourra saisir les URLs des fichiers à télécharger. Le téléchargement se fait en tâche de fond. Il doit être possible de visualiser les fichiers dont le téléchargement est terminé si il est pris en charge par une application installée. I. Création de l'interface L'interface principale est assez simple, elle est composée d'une liste d'éléments. Chaque élément correspond à un fichier dont le téléchargement est en cours ou terminé. Chaque élément de la liste est rendu par le procédé d'inflation comme pour les TPs précédents. Toutefois, l'apparence d'un fichier en cours de téléchargement est différente d'un fichier dont le téléchargement est terminé. Les copies d'écran suivantes montrent des cas pour lesquels les fichiers sont complètement téléchargés. Vous trouverez au point II du TP une copie d'écran pour un fichier en cours de téléchargement. Observez que dans le dernier cas, une ProgressBar apparaît en plus. Il est demandé d'ajouter un menu d'options permettant de saisir les URLs des fichiers à télécharger. Lorsque l'utilisateur appuie sur l'option d'ajout de « Nouvelle URL », une boîte de dialogue apparaît pour demander à l'utilisateur la nouvelle URL du fichier à télécharger. Celui-ci est ajouté à la liste des fichiers en cours de téléchargement. De manière à bien gérer l'inflation des éléments de la liste, il est conseillé de créer son propre « Adapter » appelé par la suite URLAdapter. Cet URLAdapter utilise (par composition) des éléments instanciés à partir de la classe URLItem qu'il faut créer. Chaque élément instancié à partir cette classe possède les informations nécessaires au téléchargement du fichier (URL, taille du fichier, nom du fichier destinataire sur le disque, etc...). Ces informations sont importantes pour pouvoir accéder au fichier et suivre la progression du téléchargement. 1/4 M2-SILI Développement sous Android année 2016/2017 II. Gestion du téléchargement en tâche de fond Pour ne pas bloquer le thread de l'interface graphique, les téléchargements s'effectuent en tâche de fond. Pour cela il faut créer une sous classe de AsyncTask dont les méthodes pour doInBackground() et UpdateProgress() et onPostExecute() prennent URLItem comme argument. À chaque fois qu'une nouvelle URL est ajoutée, une nouvelle tâche de fond est créée. La barre de progression de l'interface est mise à jour en fonction de la progression du téléchargement. Lorsque le téléchargement du fichier est terminé, un Toast apparaît pour indiquer la fin à l'utilisateur. L'interface de la liste change pour faire disparaître la barre de progression ainsi que pour modifier le texte sur la droite comme sur la copie d'écran ci-dessus. Pour vous aider dans la réalisation du téléchargement d'un fichier, vous pouvez vous inspirer du code suivant qui assure le téléchargement d'un flux : try { URL url = new URL(Chaîne de l'URL); URLConnection connection = url.openConnection(); connection.connect(); long totalSize = connection.getContentLength(); InputStream input = new BufferedInputStream(url.openStream()); OutputStream output = new FileOutputStream(Fichier sur le disque dur); byte data[] = new byte[1024]; int count; while ((count = input.read(data)) != -1) { output.write(data, 0, count); } output.flush(); output.close(); input.close(); 2/4 M2-SILI Développement sous Android année 2016/2017 } catch (Exception e) { Log.v("DownloadManager","Exception lors du téléchargement."); } Il faut de plus penser à attribuer des permissions supplémentaires à votre application pour qu'elle puisse accéder à Internet et écrire sur l'unité de stockage : <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET" /> Attention, lors de l'ajout de plusieurs URLs simultanément, vous pouvez vous apercevoir que les tâches sont exécutées séquentiellements (une seule AsyncTask s'exécute à la fois, les autres sont placées en attente dans une file). C'est le comportement normal sous certaines versions du SDK, il n'est pas demandé de modifier le comportement par défaut du système. Vous pouvez tester votre activité sur les URLs de votre choix, mais pour la suite vous vous focaliserez sur le téléchargement d'images, vous pouvez utiliser les trois fichiers suivants pour vos tests : http://www.info.univ-angers.fr/pub/barichar/page_perso/enseignements/android/androidgoogle-logo.jpg http://www.info.univ-angers.fr/pub/barichar/page_perso/enseignements/android/ANdroidIos.jpg http://www.info.univ-angers.fr/pub/barichar/page_perso/enseignements/android/ google_io _2014.mp4 III. Visualisation des fichiers téléchargés Maintenant que les fichiers sont présents sur l'unité de stockage, il est intéressant de pouvoir utiliser les autres applications installées sur l'appareil pour visualiser certains types de fichiers quand c'est possible. Pour simplifier vous ne traiterez que le cas des images et supposerez que les URLs saisies précédemment correspondent toutes à des images. Pour réaliser l'objectif fixé, il faut créer un intent à l'attention du système qui se charge de rechercher un récepteur adapté à cet intent au moment où la fonction startActivity() est exécutée. Si toutefois, startActivity() levait une exception car aucune activité sur le système ne pouvait prendre charge l'intent, un Toast est affiché à l'utilisateur pour lui signifier cet échec. L'exemple ci-après montre ce qu'il se passe lorsqu'une image téléchargée est sélectionnée. 3/4 M2-SILI Développement sous Android année 2016/2017 IV. Gestion de la rotation Pour gérer correctement la rotation, il faut que l'AsyncTask soit correctement reliée au thread de l'interface graphique même lorsqu'elle celle-ci est recréée. De plus il y a autant de tâches de fond qu'il y a d'éléments dans la liste, la rotation n'est donc pas si simple à prendre en compte. Une bonne manière de faire est d'utiliser un fragment sans interface mais qui sera persistant. Les tâches de fonds sont rattachées à ce fragment qui discute avec l'activité. Tâche de fond Activité Fragment persistant Tâche de fond Tâche de fond Sur le schéma précédent, l'activité charge dynamiquement le fragment sans interface, si l'activité est détruite, elle ne doit pas charger un nouveau fragment mais retrouver le précédent. Le fragment se charge de lancer les tâches de fonds (les AsyncTask). Lorsqu'une tâche communique son état (avancement du téléchargement), elle envoie l'information au fragment qui la fait suivre à l'activité. Il faut créer un mécanisme de « callbacks » afin que le fragment puisse communiquer les mises à jour des tâches à l'activité. Les méthodes du cycle de vie du fragment liées à l'activité (onAttach et onDetach) doivent être redéfinies, elles maintiennent le lien entre l'activité actuelle et le fragment. 4/4