{"id":6100,"date":"2025-08-15T18:34:34","date_gmt":"2025-08-15T16:34:34","guid":{"rendered":"https:\/\/gpmfactory.com\/?p=6100"},"modified":"2025-08-15T21:13:39","modified_gmt":"2025-08-15T19:13:39","slug":"partage-dimage-sous-android-avec-une-application-oracle-apex-pwa","status":"publish","type":"post","link":"https:\/\/gpmfactory.com\/index.php\/2025\/08\/15\/partage-dimage-sous-android-avec-une-application-oracle-apex-pwa\/","title":{"rendered":"Partage d&rsquo;image sous Android avec une application Oracle APEX PWA"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\"><strong>Contexte<\/strong><\/h3>\n\n\n\n<p>J\u2019avais un besoin simple sur le papier : permettre \u00e0 des utilisateurs Android de partager directement une photo depuis leur galerie ou Google Photos vers mon application Oracle APEX, qui est packag\u00e9e en <strong>PWA<\/strong>.<br>Objectif : que l\u2019utilisateur choisisse <em>Partager \u2192 mon appli<\/em> et que la photo soit automatiquement transmise \u00e0 APEX.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2. D\u00e9fi technique<\/strong><\/h3>\n\n\n\n<p>Oracle APEX n\u2019int\u00e8gre pas nativement la fonctionnalit\u00e9 <strong>Web Share Target API<\/strong>, qui permet aux PWA de recevoir des fichiers depuis le menu de partage du mobile.<br>Probl\u00e8me suppl\u00e9mentaire : l\u2019architecture <strong>ORDS sur le cloud<\/strong> impose des chemins fixes (<code>\/pls\/apex\/&lt;workspace&gt;\/...<\/code>), compliquant l\u2019int\u00e9gration directe dans le service worker.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3. La solution<\/strong><\/h3>\n\n\n\n<p>Apr\u00e8s plusieurs tests et un dialogue avec ChatGPT, la cl\u00e9 a \u00e9t\u00e9 de :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>D\u00e9clarer un <strong><code>share_target<\/code><\/strong> dans le <code>manifest.json<\/code> de l\u2019appli APEX.<\/li>\n\n\n\n<li>Utiliser un <strong>Service Worker custom<\/strong> pour intercepter le <code>POST<\/code> envoy\u00e9 par Android au partage.<\/li>\n\n\n\n<li>R\u00e9cup\u00e9rer le fichier envoy\u00e9 (<code>formData<\/code>) dans le SW, <strong>compresser l\u2019image<\/strong> pour limiter la taille (500 Ko max), et l\u2019envoyer vers un <strong>REST ORDS<\/strong> d\u00e9di\u00e9.<\/li>\n\n\n\n<li>Retourner un script de redirection vers une page APEX publique avec l\u2019<code>ID<\/code> de la photo.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4. Points techniques cl\u00e9s<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Activation imm\u00e9diate du Service Worker (<code>skipWaiting()<\/code> et <code>clients.claim()<\/code>).<\/li>\n\n\n\n<li>Compression c\u00f4t\u00e9 client via <code>OffscreenCanvas<\/code> et r\u00e9duction progressive de qualit\u00e9.<\/li>\n\n\n\n<li>Possibilit\u00e9 d\u2019extraire les donn\u00e9es EXIF GPS avant compression.<\/li>\n\n\n\n<li>Gestion des erreurs (<code>405 Method Not Allowed<\/code> sur mauvais endpoint, \u00e9cran blanc Android lors du premier partage). Ce point est encore \u00e0 am\u00e9liorer.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>5. R\u00e9sultat<\/strong><\/h3>\n\n\n\n<p>\u2705 Les utilisateurs peuvent d\u00e9sormais partager une photo directement depuis Google Photos ou la galerie vers l\u2019appli APEX.<br>\u2705 Temps d\u2019envoi r\u00e9duit gr\u00e2ce \u00e0 la compression locale.<br>\u2705 Int\u00e9gration fluide dans un environnement cloud sans modification du serveur APEX.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>6. Conclusion \/ Call to Action<\/strong><\/h3>\n\n\n\n<p>Cette approche montre que m\u00eame avec les contraintes d\u2019APEX et ORDS sur le cloud, il est possible de tirer parti des APIs modernes du Web pour offrir une exp\u00e9rience mobile plus naturelle.<br><\/p>\n\n\n\n<p>Ce post a \u00e9t\u00e9 r\u00e9dig\u00e9 avec ChatGPT<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Mat\u00e9riel<\/h3>\n\n\n\n<p><a href=\"https:\/\/github.com\/patrickmonaco\/ShareImages\">https:\/\/github.com\/patrickmonaco\/ShareImages<\/a><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Contexte J\u2019avais un besoin simple sur le papier : permettre \u00e0 des utilisateurs Android de partager directement une photo depuis leur galerie ou Google&#8230;<\/p>\n","protected":false},"author":1,"featured_media":6110,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"ppma_author":[150],"class_list":["post-6100","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-non-classe"],"authors":[{"term_id":150,"user_id":1,"is_guest":0,"slug":"admin8700","display_name":"Patrick","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/209d5ed69b74d288390621ab4c1d3773?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/6100","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/comments?post=6100"}],"version-history":[{"count":2,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/6100\/revisions"}],"predecessor-version":[{"id":6109,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/6100\/revisions\/6109"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/media\/6110"}],"wp:attachment":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/media?parent=6100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/categories?post=6100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/tags?post=6100"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/ppma_author?post=6100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}