621 Stimmen

Wie erstellt man eine signierte Release-APK-Datei mit Gradle?

Ich möchte, dass mein Gradle-Build eine signierte Release-APK-Datei unter Verwendung von Gradle erstellt.

Ich bin mir nicht sicher, ob der Code korrekt ist oder ob ich einen Parameter vermisse, wenn ich gradle build ausführe?

Dies ist ein Teil des Codes in meiner build.gradle/build.gradle.kts-Datei:

android {
    ...
    signingConfigs {
        release {
            storeFile(file("release.keystore"))
            storePassword("******")
            keyAlias("******")
            keyPassword("******")
        }
    }
}

Der Gradle-Build wird ERFOLGREICH abgeschlossen, und in meinem build/apk-Ordner sehe ich nur die Dateien ...-release-unsigned.apk und ...-debug-unaligned.apk.

Irgendwelche Vorschläge, wie man das lösen kann?

7voto

naufraghi Punkte 1472

Fast alle Plattformen bieten mittlerweile irgendeine Art von Schlüsselbund an, daher gibt es keinen Grund, Klartextpasswörter herumliegen zu lassen.

Ich schlage eine einfache Lösung vor, die das Python Keyring-Modul (hauptsächlich das begleitende Konsolenskript keyring) und einen minimalen Wrapper um die Groovy ['durchführen', 'etwas'].execute() Funktion verwendet:

def execOutput= { args ->
    def proc = args.execute()
    proc.waitFor()
    def stdout = proc.in.text
    return stdout.trim()
}

Mit dieser Funktion wird der Abschnitt signingConfigs wie folgt:

signingConfigs {
    release {
        storeFile file("android.keystore")
        storePassword execOutput(["keyring", "get", "google-play", storeFile.name])
        keyAlias "com.example.app"
        keyPassword execOutput(["keyring", "get", "google-play", keyAlias])
    }
}

Bevor Sie gradle assembleRelease ausführen, müssen Sie die Passwörter in Ihrem Schlüsselbund nur einmal setzen:

$ keyring set google-play android.keystore # Sie werden nach den Passwörtern gefragt
$ keyring set google-play com.example.app

Viel Erfolg bei den Veröffentlichungen!

6voto

user2288580 Punkte 2000

Ich hatte viel Spaß dabei, das herauszufinden. Hier ist mein Schritt-für-Schritt-Überblick.

Schritt-für-Schritt-Anleitung, wie man in IntelliJ (v. 13.1.4) eine Gradle-Bauplan-Datei erstellt. Diese Anleitung setzt voraus, dass Sie wissen, wie man eine Keystore-Datei erstellt. Damit dieses Tutorial funktioniert, muss sich Ihre Keystore-Datei in Ihrem App-Ordner befinden und Ihre zipalign.exe-Datei muss sich in 'SDK-ROOT\tools' befinden. Diese Datei wird normalerweise unter 'SDK-ROOT\build-tools' gefunden und in diesem Ordner befindet sie sich im höchsten API-Ordner (Alpha oder Beta, ich empfehle die Alpha-Version).

Für diejenigen von Ihnen, die direkt einsteigen möchten, hier ist die Gradle-Bauplan-Datei.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
    }
}
apply plugin: 'android'

repositories {
    mavenCentral()
}
android {
    compileSdkVersion 19
    buildToolsVersion '20.0.0'
    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    signingConfigs {
        playstore {
            keyAlias 'developers4u'
            keyPassword 'thisIsNotMyRealPassword'
            storeFile file('developers4u.keystore')
            storePassword 'realyItIsNot'
        }
    }
    buildTypes {
        assembleRelease {
            debuggable false
            jniDebugBuild false
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            zipAlign true
            signingConfig signingConfigs.playstore
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:support-v4:20.0.0'
    implementation 'com.android.support:appcompat-v7:20.0.0'
}

Sie können einen Teil dieser Bauplan-Datei (oben) von der Menüoption erstellen: Datei/Projektstruktur Wählen Sie hier Facetten und klicken Sie auf 'Android-Gradle(App). Hier sehen Sie die Registerkarten: 'Eigenschaften', 'Signing', 'Varianten', 'Build-Typen' und 'Abhängigkeiten'. Für diese Schritt-für-Schritt-Anleitung verwenden wir nur 'Signing' und 'Build-Typen'. Geben Sie unter 'Build-Typen' (im Namensabschnitt) den gewünschten Namen für Ihre Build-Typ-Konfiguration ein und geben Sie in die anderen 4 Felder Ihre Keystore-Informationen ein (den Keystore-Pfad auf den im App-Ordner angegebenen).

Geben Sie unter 'Build-Typen' den Wert 'assembleRelease' in das Namensfeld ein, 'Debuggable' sollte auf false gesetzt werden, 'Jni Debug Build' sollte auf false gesetzt werden, setzen Sie 'Run Proguard' auf true und 'Zip Align' auch auf true. Dies wird die Bauplan-Datei generieren, jedoch nicht wie oben dargestellt, Sie müssen einige Dinge zur Bauplan-Datei hinzufügen. Der ProGuard-Dateiort wird hier manuell in der Gradle-Bauplan-Datei festgelegt (wie oben abgebildet).

Die DSL-Behälter, die Sie anschließend hinzufügen müssen, sind wie folgt:

android {
    ....
    compileSdkVersion 19
    buildToolsVersion '20.0.0'
    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    ....
}

Sie müssen auch hinzufügen:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:support-v4:20.0.0'
    implementation 'com.android.support:appcompat-v7:20.0.0'
}

Beachten Sie, dass dieser DSL-Behälter oben ('Abhängigkeiten') sich am Ende der Konfigurationsdatei befinden sollte, aber nicht innerhalb des android DSL-Behälters. Um den Abhängigkeiten-Behälter von IntelliJ aus zu erstellen, wählen Sie im Menü: Datei/Projektstruktur. Wählen Sie erneut Facetten und dann Android-Gradle(app). Sie sehen die gleichen 5 Registerkarten wie oben erwähnt. Wählen Sie die Registerkarte 'Abhängigkeiten' und fügen Sie die benötigten Abhängigkeiten hinzu.

Nachdem all dies erledigt ist, sollte Ihre Gradle-Bauplan-Datei ähnlich aussehen wie die Datei oben in dieser Schritt-für-Schritt-Anleitung. Zum Erstellen Ihrer signierten, zip-alignierten Release müssen Sie die Gradle-Aufgaben öffnen. Sie können zu diesem Fenster gelangen, indem Sie Ansicht/Werkzeugfenster/Gradle auswählen. Von hier aus können Sie doppelt auf 'assembleAssembleRelease' klicken. Dies sollte Ihre bereitstellbare APK generieren.

Die möglichen Probleme, die beim Kompilieren Ihres Releases auftreten können (sind jedoch nicht darauf beschränkt), sind: Ihre Gradle-Bauplan-Datei befindet sich am falschen Ort. Es gibt zwei Gradle-Bauplan-Dateien; eine im Stammverzeichnis Ihrer Anwendung und eine weitere im App-Ordner unter dem Anwendungsstamm. Sie müssen die letztere verwenden.

Sie könnten auch auf Lint-Probleme stoßen. (Hinweis: Das Android Developer Studio erkennt Lint-Probleme viel besser als IntelliJ, Sie werden dies bemerken, wenn Sie versuchen, eine signierte APK aus den Menüoptionen zu generieren.)

Um Lint-Probleme zu umgehen, müssen Sie folgenden DSL-Behälter innerhalb des android-Behälters (am Anfang) platzieren:

android {
        ....
    lintOptions {
        abortOnError false
    }
    ....
}

Wenn Sie dies in Ihren android-DSL-Behälter setzen, wird eine Fehlerdatei im Build-Ordner (direkt unter Ihrem App-Ordner) generiert. Der Dateiname sollte etwas wie 'lint-results-release-fatal.html' sein. Diese Datei wird Ihnen sagen, in welcher Klasse der Fehler aufgetreten ist. Eine weitere Datei, die generiert wird, ist eine XML-Datei, die die 'Issue ID' mit dem Lint-Fehler enthält. Der Dateiname sollte etwas wie 'lint-results-release-fatal.xml' sein. Irgendwo oben in der Datei sehen Sie einen Knoten 'issue', in dem Sie etwas Ähnliches wie 'id="IDIhresLintProblems"' sehen werden.

Um dieses Problem zu korrigieren, öffnen Sie die Datei in Ihrem Projekt, die in der 'lint-results-assembleRelease-fatal.html' aufgeführt war, und geben Sie die folgende Codezeile in die Java-Klassendatei ein, direkt über den Klassennamen: @SuppressLint("IDIhresLintProblems"). Möglicherweise müssen Sie 'android.annotation.SuppressLint;' importieren.

Ihre Java-Klassen-Datei sollte also so aussehen:

package com.WarwickWestonWright.developers4u.app.CandidateArea;

import android.annotation.SuppressLint;
... andere Imports

@SuppressLint("IDIhresLintProblems")
public class SearchForJobsFragment extends Fragment {... Rest Ihrer Klassendefinition}

Beachten Sie, dass das Unterdrücken von Lint-Fehlern nicht immer die beste Lösung ist. Möglicherweise ist es besser, Ihren Code zu ändern, der die Lint-Fehler verursacht hat.

Ein weiteres Problem, das auftreten könnte, besteht darin, dass Sie die Umgebungsvariable für die Gradle-HOME-Umgebungsvariable nicht festgelegt haben. Diese Variable heißt 'GRADLE_HOME' und sollte auf den Pfad des Gradle-Home-Verzeichnisses gesetzt werden, z.B. 'C:\gradle-1.12'. Manchmal möchten Sie auch die Umgebungsvariable für 'ANDROID_HOME' setzen, setzen Sie diese auf 'IHR-SDK-Stammverzeichnis\sdk'.

Nachdem dies erledigt ist, kehren Sie zum Gradle-Aufgabenfenster zurück und klicken Sie doppelt auf 'assembleAssembleRelease'.

Wenn alles erfolgreich war, sollten Sie in den Ordner app\build\apk gehen können und dort Ihre bereitstellbare APK-Datei finden.

6voto

Mahozad Punkte 10508

Dies ist eine weitere Antwort für Kotlin-Buildskripte (build.gradle.kts).

Es versucht, aus der Datei local.properties zu lesen und greift anschließend auf die Umgebungsvariablen des Betriebssystems zurück. Dies kann insbesondere in CIs wie GitHub Actions nützlich sein (Sie können Umgebungssecrets in den Einstellungen Ihres Repositorys erstellen).

Beachten Sie, dass ich Kotlin 1.6.10 und Gradle 7.4.2 sowie das Android Gradle Plugin (AGP) 7.0.4 verwende.

import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
// ...

val environment = System.getenv()
fun getLocalProperty(key: String) = gradleLocalProperties(rootDir).getProperty(key)
fun String.toFile() = File(this)

android {
    signingConfigs {
        create("MySigningConfig") {
            keyAlias = getLocalProperty("signing.keyAlias") ?: environment["SIGNING_KEY_ALIAS"] ?: error("Error!")
            storeFile = (getLocalProperty("signing.storeFile") ?: environment["SIGNING_STORE_FILE"] ?: error("Error!")).toFile()
            keyPassword = getLocalProperty("signing.keyPassword") ?: environment["SIGNING_KEY_PASSWORD"] ?: error("Error!")
            storePassword = getLocalProperty("signing.storePassword") ?: environment["SIGNING_STORE_PASSWORD"] ?: error("Error!")
            enableV1Signing = true
            enableV2Signing = true
        }
    }

    buildTypes {
        release {
            signingConfig = signingConfigs["MySigningConfig"]
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
}

Wie gesagt, Sie können entweder eine local.properties-Datei im Stammverzeichnis Ihres Projekts mit Werten für die Eigenschaften haben:

signing.keyAlias=Mein Schlüssel
signing.keyPassword=zyxwvuts
signing.storePassword=abcdefgh
signing.storeFile=C\:\\Users\\Mahozad\\keystore.jks

... oder Sie können Umgebungsvariablen in Ihrem Betriebssystem setzen/erstellen; um beispielsweise eine Umgebungsvariable namens SIGNING_KEY_ALIAS zu erstellen, führen Sie aus:

  • Windows-Befehlszeile: setx SIGNING_KEY_ALIAS "Mein Schlüssel"
  • Linux-Terminal: export SIGNING_KEY_ALIAS="Mein Schlüssel"

HINWEIS: Wie in anderen Antworten erwähnt, fügen Sie Ihre local.properties-Datei NICHT Ihrem Versionskontrollsystem (wie Git) hinzu, da sie Ihre geheimen Informationen wie Passwörter usw. öffentlich zugänglich macht (wenn es sich um ein öffentliches Repository handelt).

Generieren Sie Ihr APK mit einer der 3 Methoden, die diese Antwort erwähnt hat.

6voto

Willi Mentzel Punkte 24707

Für Groovy (build.gradle)

Sie sollten Ihre Signaturinformationen nicht direkt in die build.gradle Datei schreiben. Stattdessen sollten die Informationen aus einer Datei stammen, die nicht unter Versionskontrolle steht.

Erstellen Sie eine Datei signing.properties im Verzeichnis des modulspezifischen build.gradle. Vergessen Sie nicht, diese Datei zur .gitignore Datei hinzuzufügen!

signing.properties

storeFilePath=/home/willi/example.keystore
storePassword=geheim
keyPassword=geheim
keyAlias=myReleaseSigningKey

build.gradle

android {
    // ...
    signingConfigs{
        release {
            def props = new Properties()

            def fileInputStream = new FileInputStream(file('../signing.properties'))
            props.load(fileInputStream)
            fileInputStream.close()

            storeFile = file(props['storeFilePath'])
            storePassword = props['storePassword']
            keyAlias = props['keyAlias']
            keyPassword = props['keyPassword']
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
            // ...
        }
    }
}

6voto

user1506104 Punkte 5678

Es ist 2019 und ich muss APK mit V1 (Jar-Signatur) oder V2 (komplette APK-Signatur) signieren. Ich habe nach "generiere signierte apk gradle" gegoogelt und es hat mich hierher gebracht. Also füge ich hier meine originale Lösung hinzu.

signingConfigs {
    release {
        ...
        v1SigningEnabled true
        v2SigningEnabled true
    }
}

Meine originale Frage: Wie man V1 (Jar-Signatur) oder V2 (komplette APK-Signatur) aus der build.gradle-Datei verwendet

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X