Test fermé Google Play pour les apps Kotlin et Kotlin Multiplatform
Le Kotlin natif ne change pas la règle de Google. Si votre compte Play Console est un compte personnel créé après le 13 novembre 2023, vous devez mener un test fermé avec au moins 12 testeurs inscrits pendant 14 jours sans interruption avant de pouvoir demander l'accès production (aide Play Console).
Vous utilisez déjà les outils de la plateforme : aucune couche de framework entre vous et Gradle. Les pièges sont donc des pièges Gradle : un plugin Android Gradle (AGP) trop ancien pour l'API 36, un build de release qui ne casse qu'une fois R8 passé, et, pour Kotlin Multiplatform et Compose Multiplatform, le changement d'AGP 9 dans la déclaration des modules Android. Pour la règle et chaque écran de la Play Console, commencez par le guide du test fermé Google Play.
Étape 1 : targetSdk 36, et l'AGP qui le prend en charge
Depuis le 31 août 2026, les nouvelles applications et les mises à jour doivent cibler Android 16 (niveau d'API 36) ou plus. Les applications Wear OS et Android Automotive OS doivent cibler l'API 35, les applications Android TV et Android XR l'API 34 (aide Play Console).
La valeur se trouve dans le build.gradle.kts de votre module d'app, dans defaultConfig, à côté de applicationId, minSdk, versionCode et versionName (Android Developers) :
android {
defaultConfig {
applicationId = "com.yourcompany.yourapp"
targetSdk = 36
versionCode = 1
versionName = "1.0"
}
}Beaucoup de projets lisent plutôt ce nombre dans gradle/libs.versions.toml. Vérifiez d'où vient le vôtre.
Vérifiez ensuite vos outils. Google publie les versions minimales par niveau d'API (Android Developers) :
| Niveau d'API | Android Studio minimum | AGP minimum |
|---|---|---|
| 37 | Panda 3 2025.3.3 Patch 1 | 9.1.1 |
| 36.1 | Narwhal 3 Feature Drop 2025.1.3 | 8.13.0 |
| 36 | Meerkat 2024.3.1 Patch 1 | 8.9.1 |
| 35 | Koala Feature Drop 2024.2.1 | 8.6.0 |
Google prévient que des versions plus anciennes peuvent provoquer des problèmes inattendus. Vérifié le 9 novembre 2026, la dernière version stable est AGP 9.5 (octobre 2026), qui prend en charge jusqu'à l'API 37 (Android Developers). Le guide de l'API cible 36 liste les changements de comportement à retester.
Étape 2 : fixer l'application ID avant le premier import
Remplacez com.example.* maintenant. Google indique qu'une fois un artefact importé, le nom de package est fixé et ne peut plus être modifié (aide Play Console). L'application ID doit avoir au moins deux segments, et chacun doit commencer par une lettre (Android Developers).
Étape 3 : produire un AAB signé
Dans Android Studio : Build > Generate Signed Bundle/APK, choisissez Android App Bundle, puis créez ou sélectionnez votre keystore d'importation. Les consignes de Google pour la clé : une validité d'au moins 25 ans, et le même mot de passe pour la clé que pour le keystore, à cause d'un problème connu (Android Developers).
En ligne de commande : ajoutez vos informations de signature au build.gradle.kts du module d'app, puis lancez la tâche de bundle de la variante release, par exemple ./gradlew :app:bundleRelease. Gradle compile et signe le bundle. Si vous signez dans une étape séparée, utilisez jarsigner : Google indique qu'on ne peut pas utiliser apksigner sur un app bundle (Android Developers). Gardez les mots de passe du keystore hors du fichier de build que vous versionnez.
Avec la signature d'application Play, Google détient la clé de signature d'application et vous gardez la clé d'importation. Google peut réinitialiser une clé d'importation perdue ; une clé de signature d'application que vous gérez vous-même ne peut pas l'être (aide Play Console).
Google Sign-In et Firebase. C'est Google qui signe les APK que reçoivent vos testeurs : enregistrez auprès de vos fournisseurs d'API l'empreinte de la clé de signature d'application affichée dans la Play Console, pas seulement celle de votre clé d'importation (même source). La tâche Gradle signingReport affiche vos empreintes locales (Android Developers).
Étape 4 : versionCode augmente à chaque import
versionCode est le numéro interne que compare Google Play ; versionName est ce que voient les utilisateurs. Chaque version doit avoir un versionCode plus grand, vous ne pouvez pas en réutiliser un, et le maximum de Google Play est 2 100 000 000 (Android Developers). Vous publierez des correctifs pendant les 14 jours : augmentez-le de un à chaque fois, ou dérivez-le du numéro de build de votre intégration continue.
Étape 5 : tester le build R8, pas seulement le debug
Google recommande de n'activer l'optimisation de l'app que pour le build de release (Android Developers) : les problèmes de R8 n'apparaissent donc que là.
- AGP 9.3 et plus : réglez
enable = truedans un blocoptimization {}du type de build release. Les règles de conservation vont dans des fichiers.keepsoussrc/<variant>/keepRules. - AGP plus ancien :
isMinifyEnabled = trueetisShrinkResources = true, avecgetDefaultProguardFile("proguard-android-optimize.txt"). Depuis AGP 9.0,proguard-android.txtn'est plus pris en charge.
Le mode complet de R8 est actif par défaut depuis AGP 8.0 et fait des hypothèses plus strictes sur la réflexion. Les bibliothèques qui utilisent la réflexion ou une sérialisation par nom de classe peuvent avoir besoin de règles de conservation. Installez le build de release sur un vrai téléphone et parcourez la connexion, les paiements et chaque écran qui charge des données.
Étape 6 : vérifier le manifeste fusionné
Les bibliothèques ajoutent leurs propres autorisations au manifeste final. Avant l'import, ouvrez AndroidManifest.xml dans Android Studio et cliquez sur l'onglet Merged Manifest en bas de l'éditeur. Pour retirer une autorisation ajoutée par une bibliothèque, utilisez tools:node="remove" dessus dans votre propre manifeste (Android Developers). Google évalue aussi les autorisations à risque, comme les SMS ou le journal d'appels, sur les canaux de test, et une autorisation non déclarée sur une version fermée active peut vous empêcher de publier des modifications (aide Play Console).
Kotlin Multiplatform et Compose Multiplatform
JetBrains est clair : côté Android, rien de particulier. La bibliothèque Android produite par le module partagé et l'app Android sont des modules Android Gradle classiques, et la publication ne diffère pas du processus habituel (doc Kotlin). Les étapes 1 à 6 s'appliquent. Trois points propres à KMP :
Où se trouve targetSdk. Le KMP App Template de JetBrains le range dans gradle/libs.versions.toml, sous android-targetSdk. Sur sa branche main, vérifiée le 9 novembre 2026, la valeur est 37, avec AGP 9.1.1 (modèle). Un projet plus ancien généré par l'assistant garde la valeur de sa création.
AGP 9 sépare le module d'app. À partir d'AGP 9.0, le plugin Kotlin Multiplatform n'est plus compatible avec com.android.application et com.android.library (doc Kotlin). La migration de JetBrains :
- Sortez le point d'entrée Android (
MainActivity) du module partagé (souventcomposeApp) vers un nouveau moduleandroidAppqui appliquecom.android.application. - Déplacez avec lui
applicationId,targetSdk,versionCodeetversionName. Ils n'ont plus leur place dans le module partagé. - Passez le module partagé au plugin Android-KMP library.
En solution temporaire, android.enableLegacyVariantApi=true dans gradle.properties garde l'ancienne configuration fonctionnelle sous AGP 9. JetBrains indique que ces API seront supprimées dans AGP 10.
Compiler le bon module. Après la séparation, l'AAB à importer vient d'androidApp, pas du module partagé. Lancez sa tâche de bundle release.
Étape 7 : publier sur le canal de test fermé
Dans la Play Console, allez dans Tester et publier > Tests > Tests fermés, puis Gérer le canal. Créez une version, importez le .aab, ajoutez les testeurs dans l'onglet Testeurs, choisissez les pays et envoyez les modifications pour examen.
Le lien d'inscription (opt-in) n'apparaît qu'une fois l'application à l'état « Publiée », et la première fois il peut mettre plusieurs heures à fonctionner (aide Play Console). S'il manque, voyez où trouver le lien d'inscription. Gardez vos 12 testeurs du test fermé hors du canal interne : Google indique qu'un utilisateur qui active votre test interne ne peut plus recevoir votre test fermé.
Combien de temps ça prend vraiment
- App Kotlin native avec un AGP récent : moins d'une heure jusqu'à l'AAB signé, plus le temps de tester le build R8.
- Projet KMP encore sous AGP 8 que vous passez à AGP 9 : prévoyez une demi-journée à une journée pour séparer les modules.
- Première version fermée : Google peut prendre jusqu'à sept jours, voire plus dans des cas exceptionnels, pour certains comptes (aide Play Console).
- Le test : 14 jours sans interruption. Examen de la demande d'accès production : en général sept jours ou moins (aide Play Console).
Comptez trois à quatre semaines entre votre premier import en test fermé et une publication en production.
Questions fréquentes
Les apps Kotlin natives ont-elles besoin de 12 testeurs pendant 14 jours sur Google Play ?
Oui, si votre compte Play Console est un compte personnel créé après le 13 novembre 2023. Écrire l'app en Kotlin avec Android Studio ne change pas la règle : un test fermé avec au moins 12 testeurs inscrits pendant 14 jours sans interruption.
Quelle version du plugin Android Gradle faut-il pour targetSdk 36 ?
Le tableau de Google indique qu'il faut au moins Android Studio Meerkat 2024.3.1 Patch 1 et AGP 8.9.1 pour le niveau d'API 36. Des versions plus anciennes peuvent provoquer des problèmes inattendus.
Publier une app Kotlin Multiplatform sur Google Play, est-ce différent ?
JetBrains répond que non : l'app Android d'un projet KMP est un module Android Gradle classique, qui se publie de la façon habituelle. La différence tient à la configuration du build, surtout avec AGP 9.
Pourquoi mon projet KMP casse-t-il avec AGP 9 ?
JetBrains indique qu'à partir d'AGP 9.0, le plugin Kotlin Multiplatform n'est plus compatible avec com.android.application et com.android.library dans le même module. Déplacez le point d'entrée Android dans son propre module d'app et utilisez le plugin Android-KMP library pour le code partagé.
Mon build de release plante alors que le debug fonctionne. Que vérifier ?
R8. Google recommande de n'activer l'optimisation que pour le build de release, donc le code supprimé ou renommé par R8 ne casse que là. Ajoutez des règles de conservation pour le code atteint par réflexion et testez le build de release sur un téléphone.
Sources
- support.google.com/googleplay/android-developer/answer/14151465
- support.google.com/googleplay/android-developer/answer/11926878
- support.google.com/googleplay/android-developer/answer/9845334
- support.google.com/googleplay/android-developer/answer/9842756
- support.google.com/googleplay/android-developer/answer/17367361
- support.google.com/googleplay/android-developer/answer/9214102
- support.google.com/googleplay/android-developer/answer/9859751
- developer.android.com/build/releases/about-agp
- developer.android.com/build/releases/gradle-plugin
- developer.android.com/build/configure-app-module
- developer.android.com/studio/publish/app-signing
- developer.android.com/build/building-cmdline
- developer.android.com/studio/publish/versioning
- developer.android.com/build/shrink-code
- developer.android.com/build/manage-manifests
- kotlinlang.org/docs/multiplatform/multiplatform-publish-apps.html
- kotlinlang.org/docs/multiplatform/multiplatform-project-agp-9-migration.html
- github.com/Kotlin/KMP-App-Template/blob/main/gradle/libs.versions.toml