2015-07-07 11 views
8

Sto cercando di aggiornare automaticamente i parametri versionName e VersionCode in Android Manifest e li uso nel nome del file di output anziché in "app-release.apk".Come aumentare e rilasciare automaticamente l'apk firmato in Android Studio usando lo script Gradle

Da this site ho aggiunto questo codice nel mio file build.gradle:

import java.util.regex.Pattern 
import com.android.builder.core.DefaultManifestParser 

def mVersionCode 
def mNextVersionName 
def newName 

task ('increaseVersionCode') << { 
    def manifestFile = file("src/main/AndroidManifest.xml") 
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"") 
    def manifestText = manifestFile.getText() 
    def matcher = pattern.matcher(manifestText) 
    matcher.find() 
    mVersionCode = Integer.parseInt(matcher.group(1)) 
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++mVersionCode + "\"") 
    manifestFile.write(manifestContent) 

} 

task ('incrementVersionName') << { 
    def manifestFile = file("src/main/AndroidManifest.xml") 
    def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"") 
    def manifestText = manifestFile.getText() 
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText) 
    matcherVersionNumber.find() 
    def majorVersion = Integer.parseInt(matcherVersionNumber.group(1)) 
    def minorVersion = Integer.parseInt(matcherVersionNumber.group(2)) 
    def pointVersion = Integer.parseInt(matcherVersionNumber.group(3)) 
    def buildVersion = Integer.parseInt(matcherVersionNumber.group(4)) 
    mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1) 
    def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"") 
    manifestFile.write(manifestContent) 

} 

tasks.whenTaskAdded { task -> 
    if (task.name == 'generateReleaseBuildConfig') { 
     task.dependsOn 'increaseVersionCode' 
     task.dependsOn 'incrementVersionName' 
    } 
} 

questo codice funziona perfettamente, le 2 operazioni eseguite e aggiornare correttamente il file manifesto. Ora voglio utilizzare le 2 variabili mVersionCode e mNextVersionName nel blocco release all'interno del buildTypes in questo modo:

newName = defaultConfig.applicationId + "-" + mNextVersionName + " (" + mVersionCode + ").apk" 
applicationVariants.all { variant -> 
       variant.outputs.each {output -> 
        def file = output.outputFile 
        output.outputFile = new File(file.parent, file.name.replace("app-release.apk", newName)) 
       } 
      } 

ma il valore restituito del 2 è nullo.

Ho provato anche l'impostazione delle proprietà e le proprietà aggiuntivi:

task.setProperty("vName", mNextVersionName) 
ext.vName = mNextVersionName 
extensions.extraProperties.set("vName", mNextVersionName) 

nei 2 compiti e inducendole nel blocco release, senza fortuna.

Qualcuno ha idee su come realizzare questo?

+0

Sarebbe meglio se possiamo eseguire quel codice di aumento in BuildType {VersionCode ..., VersionName ...}. si, l'ho fatto, hai bisogno della mia soluzione? – VinceStyling

+0

Certo, vediamo qual è la tua soluzione –

risposta

1

Allright, qui è il mio codice di build.gradle del modulo applicativo:

apply plugin: 'com.android.application' 

apply from: 'versionalization.gradle' 

def genVersionName = VersionInfo.versionName 
def genVersionCode = VersionInfo.versionCode 

android { 
    compileSdkVersion 22 
    buildToolsVersion "22.0.1" 

    defaultConfig { 
     applicationId "com.vincestyling.exerciseapk" 
     minSdkVersion 10 
     targetSdkVersion 22 
     versionName genVersionName 
     versionCode genVersionCode 
    } 
} 

android.applicationVariants.all { variant -> 
    def taskSuffix = variant.name.capitalize() 
    def assembleTaskName = "assemble${taskSuffix}" 

    if (tasks.findByName(assembleTaskName)) { 
     def processAPKTask = tasks.create(name: "process${taskSuffix}Apk", type: Copy) { 
      variant.outputs.each { output -> 
       from output.outputFile 
       into output.outputFile.parent 

       def newApkName = android.defaultConfig.applicationId + "-" + variant.buildType.name + "-" + genVersionName + " (" + genVersionCode + ").apk" 
       rename ~/(.+)/, newApkName 
      } 
     } 
     tasks[assembleTaskName].finalizedBy processAPKTask 
    } 
} 

la versionalization.gradle che applicati a testa è quello che uso per aumentare la VersionInfo, per poi tornare due valori da utilizzare.

task VersionInfo { 
    String FACTOR_KEY = "BUILD_NUMBER_FACTOR" 

    File buildDir = file("build") 
    buildDir.mkdir() 

    File factorPropFile = new File(buildDir, "kbuildfactor.prop") 

    Properties props = new Properties() 
    if (factorPropFile.exists()) { 
     props.load(new FileInputStream(factorPropFile)) 
    } 

    int buildNumberFactor = props.get(FACTOR_KEY) as Integer ?: 0 
    buildNumberFactor += 1 

    props.put(FACTOR_KEY, buildNumberFactor as String) 
    props.store(new FileOutputStream(factorPropFile), null) 



    String BASE_VERSION_NAME = "BASE_VERSION_NAME" 
    String BASE_VERSION_CODE = "BASE_VERSION_CODE" 


    File versionPropFile = file("versioning.properties") 
    props.load(new FileInputStream(versionPropFile)) 


    String baseVersionName = props.get(BASE_VERSION_NAME) as String 
    Integer baseVersionCode = props.get(BASE_VERSION_CODE) as Integer 

    ext.versionName = baseVersionName + "." + buildNumberFactor 
    ext.versionCode = baseVersionCode * 1000 + buildNumberFactor 
} 

è abbastanza semplice, leggere due file per prendere i campi necessari per costruire le informazioni sulla versione.

copia/rinomina l'ultimo APK alla fine.

Inoltre, ho ottenuto la copia/rinomina parte come prima, ma non funzionerà quando si hanno sapori di prodotto, lo incollo qui come un'altra scelta.

android.applicationVariants.all { variant -> 
    variant.outputs.each {output -> 
     def newApkName = android.defaultConfig.applicationId + "-" + variant.buildType.name + "-" + genVersionName + " (" + genVersionCode + ").apk" 

     def oldApkName = "app-${variant.buildType.name}.apk" 

     def file = output.outputFile 

     output.outputFile = new File(file.parent, file.name.replace(oldApkName, newApkName)) 
    } 
} 
+0

Grazie per averlo condiviso, è sicuramente una soluzione migliore. Vedo che il tuo codice incrementerà la versione Nome e codice con ogni configurazione (debug, release o personalizzata creata). Ci proverò (forse lo modificherò un po 'per soddisfare le mie esigenze) e Contrassegnalo come soluzione dopo. Grazie ancora! –

+0

Sì, aumenterà ogni volta, sto anche ancora cercando come prevenirlo, farlo aumentare solo la creazione di release, se hai trovato qualche idea, per favore condividi me. – VinceStyling

+0

no, non ho altre idee ... –

2

Nessuno ha risposto, ma ho trovato una soluzione funzionante. Non mi piace, può essere fatto in un modo migliore, ma per ora è l'unica soluzione che ho trovato.

Sto ancora cercando una soluzione migliore, se ne hai uno, sarò felice di leggere e usarlo al posto mio.


Così, ho aggiunto una nuova attività nel file gradle.build, ma basta fare una copia del file 'app-release.apk' e rinominarlo utilizzando i valori nel file manifesto:

task copia{ 
    dependsOn('assembleRelease') 
    def manifestFile = file("src/main/AndroidManifest.xml") 
    def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"") 
    def manifestText = manifestFile.getText() 
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText) 
    matcherVersionNumber.find() 
    def majorVersion = Integer.parseInt(matcherVersionNumber.group(1)) 
    def minorVersion = Integer.parseInt(matcherVersionNumber.group(2)) 
    def pointVersion = Integer.parseInt(matcherVersionNumber.group(3)) 
    def buildVersion = Integer.parseInt(matcherVersionNumber.group(4)) 
    def mVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion) 

    def pattern = Pattern.compile("versionCode=\"(\\d+)\"") 
    def matcher = pattern.matcher(manifestText) 
    matcher.find() 
    def myVersionCode = Integer.parseInt(matcher.group(1)) 
    copy { 
     from 'app-release.apk' 
     rename { String fileName -> 
      fileName.replace('app-release.apk', 'com.walker93.catpadova-' + mVersionName + ' (' + myVersionCode + ').apk') 
     } 
     into 'apk_outputs' 
    } 
} 

Come si può vedere è solo una copia e la versione modificata del codice nei 2 compiti precedenti con una funzione copy {} (qui la docs), legge i valori VersionName e versionCode senza di loro incremento, poi metterli in nuovo nome file che ho intenzione di sostituire.

Questa attività richiede ancora l'esecuzione dell'altra 2 attività, quindi alla fine avrete 3 attività. Nella prima riga di questa attività c'è dependsOn(assembleRelease). Questo è molto importante, eseguirà tutte le altre attività di build di rilascio predefinite (incluse le nostre 2 attività che incrementano e scrivono nel manifest) che generano l'apk aggiornato e firmato.

Ora se si tenta di eseguire il "generare APK firmato ..." si noterà che questa attività non verrà eseguita. Invece si dovrà avviare manualmente:

Aggiungi il tuo compito nei "configurazioni run" come this e allora si dovrebbe essere in grado di eseguire l'attività da here o here quando si desidera pubblicare l'APK firmato con il nome personalizzato . Se vuoi generare un apk firmato con nome predefinito (e comunque incrementare versionName e versionCode) usa semplicemente l'opzione "generare l'APK firmato ..." come prima.

Utilizzando questo metodo non è necessario aggiungere codice nella parte buildTypes del file.

0

utilizzare le proprietà estensioni in più, è necessario definirli in questo modo:

ext { 
    mVersionCode = 0 
    mNextVersionName = "" 
} 

allora sarete in grado di accedere liberamente nella vostra buildscript semplicemente utilizzando esattamente come li hai utilizzato nei vostri compiti sopra .

+0

Penso di aver già provato anche questo, l'ho letto nella documentazione ma non ha funzionato. Penso che il problema è che non posso "eseguire" il codice gradle nel blocco 'buildTypes'. –

Problemi correlati