{"id":2469,"date":"2016-02-22T19:56:57","date_gmt":"2016-02-22T18:56:57","guid":{"rendered":"http:\/\/olivier.hoarau.org\/?p=2469"},"modified":"2016-02-22T20:14:47","modified_gmt":"2016-02-22T19:14:47","slug":"developper-des-applications-android-sous-linux","status":"publish","type":"post","link":"https:\/\/olivier.hoarau.org\/?p=2469","title":{"rendered":"D\u00e9velopper des applications Android sous linux"},"content":{"rendered":"<p style=\"text-align: justify;\">J&rsquo;ai eu une envie subite pour le fun de voir comment programmer une application Android sous linux. En fait \u00e7a vient du fait que je suis incapable de trouver une b\u00eate application, \u00e9videmment gratuite, pour \u00e9couter de la musique o\u00f9 on puisse cr\u00e9er une liste de lecture en cochant des titres trouv\u00e9s sur la carte SD ou dans sa m\u00e9moire interne et qu&rsquo;on puisse trier sur la base de crit\u00e8res assez simples. Alors tant qu&rsquo;\u00e0 faire on n&rsquo;est jamais mieux servi que par soi m\u00eame.<\/p>\n<p style=\"text-align: justify;\">Je me rends compte que tout est fait pour faciliter ce d\u00e9veloppement, l&rsquo;environnement de d\u00e9veloppement (Software Development Kit SDK) est tr\u00e8s simple \u00e0 installer, y compris sous linux. Ensuite il faut \u00e9videmment avoir quelques bases de programmation. On trouve sur internet, un tas de sites qui expliquent comment faire votre propre application, mais ils ne vont vraiment pas loin, ils se contentent d&rsquo;aller jusqu&rsquo;au Hello World et puis c&rsquo;est tout ! J&rsquo;ai rep\u00e9r\u00e9 <a href=\"https:\/\/openclassrooms.com\/courses\/creez-des-applications-pour-android\">ce site francophone<\/a> sur <a href=\"https:\/\/openclassrooms.com\/\">OpenClassRooms<\/a> qui est vraiment excellent en approfondissant de mani\u00e8re tr\u00e8s didactique le sujet. Ce <a href=\"http:\/\/www.raywenderlich.com\/120508\/beginning-android-development-tutorial-android-studio\">post<\/a> en anglais est \u00e9galement tr\u00e8s fouill\u00e9 et r\u00e9ellement utile.<\/p>\n<p style=\"text-align: justify;\">Niveau programmation \u00e7a m&rsquo;a rappel\u00e9 ma jeunesse quand je pissais du code en C en utilisant les toolkits <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Motif_%28biblioth%C3%A8que_graphique%29\">Motif\/X11<\/a> pour construire son interface graphique, \u00e7a ne doit pas dire grand chose aux jeunes mais c&rsquo;est la biblioth\u00e8que graphique de la grande \u00e9poque d&rsquo;UNIX qui a inspir\u00e9 GTK+ et Qt, les biblioth\u00e8ques de base respectives de Gnome et de KDE. On retrouve les m\u00eames principes, on d\u00e9finit des widgets dans un environnement de d\u00e9veloppement wysiwig, puis les \u00e9v\u00e8nements (callbacks) qui vont avec.<\/p>\n<p style=\"text-align: justify;\">En attendant une page d\u00e9di\u00e9e sous mon site <a href=\"http:\/\/www.funix.org\/\">Funix<\/a>, pour en revenir \u00e0 l&rsquo;installation sous linux, on r\u00e9cup\u00e8rera le SDK android par <a href=\"http:\/\/developer.android.com\/sdk\/index.html\">l\u00e0<\/a>, ainsi qu&rsquo;un moteur JAVA dans sa version 7 par <a href=\"http:\/\/www.oracle.com\/technetwork\/java\/javase\/downloads\/jdk7-downloads-1880260.html\">ici<\/a>. On commence par installer java en tapant<\/p>\n<blockquote><p>urpmi jdk-7u79-linux-x64.rpm<\/p><\/blockquote>\n<p>Pour le SDK on d\u00e9compresse l&rsquo;archive zip en tapant<\/p>\n<blockquote><p>unzip android-studio-ide-141.2456560-linux.zip<\/p><\/blockquote>\n<p>cela donne le r\u00e9pertoire <strong>android-studio<\/strong> on lance l&rsquo;exe qui sous <strong>bin<\/strong><\/p>\n<blockquote><p>.\/studio.sh<\/p><\/blockquote>\n<p>si vous avez cette erreur<\/p>\n<blockquote><p>Please ensure JAVA_HOME points to JDK rather than JRE<\/p><\/blockquote>\n<p style=\"text-align: justify;\">\u00c9ditez votre fichier<strong> .bashrc<\/strong> et rajoutez (il faut mettre le chemin absolu de JAVA)<\/p>\n<blockquote>\n<p style=\"text-align: justify;\">export JAVA_HOME=\/usr\/java\/jdk1.7.0_79<\/p>\n<\/blockquote>\n<p style=\"text-align: justify;\">et pour prendre en compte la modification on tape <strong>source ~\/.bashrc<\/strong><\/p>\n<p style=\"text-align: justify;\">Pour la suite des op\u00e9rations et de configuration, il y a tout un tas de sites qui d\u00e9crivent tr\u00e8s bien la configuration initiale d&rsquo;Android Studio par exemple toujours celui d&rsquo;OpenClassRooms <a href=\"https:\/\/openclassrooms.com\/courses\/creez-des-applications-pour-android\/installation-et-configuration-des-outils\">ici<\/a>. A un moment on se rend compte que pour lancer un p\u00e9riph\u00e9rique virtuel (Android Virtual Device) il faut disposer de <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Kernel-based_Virtual_Machine\">KVM<\/a> (Kernel-based Virtual Machine) et d&rsquo;un noyau linux compatible permettant de faire tourner plusieurs syst\u00e8mes d&rsquo;exploitation sur la m\u00eame machine, c&rsquo;est \u00e9galement ce qu&rsquo;on appelle de la virtualisation. Pour savoir si votre noyau est compatible, on tape:<\/p>\n<blockquote>\n<p style=\"text-align: justify;\">egrep &lsquo;^flags.*(vmx|svm)&rsquo; \/proc\/cpuinfo<\/p>\n<\/blockquote>\n<p style=\"text-align: justify;\">voil\u00e0 le r\u00e9sultat avec un noyau compatible<\/p>\n<blockquote>\n<p style=\"text-align: justify;\">flags\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid xsaveopt<\/p>\n<\/blockquote>\n<p style=\"text-align: justify;\">maintenant sous Mageia 5 on installe KVM en tapant simplement <strong>urpmi kvm<\/strong>. On relance le PC, ce n&rsquo;est pas fini ! Il faut aller dans le bios, sur mon portable ThinkPad x220 j&rsquo;ai une option Virtualization et j&rsquo;ai mis \u00e0 <strong>enabled<\/strong> les options<strong> Intel (R) Virtualization technology<\/strong> et <strong>Intel (R) VT-d Feature<\/strong>. Voil\u00e0 \u00e0 quoi ressemble l&rsquo;environnement de d\u00e9veloppement<\/p>\n<p style=\"text-align: justify;\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/i0.wp.com\/www.funix.org\/fr\/linux\/images\/android\/android-studio-project.jpg?resize=474%2C242\" alt=\"\" width=\"474\" height=\"242\" \/><\/p>\n<p style=\"text-align: justify;\">Voil\u00e0 le programme que j&rsquo;ai tap\u00e9, je suis parti des sources du programme Hello World par d\u00e9faut et je me suis inspir\u00e9 des sites cit\u00e9s plus haut. Les puristes et ayatollahs de la programmation m&rsquo;excuseront, mais \u00e7a fait des ann\u00e9es (pour ne pas dire des d\u00e9cennies) que je n&rsquo;ai pas programm\u00e9 et en plus je d\u00e9couvre totalement la programmation Android ! J&rsquo;ai tout simplement construit une interface qui permet de saisir un chiffre qu&rsquo;on multiplie par 2 ensuite, c&rsquo;est tout b\u00eate ! Voil\u00e0 le fichier principal avec l&rsquo;implantation des callbacks<\/p>\n<blockquote>\n<p style=\"text-align: justify;\">import android.os.Bundle;<br \/>\nimport android.view.KeyEvent;<br \/>\nimport android.view.MotionEvent;<br \/>\nimport android.view.View;<br \/>\nimport android.view.View.OnClickListener;<br \/>\nimport android.view.View.OnKeyListener;<br \/>\nimport android.widget.Button;<br \/>\nimport android.widget.CheckBox;<br \/>\nimport android.widget.EditText;<br \/>\nimport android.widget.RadioGroup;<br \/>\nimport android.widget.TextView;<br \/>\nimport android.widget.Toast;<br \/>\nimport android.text.TextWatcher;<br \/>\nimport android.text.Editable;<\/p>\n<p>public class MainActivity extends AppCompatActivity {<\/p>\n<p>private final String defaut = \u00ab\u00a0Vous devez cliquer sur le bouton pour obtenir un r\u00e9sultat.\u00a0\u00bb;<br \/>\nButton envoyer = null;<br \/>\nEditText nombre = null;<br \/>\nTextView result = null;<\/p>\n<p>@Override<br \/>\nprotected void onCreate(Bundle savedInstanceState) {<br \/>\nsuper.onCreate(savedInstanceState);<br \/>\nsetContentView(R.layout.activity_main);<br \/>\nToolbar toolbar = (Toolbar) findViewById(R.id.toolbar);<br \/>\nsetSupportActionBar(toolbar);<\/p>\n<p>\/\/ On r\u00e9cup\u00e8re toutes les vues dont on a besoin<br \/>\nenvoyer = (Button)findViewById(R.id.button);<br \/>\n\/\/calcul = (Button)findViewById(R.id.button);<br \/>\nnombre = (EditText)findViewById(R.id.editText);<br \/>\nresult = (TextView)findViewById(R.id.textView4);<\/p>\n<p>\/\/ On attribue un listener adapt\u00e9 aux vues qui en ont besoin<br \/>\nenvoyer.setOnClickListener(envoyerListener);<br \/>\nnombre.addTextChangedListener(textWatcher);<\/p>\n<p>nombre.setOnKeyListener(modificationListener);<br \/>\n}<\/p>\n<p>\/\/ Se lance \u00e0 chaque fois qu&rsquo;on appuie sur une touche en \u00e9tant sur un EditText<br \/>\nprivate OnKeyListener modificationListener = new OnKeyListener() {<br \/>\n@Override<br \/>\npublic boolean onKey(View v, int keyCode, KeyEvent event) {<br \/>\n\/\/ On remet le texte \u00e0 sa valeur par d\u00e9faut pour ne pas avoir de r\u00e9sultat incoh\u00e9rent<br \/>\nresult.setText(defaut);<br \/>\nreturn false;<br \/>\n}<br \/>\n};<\/p>\n<p>private TextWatcher textWatcher = new TextWatcher() {<br \/>\n@Override<br \/>\npublic void onTextChanged(CharSequence s, int start, int before, int count) {<br \/>\nresult.setText(defaut);<br \/>\n}<br \/>\n@Override<br \/>\npublic void beforeTextChanged(CharSequence s, int start, int count,<br \/>\nint after) {<br \/>\n}<br \/>\n@Override<br \/>\npublic void afterTextChanged(Editable s) {<br \/>\n}<br \/>\n};<\/p>\n<p>\/\/ Uniquement pour le bouton \u00ab\u00a0Calcul\u00a0\u00bb<br \/>\nprivate OnClickListener envoyerListener = new OnClickListener() {<\/p>\n<p>@Override<br \/>\npublic void onClick(View v) {<br \/>\n\/\/ On r\u00e9cup\u00e8re le nombre<br \/>\nString t = nombre.getText().toString();<br \/>\nfloat tValue = Float.valueOf(t);<br \/>\n\/\/ Puis on v\u00e9rifie que le nombre est pas \u00e9gal \u00e0 0<br \/>\nif (tValue == 0)<br \/>\nToast.makeText(MainActivity.this, \u00ab\u00a0H\u00e9ho, pas de z\u00e9ro !\u00a0\u00bb,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Toast.LENGTH_SHORT).show();<br \/>\nelse {<br \/>\nfloat resultat = tValue \/ 2;<br \/>\nresult.setText(\u00ab\u00a0Le r\u00e9sultat est \u00a0\u00bb + String.valueOf(resultat));<br \/>\n}<br \/>\n}<br \/>\n};<\/p>\n<p>@Override<br \/>\npublic boolean onCreateOptionsMenu(Menu menu) {<br \/>\n\/\/ Inflate the menu; this adds items to the action bar if it is present.<br \/>\ngetMenuInflater().inflate(R.menu.menu_main, menu);<br \/>\nreturn true;<br \/>\n}<\/p>\n<p>@Override<br \/>\npublic boolean onOptionsItemSelected(MenuItem item) {<br \/>\n\/\/ Handle action bar item clicks here. The action bar will<br \/>\n\/\/ automatically handle clicks on the Home\/Up button, so long<br \/>\n\/\/ as you specify a parent activity in AndroidManifest.xml.<br \/>\nint id = item.getItemId();<\/p>\n<p>\/\/noinspection SimplifiableIfStatement<br \/>\nif (id == R.id.action_settings) {<br \/>\nreturn true;<br \/>\n}<\/p>\n<p>return super.onOptionsItemSelected(item);<br \/>\n}<br \/>\n}<\/p><\/blockquote>\n<p style=\"text-align: justify;\">Je vous invite \u00e0 parcourir <a href=\"https:\/\/openclassrooms.com\/courses\/creez-des-applications-pour-android\/les-widgets-les-plus-simples\">OpenClassRooms<\/a> pour comprendre ces quelques lignes. Maintenant pour tester le programme, il faut cr\u00e9er un p\u00e9riph\u00e9rique virtuel, j&rsquo;ai pris par d\u00e9faut le Nexus 5 avec Android 4.2 Jelly Bean puisque mon t\u00e9l\u00e9phone portable physique Acer Z130 fonctionne avec la version 4.2.2.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone aligncenter\" src=\"https:\/\/i0.wp.com\/www.funix.org\/fr\/linux\/images\/android\/android-studio-avd-settings-3.jpg?resize=474%2C320\" alt=\"\" width=\"474\" height=\"320\" \/><\/p>\n<p style=\"text-align: justify;\">Sur le screenshot ci-dessus, je n&rsquo;avais pas encore configur\u00e9 KVM d&rsquo;o\u00f9 le message en rouge, cela semble facultatif, sauf que l&rsquo;\u00e9mulateur ne se lan\u00e7ait pas sans&#8230; Cela donne cela ensuite avec un Nexus 5 virtuel.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone aligncenter\" src=\"https:\/\/i0.wp.com\/www.funix.org\/fr\/linux\/images\/android\/android-studio-nexus.jpg?resize=426%2C758\" alt=\"\" width=\"426\" height=\"758\" \/><\/p>\n<p style=\"text-align: justify;\">Je ne vous cache pas qu&rsquo;il faut avoir une machine bien puissante, la compilation et la virtualisation demandent pas mal de ressources, et je ne parle pas quand on passe en mode debogage. Maintenant pour pouvoir le faire tourner sur un vrai portable, il y a quelques manips \u00e0 mener au niveau, dans les options pour les d\u00e9veloppeurs, il faut activer le d\u00e9bogage USB et passer en mode PTP (appareil photo) et non mass storage. Et voil\u00e0 le r\u00e9sultat !<\/p>\n<p style=\"text-align: justify;\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/i0.wp.com\/www.funix.org\/fr\/linux\/images\/android\/acer-android.jpg?resize=474%2C632\" alt=\"\" width=\"474\" height=\"632\" \/><\/p>\n<p style=\"text-align: justify;\">\n","protected":false},"excerpt":{"rendered":"<p>J&rsquo;ai eu une envie subite pour le fun de voir comment programmer une application Android sous linux. En fait \u00e7a vient du fait que je suis incapable de trouver une b\u00eate application, \u00e9videmment gratuite, pour \u00e9couter de la musique o\u00f9 on puisse cr\u00e9er une liste de lecture en cochant des titres trouv\u00e9s sur la carte &hellip; <a href=\"https:\/\/olivier.hoarau.org\/?p=2469\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">D\u00e9velopper des applications Android sous linux<\/span>  <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false,"_share_on_mastodon":"0"},"categories":[5,12],"tags":[],"class_list":["post-2469","post","type-post","status-publish","format-standard","hentry","category-logiciels-libres","category-vie-de-funix"],"share_on_mastodon":{"url":"","error":""},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/peOjJ-DP","jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=\/wp\/v2\/posts\/2469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2469"}],"version-history":[{"count":3,"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=\/wp\/v2\/posts\/2469\/revisions"}],"predecessor-version":[{"id":2472,"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=\/wp\/v2\/posts\/2469\/revisions\/2472"}],"wp:attachment":[{"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/olivier.hoarau.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}