2015-07-07 8 views
8

Ich versuche, die versionName und VersionCode-Parameter in Android Manifest automatisch zu aktualisieren und sie im Namen der Ausgabedatei anstelle von "app-release.apk" zu verwenden.Wie automatisch signierte Apk in Android Studio mit Gradle-Skript zu erhöhen und zu lösen

Von this site habe ich diesen Code in meiner build.gradle Datei:

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' 
    } 
} 

dieser Code funktioniert perfekt, die 2 Aufgaben auszuführen und korrekt die Manifest-Datei aktualisieren. Jetzt möchte ich die 2 Variablen verwenden mVersionCode und mNextVersionName im release Block innerhalb des buildTypes wie folgt aus:

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)) 
       } 
      } 

aber der Rückgabewert der 2 ist null.

Ich habe auch versucht festigende Eigenschaften und zusätzliche Eigenschaften:

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

in den 2 Aufgaben und sie im release Block ohne Glück zu bekommen.

Hat jemand Ideen, wie dies zu erreichen ist?

+0

wäre es besser, wenn wir diesen Code bei BuildType {VersionCode ..., VersionName ...} ausführen können. Ja, habe ich, brauchen Sie die Lösung von mir? – VinceStyling

+0

Sicher, lass uns sehen, was deine Lösung ist –

Antwort

1

Allright, hier ist mein Code von build.gradle Anwendungsmodul:

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 
    } 
} 

die versionalization.gradle die am Kopf angelegt ist, was ich verwende, um die Version zu erhöhen, dann zwei Werte zurück zu verwenden.

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 
} 

Es ist ziemlich einfach, lesen Sie zwei Dateien, um die notwendigen Felder zum Erstellen der Versionsinformationen zu nehmen.

Wir kopieren/benennen die endgültige APK endlich.

Außerdem habe ich die Kopie/Umbenennen Teil wie folgt zuerst, aber es wird nicht funktionieren, wenn Sie irgendwelche Produktaromen haben, ich kleben hier als eine andere Wahl.

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

Danke für die Freigabe, es ist definitiv eine bessere Lösung. Ich sehe, dass Ihr Code Version Name und Code mit jeder Konfiguration (Debug, Release oder benutzerdefinierte erstellt) inkrementieren wird. Ich werde es versuchen (vielleicht werde ich es ein wenig nach meinen Bedürfnissen bearbeiten) und es als Lösung danach markieren. Danke noch einmal! –

+0

Ja, es wird jedes Mal steigen, ich bin auch immer noch auf der Suche nach, wie man es verhindern kann, es erhöhen nur Release-Gebäude, wenn Sie irgendwelche Ideen gefunden haben, teilen Sie mich bitte. – VinceStyling

+0

Nein, ich habe keine anderen Ideen ... –

2

Niemand antwortete, aber ich fand eine funktionierende Lösung. Ich mag es nicht, es kann besser gemacht werden, aber im Moment ist die einzige Problemumgehung, die ich gefunden habe.

Ich bin immer noch auf der Suche nach einer besseren Lösung, wenn Sie eine haben, werde ich glücklich sein, es zu lesen und zu verwenden, anstatt meiner.


Also, ich eine neue Aufgabe in der gradle.build Datei hinzugefügt, es einfach eine Kopie der ‚App-release.apk‘ Datei und benennen Sie die Werte in der Manifest-Datei mit:

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' 
    } 
} 

Wie Sie es nur eine Kopie und editierte Version des Codes in den 2 vorherigen Aufgaben mit einer copy {} Funktion sehen (hier die docs), liest sie die version und version Werte, ohne sie zu erhöhen, dann legte er sich in dem Neuer Dateiname den ich ersetzen werde.

Diese Aufgabe erfordert immer noch die anderen 2 Aufgaben, damit Sie schließlich 3 Aufgaben haben. In der ersten Zeile dieser Aufgabe steht dependsOn(assembleRelease). Dies ist sehr wichtig, es wird alle anderen standardmäßigen Release-Build-Tasks ausführen (einschließlich unserer 2 Tasks, die das Manifest inkrementieren und schreiben), die die aktualisierte und signierte Apk generieren.

Jetzt, wenn Sie versuchen, die "generieren signierten APK ..." Sie werden feststellen, dass diese Aufgabe nicht ausgeführt wird. Stattdessen müssen Sie es manuell starten:

Fügen Sie Ihre Aufgabe in den „Run-Konfigurationen“ wie this und dann sollten Sie in der Lage sein, die Aufgabe von here oder here laufen, wenn Sie die signierten APK mit dem benutzerdefinierten Namen veröffentlichen mögen . Wenn Sie eine signierte apk mit dem Standardnamen erstellen möchten (und immer noch versionName und versionCode inkrementieren), verwenden Sie einfach die Option "generate signed APK ..." wie zuvor.

Mit dieser Methode ist es nicht erforderlich, Code im buildTypes Teil der Datei hinzuzufügen.

0

Um zusätzliche Eigenschaften Erweiterungen zu verwenden, müssen Sie sie wie folgt definieren:

ext { 
    mVersionCode = 0 
    mNextVersionName = "" 
} 

Dann werden Sie sie in der Lage den Zugang frei nur in Ihrem buildscript durch mit ihnen genau so, wie Sie sie in Ihre Aufgaben verwendet oben .

+0

Ich denke, ich habe das auch schon versucht, ich habe es in der Dokumentation gelesen, aber es hat nicht funktioniert. Ich denke, dass das Problem ist, dass ich Gradle-Code im 'buildTypes' Block nicht" ausführen "kann. –

Verwandte Themen