juil
25
2010

[Tutoriel Android] Partie 8 – Chargement des images et données

Récupérer un flux de données ou une image

Bonjour à tous, aujourd’hui nous allons voir comment récupérer des données provenant d’une page ou d’un flux de données à distance, ou encore une image et l’afficher.

Commençons par créer un tout nouveau projet, contenant une activité et un layout principal.

Modifions notre layout “main.xml” de cette façon :

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<ImageView

android:id="@+id/ivImage"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

/>

<ScrollView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:scrollbars="vertical">

<TextView

android:id="@+id/tvContent"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

/>

</ScrollView>

</LinearLayout>

On retrouvera une ImageView pour afficher notre image, ansi qu’un TextView qui contiendra la page que nous avons chargée, dans une ScrollView permettant de faire défiler celui-ci.

Nous allons utiliser nos premiers flux et les classes de connexions HTTP pour aller les chercher et les stocker.

Tout d’abord, créons une instance de notre ImageView et TextView pour les utiliser au sein de notre code.

public class MonActivite extends Activity {

ImageView image;

TextView page;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

image = (ImageView)findViewById(R.id.ivImage);

page = (TextView)findViewById(R.id.tvContent);

}

}

Nous allons créer une méthode downloadImage(), qui sera chargée de télécharger l’image distante et l’afficher dans notre ImageView.

Nous déclarerons un type Bitmap qui contiendra les informations de l’image. Puis par le biais de la classe URL, nous allons ouvrir une connexion vers celle-ci. Et enfin, avec la classe HttpURLConnection, nous allons récupérer le flux et pour finir la classe BitmapFactory servira à décoder notre flux.

private void downloadImage() {

Bitmap bitmap = null;

try {

URL urlImage = new URL("http://www.google.fr/intl/en_com/images/srpr/logo1w.png");

HttpURLConnection connection = (HttpURLConnection) urlImage.openConnection();

InputStream inputStream = connection.getInputStream();

bitmap = BitmapFactory.decodeStream(inputStream);

image.setImageBitmap(bitmap);

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

Nous allons utiliser la même technique pour lire une page web à la différence que nous n’allons pas la stocker dans une image, mais stocker les données dans un BufferReader, stocker chaque ligne de données dans un StringBuffer et pour finir l’afficher dans le TextView.

private void downloadPage() {

try {

URL urlPage = new URL("http://www.google.fr");

HttpURLConnection connection = (HttpURLConnection) urlPage.openConnection();

InputStream inputStream = connection.getInputStream();

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

StringBuffer stringBuffer = new StringBuffer();

String ligne;

while((ligne = bufferedReader.readLine()) != null) {

stringBuffer.append(ligne);

// Android 2.3 et supérieur
if(!bufferedReader.ready()) {
break;
}

}

page.setText(stringBuffer.toString());

connection.disconnect();

bufferedReader.close();

inputStream.close();

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

N’oubliez pas de fermer la connection ainsi que le buffer et l’inputstream, ce qui libéra de la mémoire.

Lancez le programme et voyez par vous même.

Programme final

Et voilà, le tutoriel est terminé maintenant vous savez charger une image à distance et les données d’une page.

N’oubliez pas d’ajouter la permission : android.permission.INTERNET

A plus tard pour le prochain tutoriel !

Voici les sources complètes : FormationImage

  • http://SiteWeb Chris

    Excellent travail !
    Deux remarques :
    - serait-il possible d’enlever les numéros de lignes pour “copier” le code source,
    - mieux : serait-il possible d’avoir le code complet à télécharger ?
    Merci encore pour ce superbe boulot.

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Si tu veux copier le code c’est simple en haut a droite de chaque boite contenant du code il y’a des icones qui s’affichent dont une qui permet cela ;)

    Pour le téléchargement des sources je vais le rajouter, je te remercie Chris.

  • http://SiteWeb Chris

    Merci à toi !
    J’ai vu, après coup, l’icône pour copier le source. Plus facile en effet que de supprimer les numéros à chaque ligne lol

  • http://SiteWeb mari

    bonjour, merci bien pour ce tutoriel, je veux savoir seulement comment on peux par exemple si en clic sur une bouton envoyer il vous envois vers un lien url? merci d’avance

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    J’ai rajouté les sources de la formation à la fin de l’article :cheerful:

  • http://SiteWeb Enjolras

    Bonsoir,
    Félicitation et un grand merci pour ce travail, j’avais commencé a apprendre avec la doc officielle mais il faut avouer qu’un bon tuto en francais en fait jamais de mal !

    @mari: si je comprends ce que je veux dire, c’est expliquer lors de la presentation des intents dans la partie 3 si je me souviens bien …

  • http://SiteWeb NothingPersonal

    excellent tuto :biggrin:, ça fait lengtemps que je cherche un tuto pareil. Merci et bonne continuation :wink:

  • http://SiteWeb NothingPersonal

    Il ne faut pas oublier d’ajouter cette ligne dans le fichier AndroidManifest.xml:

    Comme ça l’application aura la permission d’accéder à internet sinon on aura un joli petit écran noir :wink: bonne journé !

  • http://SiteWeb NoBody

    Super tuto, à quand le prochain, et connais-tu d’autre site en français comme le tien

  • http://SiteWeb Dildil

    Super pour débuter ! Connaissant un peu java et Eclipse, je n’ai eu aucun mal à suivre les 8 tutos (enfin 7, vu que le 7è est un peu à part). Maintenant que j’ai quelques bases, je vais pouvoir me lancer dans le développement d’applications.

    Merci cher collègue du 33 !

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Mais de rien c’est toujours une joie de pouvoir aider les autres ;)

  • http://SiteWeb cleg

    Merci beaucoup pour ce tuto que j’ai réussi à suivre :)
    Est-il possible avec cette même technique de récupérer uniquement un article d’un blog et non toute la pge html ?

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Oui c’est faisable avec cette méthode, mais il va falloir ruser pour récupérer uniquement les bonnes informations ;)

  • http://SiteWeb Pymouss

    Merci beaucoup !
    C’est exactement ce que je cherchais.

  • http://SiteWeb Nico

    Très bon tuto comme les précédents d’ailleurs !!
    Attention si vous crée une application qui a un api level min de 11 (Android HoneyComb 3.0) l’écran reste noir car une NetworkOnMainThreadException est générée.

  • http://SiteWeb Khaireddine120

    Salut,
    j’ai un problème, je n’ai rien sur l’ecran et dans le logcat j’ai cette erreur :
    WARN/System.err(542): java.net.UnknownHostException: Host is unresolved: http://www.google.com:80

    aidez moi et merci

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Bonjour,

    Quand tu ouvres le navigateur internet de ton émulateur android est-ce que tu accèdes à internet ?

  • http://SiteWeb Khaireddine120

    Non, comment faire pour acceder à internet , j’ai quand meme ajouter la permission internet dans le manifest

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Non mais sur l’émulateur tu as le navigateur internet d’Android, regarde si t’arrives à ouvrir une page avec.

  • http://SiteWeb Khaireddine120

    je veux dire j’accède pas à internet via l’emulateur

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Alors ton problème viens de la, cherche comment faire fonctionner internet sur ton émulateur et ça réglera ton soucis en java ;)

    Bonne chance pour ça je ne peu rien pour toi

  • http://SiteWeb Khaireddine120

    je tourne l’emulateur sur linux , je croix que c’est d’ici le probleme, lorsque j’essaie de se connecter via wifi l’emulateur refuse je vais essayer avec windows pour etre sur.
    Merci pour tous.

  • http://SiteWeb Greg

    Bien le bonjour!

    Tout d’abord, merci à Pierre-Emmanuel pour ces supers tutoriels en français :smile:

    Cependant, un petit détail pour ce tuto: je suis débutant sur Android et j’ai perdu un temps fou à trouver le petit truc qui n’allait pas…

    Ce petit truc? Ajouter un uses permission dans le manifest avec comme valeur: android.permission.INTERNET

    Heureusement qu’il y avait des commentaires d’autres personnes, en espérant que le mien aide les prochains débutants :happy:

    @+

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Merci Greg, j’ai rajouté ton commentaire dans l’article. ;)

  • http://SiteWeb Justine

    Hello :)

    Tt d’abord merci beaucoup pr ce trés bon Tuto qui est tt ce que je cherchais^^
    J’ai cependant un petit problème: mon émulateur n’accède pas a internet. . . Quelqu’un aurait-il déja réglé ce problème??

    Merci d’avance!

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Bonjour Justine,

    http://developer.android.com/guide/developing/tools/emulator.html

    Regarde tu as des commandes pour rajouter l’adresse d’un proxy ou d’un serveur dns supplémentaire.

  • http://SiteWeb Droide

    Tip, top, ce tutoriel, merci.

    Bien sûr, il ne faut pas oublier à faire appel à downloadImage et downloadPage.

    Question, cela fonctionne pour récupérer tout type d’image ?
    Avec passage par paramètre de l’url de l’image, ça deviens vraiment intéressant ^^

    Autre question, c’est aussi possible de lire un flux RSS avec cette méthode, ou je suis complètement à côté de la plaque ?

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Oui oui tu peux tout lire ce ne sont que des flux après il faut juste les interpréter.

    Rien n’est impossible ;)

  • http://SiteWeb Justine

    Hello ! Merci pour vos reponses^^

    J’ai un nouveau problème: mon programme ne passe pas la ligne : InputStream inputStream = connection.getInputStream();

    Il me retrourne l’erreur suivante: request time failed : java.net.SocketExceptioin : Address family not supported by protocol.
    Pour être bien sur que mes problèmes ne venait plus du proxy j’ai mis en place un serveur local.

    Merci d’avance !!

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Address family not supported by protocol

    Il n’arrive pas à se connecter à la source car l’adresse passée en paramètre n’est pas supportée.

  • http://SiteWeb Justine

    Merci Pierre-Emmanuel!
    Mon problème est réglé^^

  • http://SiteWeb Amath

    Slt, merci vraiment pour le tuto surtout pour nous qui venons de commencer la programmation sur android. J’ai un problème je voudrai seulement charger l’image donc je me suis arrêté a la fonction downloadImage mais quand je compile j’ai rien uniquement un ecran noir. Merci d’avance

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    As tu bien fait la première partie ?

    setContentView(R.layout.main);
    image = (ImageView)findViewById(R.id.ivImage);

    Et surtout le

    N’oubliez pas d’ajouter la permission : android.permission.INTERNET

  • http://SiteWeb Amath

    Oui et merci de m’avoir répondu si rapidement, pour la classe main.xml j’ai fait la meme chose que vous et pour la classe ImageDownload.java qui represente votre classe MonActivite.java voici mon code:

    package org.hello.ImageDownload;

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;

    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.widget.ImageView;
    import android.widget.TextView;
    import android.os.Bundle;

    public class ImageDownload extends Activity {

    ImageView image;

    TextView page;

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    image = (ImageView)findViewById(R.id.ivImage);

    page = (TextView)findViewById(R.id.tvContent);

    }

    @SuppressWarnings(“unused”)
    private void downloadImage() {

    Bitmap bitmap = null;

    try {

    URL urlImage = new URL(“http://www.google.fr/intl/en_com/images/srpr/logo1w.png”);

    HttpURLConnection connection = (HttpURLConnection) urlImage.openConnection();

    InputStream inputStream = connection.getInputStream();

    bitmap = BitmapFactory.decodeStream(inputStream);

    image.setImageBitmap(bitmap);

    } catch (MalformedURLException e) {

    e.printStackTrace();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    et enfin voici comment j’ai ajouter la permission dans mon fichier AndroidManifest.xml:

  • http://SiteWeb Amath

    pour la permission voici ce k j’ai fait:

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    @SuppressWarnings(“unused”)

    Veux dire ne plus m’embêter quand tu me dis que je ne t’utilises pas !

    En faites tu ne fais aucuns appels ) a downloadImage :)

    appel le dans ton onCreate ;)

  • http://SiteWeb Amath

    merci pour ta réponse mais je sais pas comment je vais l’appeler dans onCreate. je suis vraiment nouveau sur android. Merci de votre compréhension

  • http://SiteWeb Amath

    Bonjour,

    j’arrive toujours pas a utiliser ma méthode downloadImage car je sais pas vraiment comment je vais pouvoir l’appeler dans ma méthode onCreate. Et je dois le réaliser au plus vite svp. Merci d’avance

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    tu rajoutes tout simplement

    downloadImage(); dans ta méthode onCreate

  • http://SiteWeb Amath

    Merci Pierre-Emmanuel ça marche maintenant, vraiment merci de ton aide et de ta compréhension…

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Mais il y a pas de soucis ;)

  • http://SiteWeb Amath

    Slt, une toute dernière chose j’ai essaye de télécharger une autre image autre que google avec le code en mettant ls liens vers l’image mais quand je lance l’émulateur aucune image ne se charge et je sais pas pk? Merci d’avance

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Le lien est bon ?
    Le type d’image est il supporté ?

    Vérifie en débugguant pas à pas pour voir d’où cela peux provenir

  • http://SiteWeb Amath

    oui il me semble bien mais je vais faire comme tu me dis. Et j ‘ai aussi essayer de récupérer une image sur mon pc en local pour la charger sur mon appli mais ça passe pas aussi???

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Récupérer une image en local c’est totalement différent, Android ne connait pas ton PC, pour récupérer l’image local il faut passer par une adresse web (URL), mais tu ne peux pas faire “c://mesdocs/monimage.jpg” il ne la trouvera jamais.

  • http://SiteWeb ZouVic

    bonjour a tous
    jai un probleme pour faire marche une video sur mon appli android; enfaire jutilise un fichier html pour appeler la video; et lactivity qui appele a son tour le fichier html5.
    voila d petit bout de code mon probleme

    voila mon fichier html

    body{background-color:transparent;}
    video{margin:-7;padding:0px;}

    et mon fichier java

    import android.os.Bundle;
    import android.webkit.WebView;

    public class onglet3_auto extends GenericActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.onglet_video);

    WebView webView = (WebView) findViewById(R.id.webView);
    webView.loadUrl(“file:///android_asset/html/offre_auto_hab/AUTO_Video.html”);

    }}

  • http://SiteWeb Jedix

    Juste pour signaler qu’il peut y avoir un pb pour les versions 2.3 et supérieures concernant la lecture du flux texte. Voir ce lien pour fixer le pb (un petit ajout dans la boucle while) : http://stackoverflow.com/questions/4841925/java-io-ioexception-bufferedinputstream-is-closed-in-android-2-3

  • http://www.ace-art.fr/wordpress/ Pierre-Emmanuel Mercier

    Merci Jedix, j’ai rajouté cette partie ;)

  • http://SiteWeb Jman

    MErci mon ami ça m’a beaucoup aidé ^^ :wink:

  • Gp2mv3

    J’ai un problème bien ennuyant moi…
    J’ai repris le code ci-dessus parce qu’un code que j’avais fait précédemment ne fonctionnait pas, j’ai toujours une exceptions:


    09-08 15:24:26.116: WARN/System.err(2133): java.net.UnknownHostException: http://www.google.com
    09-08 15:24:26.116: WARN/System.err(2133): at java.net.InetAddress.lookupHostByName(InetAddress.java:506)
    09-08 15:24:26.126: WARN/System.err(2133): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:294)
    09-08 15:24:26.126: WARN/System.err(2133): at java.net.InetAddress.getAllByName(InetAddress.java:256)
    09-08 15:24:26.126: WARN/System.err(2133): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.(HttpConnection.java:69)
    09-08 15:24:26.126: WARN/System.err(2133): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.(HttpConnection.java:48)
    09-08 15:24:26.126: WARN/System.err(2133): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection$Address.connect(HttpConnection.java:322)
    09-08 15:24:26.126: WARN/System.err(2133): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionPool.get(HttpConnectionPool.java:89)
    09-08 15:24:26.136: WARN/System.err(2133): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getHttpConnection(HttpURLConnectionImpl.java:285)
    09-08 15:24:26.146: WARN/System.err(2133): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.makeConnection(HttpURLConnectionImpl.java:267)
    09-08 15:24:26.146: WARN/System.err(2133): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.retrieveResponse(HttpURLConnectionImpl.java:1018)
    09-08 15:24:26.146: WARN/System.err(2133): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:512)
    09-08 15:24:26.146: WARN/System.err(2133): at com.gp2mv3.http.HttpActivity.loadPage(HttpActivity.java:39)
    09-08 15:24:26.146: WARN/System.err(2133): at com.gp2mv3.http.HttpActivity.onCreate(HttpActivity.java:30)
    09-08 15:24:26.156: WARN/System.err(2133): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    09-08 15:24:26.156: WARN/System.err(2133): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
    09-08 15:24:26.156: WARN/System.err(2133): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
    09-08 15:24:26.156: WARN/System.err(2133): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    09-08 15:24:26.156: WARN/System.err(2133): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    09-08 15:24:26.156: WARN/System.err(2133): at android.os.Handler.dispatchMessage(Handler.java:99)
    09-08 15:24:26.156: WARN/System.err(2133): at android.os.Looper.loop(Looper.java:123)
    09-08 15:24:26.156: WARN/System.err(2133): at android.app.ActivityThread.main(ActivityThread.java:3683)
    09-08 15:24:26.166: WARN/System.err(2133): at java.lang.reflect.Method.invokeNative(Native Method)
    09-08 15:24:26.166: WARN/System.err(2133): at java.lang.reflect.Method.invoke(Method.java:507)
    09-08 15:24:26.166: WARN/System.err(2133): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    09-08 15:24:26.166: WARN/System.err(2133): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    09-08 15:24:26.166: WARN/System.err(2133): at dalvik.system.NativeStart.main(Native Method)

    Pourtant mon émulateur a bien accès à internet (et donc évidemment à Google.com).
    D’ou vient le problème ?
    S’il faut je peux mettre mon code mais il est quand même bien long…