{"id":169,"date":"2021-08-20T21:13:30","date_gmt":"2021-08-20T21:13:30","guid":{"rendered":"https:\/\/www.louismarchand.me\/?page_id=169"},"modified":"2022-08-22T18:50:05","modified_gmt":"2022-08-22T18:50:05","slug":"les-projets-android","status":"publish","type":"page","link":"https:\/\/www.louismarchand.me\/index.php\/les-projets-android\/","title":{"rendered":"Les projets Android"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>La structure d&rsquo;un projet Android peut \u00eatre assez complexe. Dans cette page, je t\u00e2cherai de vous expliquer les diff\u00e9rents aspects importants dans un projet Android.<\/p>\n<h2>Cr\u00e9ation d&rsquo;un nouveau projet<\/h2>\n<p>Pour cr\u00e9er un nouveau projet, appuyez sur le bouton \u00ab\u00a0Start a new Android project\u00a0\u00bb si vous \u00eates sur l&rsquo;\u00e9cran d&rsquo;accueil d&rsquo;Android Studio, ou s\u00e9lectionnez le menu \u00ab\u00a0File-&gt;New-&gt;New Project&#8230;\u00a0\u00bb.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-644 aligncenter\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2022\/08\/start_new_accueil.png\" alt=\"\" width=\"578\" height=\"243\" srcset=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2022\/08\/start_new_accueil.png 948w, https:\/\/www.louismarchand.me\/wp-content\/uploads\/2022\/08\/start_new_accueil-300x126.png 300w, https:\/\/www.louismarchand.me\/wp-content\/uploads\/2022\/08\/start_new_accueil-768x323.png 768w\" sizes=\"auto, (max-width: 578px) 100vw, 578px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10092\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/menu_new_project.png\" alt=\"\" width=\"711\" height=\"303\" \/><\/p>\n<p>Ensuite, s\u00e9lectionnez le type d&rsquo;activit\u00e9 que vous souhaitez faire pour votre activit\u00e9 par d\u00e9faut. Nous verrons ce qu&rsquo;est une activit\u00e9 Android plus tard dans le cours. Il est toujours possible de passer d&rsquo;un type d&rsquo;activit\u00e9 \u00e0 un autre en modifiant le code source de votre projet. \u00c7a n&rsquo;a donc pas beaucoup d&rsquo;importance.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-175\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/select_activity.png\" alt=\"\" width=\"541\" height=\"391\" srcset=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/select_activity.png 904w, https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/select_activity-300x217.png 300w, https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/select_activity-768x556.png 768w\" sizes=\"auto, (max-width: 541px) 100vw, 541px\" \/><\/p>\n<p>Ensuite, s\u00e9lectionnez un nom d&rsquo;application et nom de \u00ab\u00a0Package\u00a0\u00bb.<\/p>\n<p>Le nom de \u00ab\u00a0Package\u00a0\u00bb est g\u00e9n\u00e9ralement li\u00e9 au nom du domaine Web de l&rsquo;entreprise ou du d\u00e9veloppeur qui cr\u00e9e l&rsquo;application. Cette r\u00e8gle n&rsquo;est pas obligatoire et dans le cas, ou vous n&rsquo;aviez pas de nom de domaine, vous pouvez mettre un identificateur vous repr\u00e9sentant. Par exemple, je pourrais mettre \u00ab\u00a0marchandl.mon_application\u00a0\u00bb si je n&rsquo;avais pas de nom de domaine.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-176\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/select_api.png\" alt=\"\" width=\"543\" height=\"393\" \/><\/p>\n<p>Ensuite, dans le cadre du cours, vous devez sp\u00e9cifier le langage de programmation \u00e0 utiliser. La programmation Android de base peut se faire avec les langages Java ou Kotlin. Dans le c\u00e2dre de ce cours, nous allons utiliser le langage Java.<\/p>\n<p>Le dernier \u00e9l\u00e9ment \u00e0 prendre en compte, c&rsquo;est l&rsquo;API minimum du syst\u00e8me. Pour cette valeur, je vous recommande de prendre un API assez ancien afin de supporter le maximum d&rsquo;appareil et d&rsquo;utilisateur. \u00c9galement, nous allons voir plus loin qu&rsquo;on peut mettre un API cible en plus d&rsquo;un API minimum, ce qui nous permettra d&rsquo;avoir plus de fonctionnalit\u00e9, sans avoir \u00e0 restreindre les utilisateurs avec des appareils anciens.<\/p>\n<h2>La structure des r\u00e9pertoires<\/h2>\n<p>Le r\u00e9pertoire racine du projet contient des scripts et des fichiers de configurations du syst\u00e8me de compilation Gradle. Peu d&rsquo;information de ce r\u00e9pertoire peut vous \u00eatre utile dans le cours. Par contre, les fichiers scripts \u00ab\u00a0gladlew\u00a0\u00bb et \u00ab\u00a0gladlew.bat\u00a0\u00bb sont des scripts pouvant \u00eatre utilis\u00e9s en ligne de commande et qui peuvent vous permettre de compiler votre projet sans n\u00e9cessiter l&rsquo;utilisation d&rsquo;Android Studio; ce qui peut \u00eatre tr\u00e8s utile si vous utilisez un serveur de compilation ou un service d&rsquo;int\u00e9gration continue. \u00c9galement, le r\u00e9pertoire \u00ab\u00a0gradle\u00a0\u00bb contient des fichiers de configuration et des librairies n\u00e9cessaires au bon fonctionnement du syst\u00e8me de compilation.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10094\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/repertoire_racine.png\" alt=\"\" width=\"717\" height=\"218\" \/><\/p>\n<p>Le r\u00e9pertoire \u00ab\u00a0app\u00a0\u00bb contient les fichiers et r\u00e9pertoire qui vous seront utiles en tant que programmeur.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10095\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/repertoire_app.png\" alt=\"\" width=\"607\" height=\"147\" \/><\/p>\n<p>Le r\u00e9pertoire \u00ab\u00a0libs\u00a0\u00bb contient les librairies Java (et parfois natives) qui permettent de bien faire fonctionner le code source qui se trouve dans le r\u00e9pertoire \u00ab\u00a0src\u00a0\u00bb.<\/p>\n<p>Le fichier \u00ab\u00a0build.gradle\u00a0\u00bb est le fichier de configuration principal de votre application. Il peut \u00eatre tr\u00e8s int\u00e9ressant d&rsquo;explorer les diff\u00e9rentes informations que ce fichier contient (ou peut contenir). Nous verrons cela plus bas. Le fichier \u00ab\u00a0proguard-rules.pro\u00a0\u00bb est utilis\u00e9 par l&rsquo;utilitaire \u00ab\u00a0R8\u00a0\u00bb afin de faire de l&rsquo;optimisation du programme, lors de la cr\u00e9ation du \u00ab\u00a0package\u00a0\u00bb d&rsquo;installation. La configuration ProGuard n&rsquo;est pas pr\u00e9vue dans ce cours, mais si c&rsquo;est un aspect qui vous int\u00e9resse, vous pouvez voir la documentation \u00e0 <a href=\"https:\/\/developer.android.com\/studio\/build\/shrink-code\">ici<\/a>.<\/p>\n<p>Le code source de l&rsquo;application se trouve dans le r\u00e9pertoire \u00ab\u00a0src\u00a0\u00bb. Dans ce r\u00e9pertoire, on y trouve un r\u00e9pertoire \u00ab\u00a0main\u00a0\u00bb contenant le code source du projet, un r\u00e9pertoire \u00ab\u00a0test\u00a0\u00bb contenant des fichiers de test Java standard et un r\u00e9pertoire \u00ab\u00a0androidTest\u00a0\u00bb, contenant des tests pour les modules Android.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10096\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/repertoire_src.png\" alt=\"\" width=\"503\" height=\"125\" \/><\/p>\n<p>Les 3 r\u00e9pertoires contiennent une structure de r\u00e9pertoire de vos \u00ab\u00a0Package\u00a0\u00bb Java. Il est important de noter que le syst\u00e8me de \u00ab\u00a0Package\u00a0\u00bb de java est directement reli\u00e9 \u00e0 la structure de r\u00e9pertoire. Par exemple, le fichier source de mon activit\u00e9 \u00ab\u00a0main\u00a0\u00bb se trouve dans le \u00ab\u00a0Package\u00a0\u00bb \u00ab\u00a0me.louismarchand.mon_application\u00a0\u00bb et se trouve donc dans le r\u00e9pertoire source du projet \u00ab\u00a0me\/louismarchand\/mon_application\u00a0\u00bb.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10097\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/repertoire_package.png\" alt=\"\" width=\"1090\" height=\"152\" \/><\/p>\n<p>En plus des fichiers sources, le r\u00e9pertoire \u00ab\u00a0main\u00a0\u00bb contient les ressources utilis\u00e9es dans l&rsquo;application ainsi que le fichier \u00ab\u00a0AndroidManifest.xml\u00a0\u00bb qui est un fichier tr\u00e8s important dans le d\u00e9veloppement Android. Nous verrons l&rsquo;utilisation de ce fichier ainsi que des ressources plus tard dans le cours.<\/p>\n<p>Il est \u00e0 noter que tous ces fichiers sont accessibles directement dans l&rsquo;\u00e9diteur Android Studio. Il n&rsquo;est donc g\u00e9n\u00e9ralement pas n\u00e9cessaire de naviguer cette structure de r\u00e9pertoires.<\/p>\n<h2>Le fichier \u00ab\u00a0build.gradle\u00a0\u00bb<\/h2>\n<p>Le fichier \u00ab\u00a0build.gradle\u00a0\u00bb permet entre autres de changer l&rsquo;API minimal et l&rsquo;API cible utilis\u00e9 dans votre projet. Notez que les termes API et SDK sont souvent m\u00e9lang\u00e9s dans la technologie Android. Ils repr\u00e9sentent presque la m\u00eame chose et leurs num\u00e9ros sont les m\u00eames (l&rsquo;API 15 est impl\u00e9ment\u00e9 par le SDK 15).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10100\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/select_sdk_target.png\" alt=\"\" width=\"1276\" height=\"628\" \/><\/p>\n<h2>Le fichier \u00ab\u00a0AndroidManifest.xml\u00a0\u00bb<\/h2>\n<p>Ce fichier contient la configuration principale du code source du projet. On y retrouve des configurations comme: le nom et le nom de l\u2019ic\u00f4ne de l&rsquo;application, l&rsquo;activit\u00e9 principale \u00e0 lancer lors de l&rsquo;ex\u00e9cution de l&rsquo;application, les activit\u00e9s de service de l&rsquo;application, les permissions de l&rsquo;application (cam\u00e9ra, avoir acc\u00e8s aux fichiers de l&rsquo;utilisateur, calendrier, contacts, etc.) et bien d&rsquo;autres.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10101\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/AndroidManifest.png\" alt=\"\" width=\"1102\" height=\"416\" \/><\/p>\n<p>Pour plus de d\u00e9tail sur ce que le manifeste Android peut contenir comme configuration, voir la documentation officielle <a href=\"https:\/\/developer.android.com\/guide\/topics\/manifest\/manifest-intro\">ici<\/a>.<\/p>\n<h2>Les fichiers de ressources<\/h2>\n<p>Dans le r\u00e9pertoire \u00ab\u00a0res\u00a0\u00bb, on y trouve les ressources visuelles (par exemple: images), les informations de mise en page (layouts) ainsi que les diff\u00e9rentes constantes utilis\u00e9es dans l&rsquo;application (par exemple, les chaines de caract\u00e8res, les couleurs, etc.).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10103\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/ressources.png\" alt=\"\" width=\"790\" height=\"648\" \/><\/p>\n<p>Une fois une ressource cr\u00e9\u00e9e, ses \u00e9l\u00e9ments peuvent \u00eatre acc\u00e9d\u00e9s dans le code java en utilisant la r\u00e9f\u00e9rence retourn\u00e9 par le singleton \u00ab\u00a0R\u00a0\u00bb (nom tr\u00e8s peu significatif \u00e0 mon avis), ainsi que des fonctions comme \u00ab\u00a0getRessource\u00a0\u00bb. Par exemple, voici une constante texte appel\u00e9 \u00ab\u00a0bonjour\u00a0\u00bb cr\u00e9\u00e9 dans le fichier \u00ab\u00a0strings.xml\u00a0\u00bb:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10104\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/bonjour_strings.png\" alt=\"\" width=\"683\" height=\"280\" \/><\/p>\n<p>Si je veux faire afficher cette valeur dans un Popup Android (appel\u00e9 \u00ab\u00a0Toast\u00a0\u00bb) voici ce que je peux faire en Java (noter que tous le code permettant l&rsquo;acc\u00e8s aux ressources se trouve dans la premi\u00e8re ligne de l&rsquo;exemple):<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">CharSequence<\/span> <span class=\"n\">lBonjour<\/span> <span class=\"o\">=<\/span> <span class=\"n\">getResources<\/span><span class=\"o\">().<\/span><span class=\"na\">getText<\/span><span class=\"o\">(<\/span><span class=\"n\">R<\/span><span class=\"o\">.<\/span><span class=\"na\">string<\/span><span class=\"o\">.<\/span><span class=\"na\">bonjour<\/span><span class=\"o\">);<\/span>\r\n<span class=\"n\">Toast<\/span> <span class=\"n\">lPopup<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Toast<\/span><span class=\"o\">.<\/span><span class=\"na\">makeText<\/span><span class=\"o\">(<\/span><span class=\"n\">getApplicationContext<\/span><span class=\"o\">(),<\/span> <span class=\"n\">lBonjour<\/span><span class=\"o\">,<\/span> <span class=\"n\">Toast<\/span><span class=\"o\">.<\/span><span class=\"na\">LENGTH_LONG<\/span><span class=\"o\">);<\/span>\r\n<span class=\"n\">lPopup<\/span><span class=\"o\">.<\/span><span class=\"na\">show<\/span><span class=\"o\">();<\/span>\r\n<\/pre>\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10105\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/toast_java.png\" alt=\"\" width=\"926\" height=\"388\" \/><\/p>\n<p>Voici le r\u00e9sultat en ex\u00e9cution (le \u00ab\u00a0Toast\u00a0\u00bb est point\u00e9 par la fl\u00e8che rouge):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10106\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/toast.png\" alt=\"\" width=\"216\" height=\"386\" \/><\/p>\n<h2>\u00c0 propos des versions d&rsquo;API<\/h2>\n<p>Malgr\u00e9 qu&rsquo;il est g\u00e9n\u00e9ralement mieux de permettre l&rsquo;utilisation de l&rsquo;application au plus grand nombre de personnes, il peut arriver qu&rsquo;une fonctionnalit\u00e9 soit souhait\u00e9e, pour les appareils qui peuvent le g\u00e9rer. Par exemple, voici un bout de code qui permettrait d&rsquo;ex\u00e9cuter une m\u00e9thode particuli\u00e8re (\u00ab\u00a0clearData\u00a0\u00bb) dans le cas o\u00f9 l&rsquo;appareil aurait trop peu d&rsquo;espaces m\u00e9moire vive libres:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10115\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/API_error.png\" alt=\"\" width=\"892\" height=\"218\" \/><\/p>\n<p>On voit que la m\u00e9thode ne peut pas \u00eatre ex\u00e9cut\u00e9e sur les machines ayant un API inf\u00e9rieur \u00e0 19. Puisque notre API minimal est de 16, ce programme ne peut pas \u00eatre compil\u00e9. Deux solutions s&rsquo;offrent \u00e0 nous pour r\u00e9gler cette erreur.<\/p>\n<p>La premi\u00e8re, dans le cas o\u00f9 la fonctionnalit\u00e9 est n\u00e9cessaire au bon fonctionnement de l&rsquo;application, il sera n\u00e9cessaire de modifier le SDK minimal du projet afin de le monter \u00e0 19 (voir la section sur le fichier \u00ab\u00a0build.gradle\u00a0\u00bb).<\/p>\n<p>La seconde solution est utilisable dans le cas o\u00f9 la fonctionnalit\u00e9 n&rsquo;est pas n\u00e9cessaire, mais tout de m\u00eame int\u00e9ressante \u00e0 ajout\u00e9 \u00e0 l&rsquo;application si l&rsquo;appareil de l&rsquo;utilisateur le permet. On peut donc encapsuler l&rsquo;instruction fautive dans un \u00ab\u00a0if\u00a0\u00bb, avec la condition:<\/p>\n<pre>if (Build.VERSION.SDK_INT &gt;= API_NUMBER) {<\/pre>\n<p>Dans notre exemple, on pourrait faire:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10116\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/API_no_error_if.png\" alt=\"\" width=\"688\" height=\"215\" \/>Ou, pour enlever le \u00ab\u00a0if\u00a0\u00bb inutilement imbriqu\u00e9:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10117\" src=\"https:\/\/www.louismarchand.me\/wp-content\/uploads\/2021\/08\/API_no_error.png\" alt=\"\" width=\"685\" height=\"175\" \/><\/p>\n<p><a href=\"https:\/\/www.louismarchand.me\/index.php\/programmation-android\/\">Retour<\/a><\/p>\n<hr \/>\n<p>Auteur: Louis Marchand<br \/>\n<a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/deed.fr\" target=\"_blank\" rel=\"license noopener noreferrer\"><img decoding=\"async\" src=\"https:\/\/i.creativecommons.org\/l\/by\/4.0\/80x15.png\" alt=\"Creative Commons License\" \/><\/a><br \/>\nSauf pour les sections sp\u00e9cifi\u00e9es autrement, ce travail est sous licence <a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/deed.fr\" target=\"_blank\" rel=\"license noopener noreferrer\">Creative Commons Attribution 4.0 International<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction La structure d&rsquo;un projet Android peut \u00eatre assez complexe. Dans cette page, je t\u00e2cherai de vous expliquer les diff\u00e9rents aspects importants dans un projet Android. Cr\u00e9ation d&rsquo;un nouveau projet Pour cr\u00e9er un nouveau projet, appuyez sur le bouton \u00ab\u00a0Start a new Android project\u00a0\u00bb si vous \u00eates sur l&rsquo;\u00e9cran d&rsquo;accueil d&rsquo;Android Studio, ou s\u00e9lectionnez le&hellip; <a class=\"more-link\" href=\"https:\/\/www.louismarchand.me\/index.php\/les-projets-android\/\">Continue reading <span class=\"screen-reader-text\">Les projets Android<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-169","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/169","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/comments?post=169"}],"version-history":[{"count":23,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/169\/revisions"}],"predecessor-version":[{"id":645,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/169\/revisions\/645"}],"wp:attachment":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/media?parent=169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}