PnX-SI / gn_mobile_occtax

Application mobile pour la saisie dans le module Occtax de GeoNature
GNU General Public License v3.0
14 stars 5 forks source link

Bug sur l'ajout de média depuis la galerie #268

Open PaulLabruyere opened 1 month ago

PaulLabruyere commented 1 month ago

Version de l'application

Version d'Occtax-mobile affectée par le bug : 2.6.0 Version de GeoNature utilisée : 2.12.3

Terminal et Version Android

Marque et modèle du terminal : Xiaomi MI10T Version d'Android : 11 RKQ1.200826.002

Description du bug

Bonjour,

Un de nos utilisateurs ne parvient pas à ajouter de médias depuis la galerie photo. À ma connaissance, il est le seul dans ce cas.

Lorsqu'il clique sur "ajouter un média" puis "Depuis la galerie", la galerie s'ouvre, il choisit sa photo, l'appli revient sur l'écran du dénombrement, mais la photo n'est pas ajoutée.

Voir le fichier de log ci-joint : il semble que le fichier de la photo n'est pas trouvé. Le chemin vers le fichier me paraît étrange : on dirait une concaténation du chemin du dénombrement dans le namespace de l'appli (/storage/emulated/0/Android/data/fr.geonature.clicnatapp/inputs/276359352/taxon/61636/counting/1/) et du chemin d'origine de la photo (storage/emulated/0/DCIM/Imaging Edge Mobile/_DSC2997.JPG).

On a bien revérifié ensemble, la permission d'accès aux fichiers a bien été accordée.

Toute aide sera la bienvenue pour découvrir l'origine de ce vilain bug :bug: :mag:

occtax_20241003_153051[1].log

sgrimault commented 1 month ago

Bonjour @PaulLabruyere,

Pas mal celui là :) ~Il y a une petite limitation dans le code où le "picker" occtax/src/main/java/fr/geonature/occtax/ui/input/counting/TakePhotoLifecycleObserver.kt se limite à des fichiers JPG avec extension .jpg uniquement...~

C'est plus subtile que ça finalement...

Je vais voir ça.

Merci pour votre retour.

sgrimault commented 1 month ago

Il y a un comportement un peu bizarre lors de la récupération de l'image sélectionnée sous forme d'Uri dans la méthode asFile() de la classe occtax/src/main/java/fr/geonature/occtax/ui/input/counting/TakePhotoLifecycleObserver.kt :

Logiquement, j'ai donc en entrée le chemin vers l'image sélectionnée sous forme d'Uri. Donc ici quelque chose du genre /storage/emulated/0/DCIM/Imaging Edge Mobile/_DSC2997.JPG. Ensuite, la méthode asFile() va copier son contenu dans un nouveau fichier en reprenant le nom du fichier source (ici _DSC2997). Donc le nouveau fichier doit être créé sous /storage/emulated/0/Android/data/fr.geonature.clicnatapp/inputs/276359352/taxon/61636/counting/1/_DSC2997.jpg (cf. la partie où la variable filename est initialisée). Si ce fichier n'existe pas, on le créé en copiant la source (Uri) dans ce fichier. L'idée est d'ajouter les images pour le dénombrement en question (ici c'est le premier : counting/1/).

Le but premier de cette méthode est de copier la source dans un nouveau fichier placé directement dans le répertoire du dénombrement en cours, en essayant de respecter le nom original de la source (c'est cette partie là où ça coince...). Si pour x raisons ce nom ne peut pas être déterminé, on créé un nouveau nom basé sur le timestamp de la date courante. (cf. la partie où la variable filename est initialisée).

Le problème est que la méthode lastPathSegment appelée sur l'Uri en entrée ne semble pas retourner le dernier segment (on devrait avoir _DSC2997.JPG), mais plutôt le chemin complet (/storage/emulated/0/DCIM/Imaging Edge Mobile/_DSC2997.JPG). on le voit bien dans les logs où il cherche à accéder au fichier /storage/emulated/0/Android/data/fr.geonature.clicnatapp/inputs/276359352/taxon/61636/counting/1/storage/emulated/0/DCIM/Imaging Edge Mobile/_DSC2997.JPG (une concaténation du chemin vers le dénombrement en cours et le chemin vers la source). Comme le chemin intermédiaire /storage/emulated/0/DCIM/Imaging Edge Mobile/ n'existe pas sous le répertoire (counting/1/), il provoque une exception FileNotFoundException.

Pour mieux voir ce qu'il se passe, ce serait déjà de tracer dans les logs le chemin de l'Uri que l'on récupère en entrée de la méthode asFile(), par exemple :

Logger.debug { "selected URI: '$uri'" }

Si effectivement, au lieu de retourner le dernier segment on a un chemin complet..., une première correction serait donc de récupérer la dernière partie de l'Uri après le dernier / :

val filename = (uri.lastPathSegment ?: "${Date().time}").let {
  "${it.substringBeforeLast(".").substringAfterLast("/")}.jpg"
}

La dernière option (moins "propre") est de ne pas chercher à garder le nom original du fichier source et de faire plus simplement comme suit, en se basant par exemple sur le timestamp de la date courante :

val filename = "${Date().time}.jpg"

Où alors basé sur un UUID :

val filename = "${UUID.randomUUID()}.jpg"

Comme on veut...

sgrimault commented 1 month ago

Petites remarques pour compléter :