Développer une application Android pour un site HTML

Application Android Geek01

Application Android Geek01

Dans le dernier article, nous exposions tout le confort gagné à avoir son propre site, aujourd’hui nous allons découvrir comment doter son blog d’une application Android bien à lui!
Nous parlons ici d’un développement android visant à pouvoir consulter son site ou son blog depuis une application mobile. Concrètement le site HTML sera affiché par l’application mobiledédiée.

télécharger le code sourceTélécharger l’application Android Geek01

NB: Pour installer l’appli qui ne provient pas du play store (market android), il faudra autoriser les applications « Sources inconnues » dans les paramètres de votre smartphone ou de votre tablette.

Menu application android

Menu application android

Formulaire contact mail Android

Formulaire contact mail Android

Voici le but du développement:
L’application permettra la visualisation et la navigation sur le site comme dans un navigateur internet.
Un menu donnera accès à la page d’accueil, à un formulaire de contact et à la fermeture de l’application.
D’aucuns diront, mais c’est trop facile, et ils n’auront pas tort quoique… D’autres se sont déjà enfuis en courant et ils ne devraient pas, car à tout problème une solution.

Les pré-requis pour ce développement Android

  •  le site Html (blog wordpress par exemple) doit être conçu pour s’adapter à une consultation sur mobile. C’est le cas de Geek01.com car le thème wordpress weaverII a bien une version mobile.
  • il nous faut un environnement de développement: un PC (sous linux ou windows, voire même un Mac mais sans moi!) avec:
  • le SDK Android installé et à jour
  • l’IDE Eclipse installé
  • le plugin ADT pour eclipse
    si vous êtes perdu voici un  tutoriel pour installer l’environnement de développement Android
  • Enfin des connaissances en Java ne sont pas superflues

IMPORTANT: Vous pouvez télécharger le code sourcetélécharger le code source de ce qui suit.
C’est bien entendu open source.

Dans un but didactique et de simplification, les fonctionnalités de l’application ont toutes été regroupées au sein de la même activité.
Je n’évoquerai dans ce qui suit que les points bloquants car mal documentés ailleurs, voire parfois complètement faux sur le site Android developer

AndroidManifest.xml: permission, orientation, icône

  • Il convient en premier lieu de permettre à l’application Geek01 d’accéder à internet, sans cette permission spécifique l’appli ne pourrait afficher le site HTML cible, pour cela on ajoute la ligne
    
    
  • si rien n’est prévu pour la gestion de l’orientation de l’écran, alors la procédure Oncreate de l’activité sera appelée à chaque fois que l’utilisateur tournera son mobile (ça c’est la théorie car ici l’appli se ferme carrément!) pour éviter ce plantage on ajoute l’attribut android:configChanges dans la balise activity
    android:configChanges="orientation"
  • Comment donner une icône à l’application?
    Dans le répertoire /res nous allons placer les icônes geek01.png en diverses tailles (pour s’adapter aux diverses tailles d’écran des mobiles et tablettes )
    dans ./res/drawable-ldpi l’image geek01.png en 36×36 , ./res/drawable-mdpi en 48×48, ./res/drawable-hdpi en 72×72
    Ensuite nous ajoutons dans la balise application l’attribut android:icon

    android:icon="@drawable/geek01"

 Afficher un site web http dans une application Android

  • Dans le layout principal (main.xml), nous positionnons un webview webkit:
    
    
  • Dans le code source Java (fichier Geek01Activity.java) nous créons une procédure qui initialisera le contenu du WebView et chargera le site. La fonction loadUrl(monurl) charge l’url du site, nous aurions pu mettre loadUrl(« http://geek01.com »), mais nous avons préféré définir l’url en dur dans le fichier de ressources strings.xml plutôt que dans le code JAVA.(voir plus bas)
    //procédure d'affichage et de chargement du site Geek01
    public void ChargerLeSite(){
    stgModeActuel="web";
    //affichage du layout principal (celui qui contient le webview)
    setContentView(R.layout.main);//gestion du webview qui affichera le site
    WebView myWebView = (WebView) findViewById(R.id.webview1);
    myWebView.getSettings().setJavaScriptEnabled(true);
    //chargement du site http dans le webview
    //on utilise la methode getString de la variable de contexte pour récupérer l'url car R.string.url_geek01 est un entier référence...
    myWebView.loadUrl(s_appContext.getString(R.string.url_geek01));
    //NB on pourrait aussi charger un fichier local ainsi:myWebView.loadUrl("file://sdcard/");
    myWebView.setWebViewClient(new WebViewClient()); //permet d'ouvrir les liens url dans le webview et non dans le navigateur
    myWebView.setInitialScale(1); // facteur de zoom initial
    myWebView.getSettings().setBuiltInZoomControls(false); // ne pas afficher le contrôle de zoom
    myWebView.getSettings().setUseWideViewPort(true); // activer le double-tap pour zoomer
    }
  • Création de l’activité principale
    /** Appelé lors de la 1ère création de l'activité */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //initialisation de la variable de contexte
            //cette variable permettra la récupération directe du contenu des chaînes de caractères de strings.xml
            //(car R.string.x renvoie un entier et non la chaîne x
            s_appContext = this.getApplicationContext();
            ChargerLeSite();
    
        }
  • Gestion du bouton Retour (back)
    Le bouton back est un vrai problème dans notre application:
    lorsqu’on est sur le webview (c’est à dire sur le site HTML encapsulé dans l’application), le bouton retour doit faire un back de navigation (retour à la page précédente), mais si on est sur le formulaire de contact mail, le bouton back doit alors renvoyer sur le webview. Pour s’en sortir on crée une fonction personnalisée onBackPressed qui surcharge la fonction de gestion normale
    //gestion du bouton back
    //il faut que le back entraine un retour dans la navigation du site dans le webform
    //si on ne fait rien le back sortirait de l'application!
    @Override
    public void onBackPressed() {
    	if (stgModeActuel=="web"){
    				//on est dans le webview
			    	WebView myWebView = (WebView) findViewById(R.id.webview1);
			    	//si le back est possible dans la navigation, il faut le faire
			        if (myWebView.canGoBack()) {
			        	myWebView.goBack();
			        }
			        else
			        {
			        	//fonctionnement habituel du back car on ne peut faire de retour web
			        	moveTaskToBack(true);
			        }
			        return;
    	}
		else
			//on est sur une page secondaire, le back doit recharger la page Accueil de l'appli, c'est à dire le site
        	{
        	ChargerLeSite();
        	return;
        }

    }

Ajouter un Menu à l’application

  • Dans la classe de l’activité principale, nous déclarons chaque élément du menu comme un nombre entier
    //variables du menu
    	public static final int intMenu_Geek01 =  Menu.FIRST;
    	public static final int intMenu_Contact = 2;
    	public static final int intMenu_Exit = 3;
  • Pour créer chaque bouton du menu, on remplace la fonction onCreateOptionsMenu par une fonction personnalisée. menu.add permet l’ajout des éléments du menu
     //Construction du Menu
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // TODO Auto-generated method stub
            boolean result = super.onCreateOptionsMenu(menu);
            //option menu Geek01
            menu.add(0, intMenu_Geek01, 0, R.string.menu_geek01);
            //option menu: Contact
            menu.add(0, intMenu_Contact, 1, R.string.menu_contact);
            //option menu: Sortie
            menu.add(0, intMenu_Exit, 2, R.string.menu_exit);
    
            return result;
    
        }
  • Pour gérer le comportement du menu, on utilise la fonction onOptionsItemSelected (voir plus bas)

Gérer un formulaire de contact mail

  • Les ressources textuelles, les couleurs utilisées dans l’application ne sont pas contenues dans le code java, ni dans les layers, mais dans le fichier res/values/strings.xml
    <!--?xml version="1.0" encoding="utf-8"?-->
    
        Geek01.com
        Contacter l\'auteur!
        Message
        Objet
        Envoi
        Geek01 version 0.1 - code source disponible sur http://geek01.com
        Exit
        Cont@ct
        Geek01
    
    http://geek01.com
    
        toto@turlututu.com
        Envoi du message via:
    #333333
  • Attention le code java pour récupérer un élément de strings.xml est: R.string.nomdelachaine, MAIS la valeur renvoyée n’est pas la chaîne de caractère elle-même mais un entier référence la représentant. Pour accéder à la chaîne on utilisera ici une variable de contexte
    s_appContext = this.getApplicationContext();
    ...
    ...
    String stgMailTo = s_appContext.getString(R.string.email_geek01);
  • les éléments graphiques (textview, edittext, etc) sont créés dans un layout à part (contact_layer.xml) différent du principal(main.xml). Ce layout sera affiché par la commande Java suivante:
    setContentView(R.layout.contact_layer);
  • Le comportement du formulaire de contact est géré dans la fonction de gestion du menu onOptionsItemSelected.
    IL est intéressant de noter que l’envoi de mail est en fait un simple passage d’info au client mail que choisira l’utilisateur suite à l’appel final startActivity(Intent.createChooser). D’aucuns diront qu’il serait plus élégant d’envoyer directement le mail par programmation en sollicitant un serveur SMTP, certes mais si Android permettait un tel usage, il serait alors très facile de transformer un mobile en zombie, capable d’envoyer des spams à la terre entière…

        //gestion du menu
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // TODO Auto-generated method stub
        	 switch (item.getItemId()) {
             //clic sur le menu contact
        	 case intMenu_Contact:
            	 //changement de layer (on sort de main pour aller dans le contact layer)
            	 setContentView(R.layout.contact_layer);
            	 stgModeActuel="contact";
            	//-----------------Gestion Envoi Mail-------------
                 send=(Button) findViewById(R.id.emailsendbutton);
                 txtSubject=(EditText) findViewById(R.id.emailObjet);
                 emailtext=(EditText) findViewById(R.id.emailtext);
    
                 //gestion du clic sur le bouton d'envoi du message
                 send.setOnClickListener(new OnClickListener() {
                     public void onClick(View v) {
                    	 String stgMailTo = s_appContext.getString(R.string.email_geek01);
    
                    	 // création d'un intent pour envoyer l'email via l'application messagerie du mobile
                    	 final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
                    	 //emailIntent.setType("text/plain"); //propose une liste d'appli dont certaines n'ont rien à voir
                    	 emailIntent.setType("message/rfc822");//selectionne uniquement les appli mails, s'il n'y a que gmail il s'ouvre directement, sinon liste de choix d'appli (k9, gmail...)
                    	 //passage de l'adresse destinataire
                    	 emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[]{stgMailTo});
    	                 //sujet du message
                    	 //attention EXTRA_SUBJECT attend une string &gt;&gt; tostring
    	                 emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,txtSubject.getText().toString());
    	                 //corps du message
    	                 //EXTRA_TEXT attend une charsequence qu'on récupère directement dans emailtext par la métode getText
    	                 emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, emailtext.getText());
    	                 //Rock'n'roll!
    	                 Geek01Activity.this.startActivity(Intent.createChooser(emailIntent, s_appContext.getString(R.string.email_txtEnvoi)));
                     }
             });
    
               //-----------------fin Gestion email---------------
    
                return true;
              //clic sur menu sortie
             case intMenu_Geek01:
            	 ChargerLeSite();
                 return true;
             //clic sur menu sortie
             case intMenu_Exit:
             	finish();
                 return true;
             }
    
             return super.onOptionsItemSelected(item);
        }

Comment fermer complètement l’application android?

  • Dans le menu nous avons positionné un bouton exit, ce bouton déclenche l’appel à la fonction finish()
  • Pour fermer et sortir de notre applicationproprement et complètement , en tuant tous ses processus, et fermant ses ressources, nous alons personnaliser onDestroy
     //onDestroy est appelé lorsque finish est invoqué sur l'activité
        @Override
        public void onDestroy() {
            super.onDestroy();
    
            //demande au système de fermer tout objet de l'application de sorte que l'appli puisse être tuée sans risque
            //true implique que le processus ne sera tué que quand tous les threads auront été fermés
            System.runFinalizersOnExit(true);
    
            //force l'application à se fermer complètement et à ne passer en arrière-plan
            System.exit(0);
        }

 

5 comments on “Développer une application Android pour un site HTML

  1. Pingback: Meilleures applications Android, mon market à moi! | Geek01

  2. Ouh le vilain System.exit(0) :( ((
    Ca ne se fait pas ce genre de chose ;-)

    Normalement, il me semble qu’il suffit d’un « finish() » et on laisse l’OS géré ça tranquillement.

  3. FredBx on said:

    En fait c’est voulu! System.finish ne tue pas le processus, il ferme l’activité et bascule le processus en arrière-plan. Personnellement je trouve plus propre de tuer complètement le processus, puisque l’appli n’a pas vocation à rester en arrière plan…

  4. trotinet65 on said:

    Bonjour,

    Compilé sous eclipse et testé sur un Galaxy SII, l’application affiche une page noire puis se ferme.

    Dommage

  5. Jonathan on said:

    Impossible de l’importer dans eclipse et de générer un apk sans avoir une seule erreur…

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>