Le téléphone balayait quarante radios toutes les trois minutes, cherchait dans
quatre catalogues et enregistrait des directs. Tout cela le tenait éveillé pour
un travail qui n'a aucune raison de se faire sur batterie.
Un serveur reprend la collecte : recherche, guet, enregistrement, file de
téléchargement, piloté depuis un navigateur. Le mobile demande ce qui a changé
depuis son curseur, télécharge et se rendort — toutes les six heures, en Wi-Fi
non facturé. Vingt fichiers quittent l'application au passage.
Le balayage devient continu plutôt qu'espacé de trois minutes : une sonde ne lit
que le premier bloc de métadonnées avant de refermer, ce qui rend la permanence
tenable quand garder les flux ouverts coûterait plusieurs mégabits par seconde.
Un morceau guetté a été capté en moins de vingt-cinq secondes. La recherche
interroge les quatre catalogues à la fois et fond leurs résultats, les plus
légers d'abord.
Quatre défauts corrigés en chemin, tous trouvés en essayant plutôt qu'en
relisant : un jeton régénéré à chaque démarrage, qui aurait obligé à
reconfigurer le mobile ; un 403 de Wikimedia dû à un agent trop générique, que
la fusion des sources masquait ; un dossier de données par défaut inaccessible
au compte qui lance le serveur ; et une lecture de métadonnées qui n'itérait
rien, faute d'être asynchrone.
Guetter un morceau supposait de savoir sur quelle station il passerait. On le
nomme désormais sans plus : les quarante stations les plus écoutées sont
balayées quatre à la fois, et l'enregistrement part dès que l'une le diffuse.
Un écran sépare ce qu'on attend de ce qu'on a capté.
Reste que la tâche périodique du système ne descend pas sous le quart d'heure,
quand un morceau dure trois à quatre minutes : elle ne peut qu'en manquer. Une
veille active, à enclencher, balaie toutes les trois minutes en service de
premier plan, et s'arrête d'elle-même une fois le guet vide. L'écran expose ce
compromis plutôt que de laisser croire à une surveillance continue gratuite.
Les titres sans pochette en reçoivent une, cherchée sur leur nom. Le nom est
nettoyé d'abord : un enregistrement radio traîne celui de sa station, qui
fausserait la recherche. Le bouton d'actualisation de l'écran Hors ligne relance
le scan et complète ce qui manque.
L'écran de lecture dit enfin d'où vient ce qu'on écoute : playlist, source,
taille, date.
Un guet ne s'enregistrait pas : le champ était vidé avant que la coroutine n'en
lise la valeur. Elle est capturée avant l'effacement.
Le nom change, et pas seulement à l'écran : identifiant d'application, paquet
Kotlin, dépôt et dossier d'enregistrements suivent, pour qu'il ne subsiste pas
deux noms selon l'endroit où l'on regarde.
Android traite le nouvel identifiant comme une application distincte : une
installation en 1.5.0 ne se mettra pas à jour seule et devra être remplacée.
C'est le prix d'un renommage complet, assumé plutôt que contourné. Les
enregistrements déjà faits ne sont pas perdus, étant dans le stockage partagé,
et le scan continue d'écarter l'ancien dossier pour ne pas les compter deux fois.
L'icône fournie est détourée de son fond blanc avant d'être déclinée : posée
telle quelle, le masque du système aurait redécoupé un badge qui l'est déjà et
laissé du blanc sur les bords. La couleur de fond est échantillonnée dans
l'image, non choisie au jugé.
La page À propos dit enfin ce que l'application fait, ce qu'elle garantit, avec
quoi elle est construite et qui en répond. Sa version vient du manifeste et son
journal du CHANGELOG du dépôt : ni l'un ni l'autre ne peut dériver. La licence
n'étant pas déclarée, la pastille le signale en rouge au lieu d'en inventer une.
Le .gitignore filtre désormais *.apk, et non un motif au nom du projet : c'est
ce motif nommé qui, au renommage, avait laissé entrer 95 Mo d'anciens APK.
Un téléchargement qui échoue restait échoué, attendant un geste. Il repart
maintenant de lui-même après cinq, quinze puis quarante-cinq secondes.
Vérifié contre un serveur qui refuse deux fois avant d'accepter : trois
requêtes, et le fichier arrive sans intervention.
Cela ne recouvre pas la coupure réseau, et c'est voulu : sans réseau, Media3
met déjà le téléchargement en attente et le reprend au retour. Les deux
mécanismes se complètent au lieu de se concurrencer.
La radio manquait. L'annuaire Radio Browser fournit les stations les plus
écoutées, par genre ou par nom ; chacune s'écoute en direct ou s'enregistre.
Un direct n'ayant pas de fin, DownloadManager ne pouvait pas s'en charger :
un service de premier plan copie le flux jusqu'à l'arrêt demandé, puis verse
le fichier dans la bibliothèque, déjà hors connexion. Les flux HLS sont
écartés de la liste, ne se laissant pas enregistrer par copie d'octets.
Le repli vers une autre source en cas d'échec n'a pas été retenu : rien ne
garantit qu'un même titre trouvé sur deux catalogues soit le même
enregistrement.
Deux bugs signalés à l'usage, et la distribution hors magasin qui manquait.
LibriVox ne renvoyait jamais rien : l'API cherche les titres en correspondance
exacte sauf préfixe « ^ », et les auteurs sur le seul nom de famille. Les trois
critères sont interrogés en parallèle et dédoublonnés, et un 404 « aucun
résultat » n'est plus confondu avec une panne.
Les téléchargements Internet Archive échouaient pour trois raisons distinctes :
éléments en accès restreint répondant 401, filtre limité aux seuls .mp3/.mp4, et
choix du premier fichier plutôt que du plus petit dérivé. La taille de chaque
résultat est désormais affichée avant sélection, ce qui distingue une chanson
d'une émission de 500 Mo.
L'application étant distribuée hors magasin, elle surveille elle-même les
releases du dépôt, télécharge l'APK en Wi-Fi et propose l'installation, qui
reste un geste de l'utilisateur comme Android l'impose.
Cachette met des médias de côté pendant qu'il y a du réseau, pour les lire
quand il n'y en a plus.
- Lecture audio et vidéo en arrière-plan (Media3 MediaSessionService)
- Mise en cache explicite, reprise automatique après coupure (WorkManager)
- Sources : appareil (MediaStore), lien direct, flux RSS de podcast
- Catalogues libres de droits : Internet Archive et LibriVox
- Parcours d'une source avec sélection multiple et téléchargement en lot
- Interface Jetpack Compose Material 3, thèmes clair et sombre
- Makefile catégorisé, publication Gitea déléguée à BorisSkill
Le fichier VERSION est la source unique de la version : versionCode en est
déduit et la publication s'y réfère.