MediaSessionCompat FLAG_IMMUTABLE/FLAG_MUTABLE : solution complète en Kotlin

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : le lecteur « cassé » sur Android 12 et versions ultérieures

\n

Imaginez : vous publiez fièrement une mise à jour de votre application de lecteur ou de client de podcast. Quelques jours passent, et dans la section des avis apparaissent des commentaires en colère : « Après la mise à jour, la musique ne se lance plus ! », « Les boutons sur l'écran verrouillé ne fonctionnent pas ! », « L'application plante quand j'essaie de lancer un morceau ! ». Cela vous semble familier ? Vous avez probablement rencontré cette fameuse erreur qui tourmente des milliers de développeurs dans le monde entier :

\n
MediaSessionCompat : Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent
\n

Ce problème est l'une des questions les plus populaires sur Stack Overflow (des dizaines de milliers de vues), et il est directement lié aux modifications apportées à Android 12 (API level 31). Bonne nouvelle : la correction est simple et ne vous prendra pas plus de 10 minutes. Dans cet article, nous analyserons les causes de l'erreur, la solution correcte en Kotlin et les meilleures pratiques pour que votre application fonctionne à nouveau parfaitement.

\n\n

Pourquoi l'erreur se produit-elle ? Comprendre PendingIntent

\n

Pour comprendre le problème, il faut se rappeler comment fonctionne MediaSessionCompat. C'est un composant qui permet à votre application d'interagir avec les contrôles système des médias : les boutons du casque, l'écran de verrouillage, le panneau de notifications. Pour cela, il crée un PendingIntent — une sorte d'« appel différé » pour les services système. Le système utilise cet Intent pour dire à votre application : « L'utilisateur a appuyé sur Lecture/Pause/Suivant ».

\n

À partir d'Android 12 (API 31), Google a renforcé les exigences de sécurité pour PendingIntent. Auparavant, les développeurs pouvaient ne pas spécifier le flag FLAG_IMMUTABLE ou FLAG_MUTABLE, et le système utilisait par défaut la variante mutable. Désormais, vous devez explicitement indiquer si le système peut modifier le contenu de votre Intent après sa création. Si vous ne le faites pas, votre application plantera. Android 12+ ne permettra tout simplement pas de créer un tel PendingIntent.

\n\n

FLAG_IMMUTABLE vs FLAG_MUTABLE : que choisir ?

\n
    \n
  • FLAG_IMMUTABLE (recommandé) : l'Intent ne peut pas être modifié après sa création. C'est plus sûr, car un attaquant ne pourra pas falsifier les données. Utilisez ce flag dans 90% des cas, y compris pour MediaSessionCompat.
  • \n
  • FLAG_MUTABLE : l'Intent peut être modifié. Nécessaire uniquement dans des cas particuliers, par exemple si vous utilisez NotificationCompat avec des actions nécessitant des données dynamiques, ou lors de l'utilisation d'AlarmManager.
  • \n
\n

Pour MediaSessionCompat et les notifications média, utilisez toujours FLAG_IMMUTABLE. Cela améliore la sécurité et la stabilité de votre application.

\n\n

Correction étape par étape en Kotlin

\n

Voyons à quoi ressemble le code typique qui provoque l'erreur, et comment le corriger. Le problème survient le plus souvent dans la méthode onCreate() de votre service ou navigateur média.

\n\n

Code incorrect (provoque un plantage sur Android 12+)

\n
// Ancienne méthode — sans spécifier de flag\nval pendingIntent = PendingIntent.getActivity(\n    this,\n    0,\n    Intent(this, MainActivity::class.java),\n    0 // <-- Erreur ! Pas de FLAG_IMMUTABLE ou FLAG_MUTABLE\n)
\n\n

Code correct en Kotlin (correction)

\n

Ajoutez simplement PendingIntent.FLAG_IMMUTABLE dans le dernier paramètre :

\n
val pendingIntent = PendingIntent.getActivity(\n    this,\n    0,\n    Intent(this, MainActivity::class.java),\n    PendingIntent.FLAG_IMMUTABLE // <-- Solution !\n)
\n

Si votre application prend en charge des versions plus anciennes d'Android (inférieures à l'API 31), utilisez une vérification conditionnelle pour éviter un plantage sur les anciens appareils :

\n
val flags = if (Build.VERS                

Blogs

Book Recommendations