Skip to content

Conception du Foreground

Damien Brun edited this page Feb 5, 2026 · 2 revisions

1. Responsabilités du Service (TypingService)

Le service doit être autonome et gérer quatre piliers majeurs :

  1. Gestion de l'Audio (TTS) : Initialiser le moteur TextToSpeech et gérer la file d'attente des phrases à dicter.

  2. Interception des entrées : Capturer les touches du clavier Bluetooth (via un BroadcastReceiver ou la transmission d'événements depuis l'Activity).

  3. Logique de validation : Comparer en temps réel ce qui est tapé avec la phrase dictée et déclencher les sons de feedback (bip d'erreur/succès).

  4. Persistance : Enregistrer la session dans la base de données Room une fois l'exercice terminé ou interrompu.

2. Schéma du Cycle de Vie

Le Foreground Service suit un cycle de vie strict pour éviter d'être tué par le système Android.

Les étapes clés :

  • onCreate() : Initialisation unique du moteur TTS, du SoundPool (pour les bruitages rapides) et de la base de données Room.

  • onStartCommand() : C'est ici que le service passe en "Foreground". Il reçoit l'Intent contenant le texte à dicter et affiche la Notification Permanente.

  • Running State : Le service boucle sur les phrases. Il attend une validation (touche Entrée ou phrase complète) pour passer à la suite.

  • onDestroy() : Libération cruciale des ressources (TTS, Media Player) pour éviter les fuites de mémoire.

3. Structure Technique (Kotlin)

Voici comment structurer la classe principale pour assurer la stabilité en mode "nomade" :

class TypingService : Service() {

    private lateinit var tts: TextToSpeech
    private lateinit var soundPool: SoundPool
    private var currentText: String = ""

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val text = intent?.getStringExtra("EXTRA_TEXT") ?: ""
        
        // 1. Passer en Foreground immédiatement
        val notification = createNotification("Exercice en cours...")
        startForeground(NOTIFICATION_ID, notification)

        // 2. Lancer la dictée
        speakPhrase(text)

        return START_NOT_STICKY // Ne redémarre pas tout seul s'il est tué
    }

    private fun createNotification(content: String): Notification {
        // Construction de la notification obligatoire avec un PendingIntent
        // pour revenir à l'app si besoin.``
    }

    override fun onDestroy() {
        tts.stop()
        tts.shutdown()
        super.onDestroy()
    }
}

4. Points d'attention pour le mode "Poche"

  • Wakelocks : Bien que le Foreground Service aide, l'utilisation d'un Partial WakeLock peut être nécessaire si vous traitez des données complexes pour éviter que le CPU ne s'endorme.

  • Gestion du Focus Audio : Le service doit demander le AudioFocus. Si l'utilisateur reçoit un appel, le service doit mettre la dictée en pause automatiquement.

  • Interception Bluetooth : Puisque l'écran est éteint, l'Activity ne reçoit plus les événements clavier. Vous devrez peut-être utiliser un MediaButtonReceiver détourné ou maintenir une fenêtre invisible si les restrictions Android deviennent trop fortes sur les événements HID en arrière-plan.

Clone this wiki locally