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