{"id":82,"date":"2020-03-16T15:43:50","date_gmt":"2020-03-16T15:43:50","guid":{"rendered":"https:\/\/amelioretonparent.wordpress.com\/?p=82"},"modified":"2020-03-16T15:43:50","modified_gmt":"2020-03-16T15:43:50","slug":"android-lenfer-pour-acceder-aux-fichiers-du-telephone","status":"publish","type":"post","link":"https:\/\/atpart.fr\/index.php\/2020\/03\/16\/android-lenfer-pour-acceder-aux-fichiers-du-telephone\/","title":{"rendered":"Android : l&#8217;enfer pour acc\u00e9der aux fichiers du t\u00e9l\u00e9phone !"},"content":{"rendered":"<p style=\"text-align:justify;\">Pour une application qui propose de jouer un son utilisateur, il me semble normal de proposer l&#8217;utilisation des musiques\/sons disponibles sur le t\u00e9l\u00e9phone.<\/p>\n<p style=\"text-align:justify;\">Et pourtant, la mise en place d&#8217;un tel m\u00e9canisme est loin d&#8217;\u00eatre simple. A tel point que j&#8217;ai carr\u00e9ment fait une nouvelle application uniquement pour d\u00e9velopper un tel m\u00e9canisme. Mes objectifs \u00e9taient de pouvoir choisir un fichier son (*.wav, *.ohh, etc.) depuis les pr\u00e9f\u00e9rences de l&#8217;application, de fournir une gestion de liste de fichiers son et de pouvoir faire une lecture d&#8217;un fichier lorsqu&#8217;il est s\u00e9lectionn\u00e9 dans la liste. Pour faire plaisir aux enfants, je suis parti sur le d\u00e9veloppement d&#8217;une <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=fr.atpar.boitameuh\">boite \u00e0 meuh<\/a>.<\/p>\n<div id='gallery-1' class='gallery galleryid-82 gallery-columns-3 gallery-size-thumbnail'><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon portrait'>\n\t\t\t\t<a href='https:\/\/atpart.fr\/index.php\/2020\/03\/16\/android-lenfer-pour-acceder-aux-fichiers-du-telephone\/1_fr-fr\/'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/atpart.fr\/wp-content\/uploads\/2020\/03\/1_fr-fr-150x150.png\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon portrait'>\n\t\t\t\t<a href='https:\/\/atpart.fr\/index.php\/2020\/03\/16\/android-lenfer-pour-acceder-aux-fichiers-du-telephone\/2_fr-fr\/'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/atpart.fr\/wp-content\/uploads\/2020\/03\/2_fr-fr-150x150.png\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon portrait'>\n\t\t\t\t<a href='https:\/\/atpart.fr\/index.php\/2020\/03\/16\/android-lenfer-pour-acceder-aux-fichiers-du-telephone\/3_fr-fr\/'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/atpart.fr\/wp-content\/uploads\/2020\/03\/3_fr-fr-150x150.png\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure>\n\t\t<\/div>\n\n<p style=\"text-align:justify;\">Dans le d\u00e9tails, ce qui est \u00e9vident, c&#8217;est de faire une page &#8220;settings&#8221; (tr\u00e8s simple avec l&#8217;aide d&#8217;android studio), et d&#8217;ajouter la permission d&#8217;acc\u00e9der au stockage du t\u00e9l\u00e9phone.<\/p>\n<blockquote>\n<pre>&lt;uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" \/&gt;<\/pre>\n<\/blockquote>\n<p style=\"text-align:justify;\">Comme la gestion de liste d&#8217;\u00e9l\u00e9ments n&#8217;est pas au top dans les pr\u00e9f\u00e9rences (pas de gestion dynamique des \u00e9l\u00e9ments, pas possible d&#8217;associer une action \u00e0 l&#8217;\u00e9v\u00e9nement de s\u00e9lection), nous basculons alors dans une nouvelle fen\u00eatre d\u00e9di\u00e9e. L\u00e0 encore, une simple d\u00e9claration dans le fichier de configuration des pr\u00e9f\u00e9rences permet d&#8217;ouvrir une nouvelle activit\u00e9 lorsque nous s\u00e9lectionnons la pr\u00e9f\u00e9rence.<\/p>\n<blockquote>\n<pre>&lt;Preference\n    app:key=\"customSoundActivity\"\n    app:summary=\"@string\/custom_sound_picker_activity_summary\"\n    app:title=\"@string\/custom_sound_picker_activity_title\"&gt;\n    &lt;intent\n        android:targetClass=\"fr.atpar.boitameuh.ringtone.RingtonePickerActivity\"\n        android:targetPackage=\"fr.atpar.boitameuh\" \/&gt;\n&lt;\/Preference&gt;<\/pre>\n<\/blockquote>\n<p style=\"text-align:justify;\">Ensuite, la mise en place de la liste d&#8217;\u00e9l\u00e9ments sonores. Et c&#8217;est l\u00e0 que cela se complique. Nous avons \u00e0 notre disposition la classe <a href=\"https:\/\/developer.android.com\/reference\/android\/widget\/ListView\">ListView<\/a> qui pourrait tout \u00e0 fait nous convenir dans un premier temps, ou une alternative plus performante et moderne mais obsol\u00e8te, la classe <a href=\"https:\/\/developer.android.com\/reference\/android\/support\/v7\/widget\/RecyclerView.html\">RecyclerView<\/a>. Si si, c&#8217;est possible, Android l&#8217;a fait \ud83d\ude42<\/p>\n<p style=\"text-align:justify;\">Comme j&#8217;aimerais avoir deux sections, une pour les sons fournis par l&#8217;application et une pour les sons utilisateurs. Que j&#8217;aimerais jouer le fichier son lors de sa s\u00e9lection et aussi int\u00e9grer le bouton d&#8217;ajout de nouveau son directement dans la liste. Et que l&#8217;exemple trouv\u00e9 dans le code source du framework android (les param\u00e8tres de gestion de la sonnerie du t\u00e9l\u00e9phone) se base sur RecyclerView. Je suis parti sur cette solution \ud83d\ude42<\/p>\n<p style=\"text-align:justify;\">3 fichiers xml et 31 classes plus tard, j&#8217;ai enfin &#8220;la&#8221; gestion de sons qui me convient ! Enfin, presque &#8230; la lecture du fichier son ne se d\u00e9clenche pas syst\u00e9matiquement (petit probl\u00e8me de la gestion asynchrone du fichier media et la pr\u00e9emption des ressources audio du t\u00e9l\u00e9phone), la gestion de la suppression des fichiers utilisateurs est moche (bouton remove qui apparait sur un appui long), pas de v\u00e9rification sur l&#8217;existence des fichiers utilisateurs (pourtant, ils peuvent \u00eatre supprim\u00e9s \u00e0 tout moment du t\u00e9l\u00e9phone) et l&#8217;acc\u00e8s aux fichiers media du t\u00e9l\u00e9phone qui est encore perfectible (surtout pour les fichiers *.amr qui correspondent aux enregistrements audio fait directement depuis votre t\u00e9l\u00e9phone). Bon, des am\u00e9liorations qui pourront attendre l&#8217;int\u00e9gration dans l&#8217;application cible.<\/p>\n<p><a href=\"https:\/\/gitlab.com\/atpar\/boitameuh\">https:\/\/gitlab.com\/atpar\/boitameuh<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pour une application qui propose de jouer un son utilisateur, il me semble normal de proposer l&#8217;utilisation des musiques\/sons disponibles sur le t\u00e9l\u00e9phone. Et pourtant, la mise en place d&#8217;un tel m\u00e9canisme est loin d&#8217;\u00eatre simple. A tel point que j&#8217;ai carr\u00e9ment fait une nouvelle application uniquement pour d\u00e9velopper un tel m\u00e9canisme. Mes objectifs \u00e9taient [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-82","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/posts\/82","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/comments?post=82"}],"version-history":[{"count":0,"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/posts\/82\/revisions"}],"wp:attachment":[{"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/media?parent=82"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/categories?post=82"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/atpart.fr\/index.php\/wp-json\/wp\/v2\/tags?post=82"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}