web-dev-qa-db-fra.com

Android N - Impossible d'exécuter une API inférieure si minSDK est défini sur 14

J'essaie d'exécuter l'APK sur le périphérique API 22 après la mise à jour de compileSdkVersion sur N, mais je suis incapable de le faire.

compileSdkVersion 'Android-N'
buildToolsVersion "24.0.0 rc1"

defaultConfig {
       minSdkVersion 14
       targetSdkVersion 'N'
}

 enter image description here

17
mjosh

Les outils de construction sont immédiatement configurés pour vous empêcher d’exécuter les applications N Developer Preview sur des appareils plus anciens. Vraisemblablement, il s’agit là d’un moyen peu judicieux pour Google d’empêcher les internautes d’envoyer des éléments créés à partir de la prévisualisation. Cette approche a également été utilisée dans les deux derniers aperçus des développeurs. Google ne veut donc pas que vous testiez votre application N Developer Preview sur votre appareil Android 5.0 (API niveau 22) pour voir si vous gérez correctement la compatibilité ascendante.

¯\_ (ツ) _/¯

Heureusement, vous pouvez pirater une solution:

Android {
    compileSdkVersion 'Android-N'
    buildToolsVersion "24.0.0 rc1"

    defaultConfig {
      minSdkVersion 15
      targetSdkVersion 'N'
    }

    // based on http://stackoverflow.com/a/27372806/115145

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.processManifest.doLast {
                def manifestOutFile = output.processManifest.manifestOutputFile
                def xml = new XmlParser().parse(manifestOutFile)
                def usesSdk = xml.'uses-sdk'

                usesSdk.replaceNode{
                    'uses-sdk'('Android:minSdkVersion': '15',
                               'Android:targetSdkVersion': '15')
                }

                def fw=new FileWriter(manifestOutFile.toString())

                new XmlNodePrinter(new PrintWriter(fw)).print(xml)
            }
        }
    }
}

Ce que les outils exigent, c'est targetSdkVersion 'N', et c'est ce qui brise votre capacité à exécuter l'application sur d'anciens appareils. Ainsi, ce morceau de code Groovy permet aux outils de construction de commencer par targetSdkVersion 'N', puis d’échanger une autre valeur targetSdkVersion dans le manifeste généré, avant l’emballage. Dans ce cas, je règle les minSdkVersion et targetSdkVersion à 15, mais vous pouvez les remplacer par vos propres valeurs. De plus, vous devrez reconstruire ou nettoyer votre projet pour que le changement prenne effet.

Sur le plan positif, l’application résultante peut être installée et exécutée sur un appareil Android plus ancien (même s’il est possible que ce soit uniquement via une version en ligne de commande; je pense qu’Android Studio n’a pas aimé cette technique).

Sur le côté négatif, votre targetSdkVersion ne sera pas réellement N, ce qui peut avoir une incidence sur certains comportements sur les périphériques N Developer Preview. Vous voudrez peut-être configurer un type de construction particulier que vous utiliserez pour le test de compatibilité ascendante et ne faire que mon astuce de hack-the-manifest sur ce type de construction. Ensuite, vous pouvez tester à la fois en utilisant une configuration officielle N Developer Preview et effectuer une mesure des tests de compatibilité, dans une version.

17
CommonsWare

J'ai trouvé une solution qui fonctionne mais auparavant, un peu d'histoire. Ce que j'ai fait était d'essayer d'avoir différentes variantes de mon application et chaque variante aurait sa propre compileSdkVersion

Ce sont des extraits de mon build.gradle

Première tentative _ (compileSdkVersion est spécifique à la variante): Permet d'installer l'application au niveau de l'API> = Android-N uniquement}

    //compileSdkVersion 'Android-N'
    buildToolsVersion '24.0.0 rc1'

    productFlavors {
        dev {
            compileSdkVersion 23
            targetSdkVersion 23
        }
        experimental {
            compileSdkVersion 'Android-N'
            minSdkVersion 'N'
            targetSdkVersion 'N'
        }
    }

Deuxième tentative _ (compileSdkVersion toujours spécifique à la variante mais j'ai supprimé la variante experimental): Permet d'installer l'application au niveau de l'API <Android-N uniquement}

    //compileSdkVersion 'Android-N'
    buildToolsVersion '24.0.0 rc1'

    productFlavors {
        dev {
            compileSdkVersion 23
            targetSdkVersion 23
        }
        /*
        experimental {
            compileSdkVersion 'Android-N'
            minSdkVersion 'N'
            targetSdkVersion 'N'
        }
        */
    }

Troisième tentative _ (compileSdkVersion reste une variante spécifique mais experimental est défini avantdev)

//compileSdkVersion 'Android-N'
buildToolsVersion '24.0.0 rc1'

productFlavors {
    experimental {
        compileSdkVersion 'Android-N'
        minSdkVersion 'N'
        targetSdkVersion 'N'
    }
    dev {
        compileSdkVersion 23
        targetSdkVersion 23
    }
}

À ma grande surprise celui-ci a fonctionné! Je ne sais pas pourquoi mais c'est le cas. Tout ce que vous avez à faire est de définissez votre variante unique sous Android-N avant toute autre variante}, cliquez sur Variantes de construction dans Android Studio et sélectionnez celle que vous souhaitez compiler.

Je vais signaler un problème dans le gestionnaire de bugs Android-N et mettre à jour cette réponse lorsque j'aurai plus d'informations.

1