Jak utworzyć plik APK z podpisem Wydania za pomocą Gradle?

Chciałbym mieć mój Gradle build, aby utworzyć plik APK z podpisem Wydania za pomocą Gradle.

Nie jestem pewien, czy kod jest poprawny lub czy brakuje mi parametru podczas wykonywania gradle build?

Oto część kodu w moim pliku gradle:

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

Budowanie gradle kończy się sukcesem, a w moim folderze build/apk widzę tylko pliki ...-release-unsigned.apk i ...-debug-unaligned.apk.

Jakieś sugestie, jak to rozwiązać?

Author: Jonik, 2013-08-20

26 answers

Łatwiejszy sposób niż poprzednie odpowiedzi:

Włóż to do ~/.gradle/gradle.properties

RELEASE_STORE_FILE={path to your keystore}
RELEASE_STORE_PASSWORD=*****
RELEASE_KEY_ALIAS=*****
RELEASE_KEY_PASSWORD=*****

Zmodyfikuj swoje build.gradle tak:

...    
signingConfigs {

   release {
       storeFile file(RELEASE_STORE_FILE)
       storePassword RELEASE_STORE_PASSWORD
       keyAlias RELEASE_KEY_ALIAS
       keyPassword RELEASE_KEY_PASSWORD
   }
}

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

Wtedy możesz uruchomić gradle assembleRelease

 343
Author: David Vávra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-09 12:36:23

Udało mi się to rozwiązać dodając ten kod i budując z gradle build:

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

Generuje plik APK podpisanego wydania.

 239
Author: Jan-Terje Sørensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-20 10:04:17

Zauważ, że skrypt @ sdqali będzie (przynajmniej podczas korzystania z Gradle 1.6) pytał o hasło za każdym razem, gdy wywołujesz jakiekolwiek zadanie gradle. Ponieważ potrzebujesz go tylko podczas wykonywania gradle assembleRelease (lub podobnych), możesz użyć następującego triku:

android {
    ...
    signingConfigs {
        release {
            // We can leave these in environment variables
            storeFile file(System.getenv("KEYSTORE"))
            keyAlias System.getenv("KEY_ALIAS")

            // These two lines make gradle believe that the signingConfigs
            // section is complete. Without them, tasks like installRelease
            // will not be available!
            storePassword "notYourRealPassword"
            keyPassword "notYourRealPassword"
        }
    }
    ...
}

task askForPasswords << {
    // Must create String because System.readPassword() returns char[]
    // (and assigning that below fails silently)
    def storePw = new String(System.console().readPassword("Keystore password: "))
    def keyPw  = new String(System.console().readPassword("Key password: "))

    android.signingConfigs.release.storePassword = storePw
    android.signingConfigs.release.keyPassword = keyPw
}

tasks.whenTaskAdded { theTask -> 
    if (theTask.name.equals("packageRelease")) {
        theTask.dependsOn "askForPasswords"
    }
}

Zauważ, że musiałem również dodać następujące (pod Androidem), aby to działało:

buildTypes {
    release {
        signingConfig signingConfigs.release
    }
}
 63
Author: jclehner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-18 19:10:49

Jeśli chcesz uniknąć kodowania twardego klucza i hasła w build.gradle, możesz użyć pliku właściwości, jak wyjaśniono tutaj: obsługa konfiguracji podpisywania za pomocą GRADLE

W zasadzie:

1) Utwórz projekt myproject.Plik Właściwości w /home/[username]/.podpis {[5] } z taką treścią:

keystore=[path to]\release.keystore
keystore.password=*********
keyAlias=***********
keyPassword=********

2) Utwórz gradle.Plik Właściwości (być może w katalogu głównym projektu) o treści:

MyProject.properties=/home/[username]/.signing/myproject.properties

3) odnieść się do niego w swoim zbuduj.gradle Tak:

    if(project.hasProperty("MyProject.properties")
        && new File(project.property("MyProject.properties")).exists()) {

    Properties props = new Properties()
    props.load(new FileInputStream(file(project.property("MyProject.properties"))))

    signingConfigs {
        release {
            storeFile file(props['keystore'])
            storePassword props['keystore.password']
            keyAlias props['keyAlias']
            keyPassword props['keyPassword']
        }
    }
}
 54
Author: Igor Ganapolsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-26 05:01:07

Jak powiedział @ Destil, ale pozwól innym, którzy nie mają klucza do budowania: Łatwiejszy sposób niż poprzednie odpowiedzi:

Włóż to do ~/.gradle/gradle.properties

RELEASE_STORE_FILE={path to your keystore}
RELEASE_STORE_PASSWORD=*****
RELEASE_KEY_ALIAS=*****
RELEASE_KEY_PASSWORD=*****

Zmodyfikuj swoje build.gradle Tak:

...    
if(project.hasProperty("RELEASE_STORE_FILE")) {
    signingConfigs {    
       release {
           storeFile file(RELEASE_STORE_FILE)
           storePassword RELEASE_STORE_PASSWORD
           keyAlias RELEASE_KEY_ALIAS
           keyPassword RELEASE_KEY_PASSWORD
       }
    }
}

buildTypes {
    if(project.hasProperty("RELEASE_STORE_FILE")) {
        release {
            signingConfig signingConfigs.release
        }
    }
}
....

Wtedy możesz uruchomić gradle assembleRelease Lub gradle build

 31
Author: Gal Bracha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-24 05:47:08

(w odpowiedzi na user672009 powyżej.)

Jeszcze łatwiejsze rozwiązanie, jeśli chcesz trzymać swoje hasła z dala od repozytorium git, ale chcesz dołączyć swoją kompilację.gradle w nim, że nawet świetnie działa z smaków produktów, jest utworzenie oddzielnego pliku gradle. Nazwijmy to podpisaniem.gradle " (include it in your .gitignore). Tak, jakby to była twoja Budowa.plik gradle minus wszystko, co nie jest związane z logowaniem.

android {
    signingConfigs { 
        flavor1 {
            storeFile file("..")
            storePassword ".."
            keyAlias ".."
            keyPassword ".."
        }
        flavor2 {
            storeFile file("..")
            storePassword ".."
            keyAlias ".."
            keyPassword ".."
        }
    }
}

Potem w Twojej budowie.gradle file include this line right poniżej "zastosuj wtyczkę: 'android' "

 apply from: 'signing.gradle'

Jeśli nie masz lub nie używasz wielu smaków, Zmień nazwę" flavor1 "na" release " powyżej i powinieneś być gotowy. Jeśli używasz smaki kontynuować.

Na koniec połącz swoje smaki z prawidłowym signingConfig w swojej kompilacji.gradle file i powinieneś być skończony.

  ...

  productFlavors {

      flavor1 {
          ...
          signingConfig signingConfigs.flavor1
      }

      flavor2 {
          ...
          signingConfig signingConfigs.flavor2
      }
  }

  ...
 27
Author: jonbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:43

Automatyczne Podpisywanie aplikacji za pomocą Gradle podczas korzystania z git

To niesamowite, jak wiele zawiłych sposobów jest na to. Oto mój własny sposób, w którym staram się stosować do zaleceń Googlesa . Jednak ich wyjaśnienie nie jest do końca jasne, więc opiszę szczegółowo procedurę dla Linuksa.

Opis:

Domyślne instrukcje Google do automatycznego podpisywania aplikacji podczas budowy, bez zachowania haseł i pliki podpisów ścieżka rozwoju aplikacji (GIT) jest raczej niejasna. Oto wyjaśnione instrukcje krok po kroku, jak to zrobić.

Założenia początkowe:

Masz aplikację o nazwie "MyApp" w katalogu podanym przez następującą ścieżkę: $HOME/projects/mydev/MyApp. Jednak katalog MyApp jest używany i kontrolowane za pomocą GIT.

Tutaj wpisz opis obrazka

Problem

Oczywiście nie chcemy mieć naszych plików podpisu lub hasła nigdzie w the Git controlled katalog, nawet jeśli jesteśmy bardzo zdolni do używania .gitignore itd., to i tak jest zbyt ryzykowne i łatwe popełnienie błędu. Więc chcemy mieć na zewnątrz pliki keystore i signature.

Rozwiązanie

Musimy zrobić trzy (3) rzeczy:

  1. Utwórz plik hasła, który będzie używany przez Android Studio
  2. Utwórz plik klucza podpisu
  3. Edytuj plik modułu build.gradle do użycia (1) i (2).

W tym przykładzie wymieniamy dwa pliki:

  1. keystore.properties
  2. MyApp-release-key.jks

Możemy umieścić oba te pliki tutaj:

cd $HOME/projects/mydev/

(1) Tworzenie pliku hasła do keystore

Pierwszy plik zawiera jasne hasła tekstowe użyte w; oraz ścieżki do pliku release-key w (2). Zacznij od wypełnienia tego, ponieważ ułatwi to operację kopiowania i wklejania w następnym kroku.

cd $HOME/projects/mydev/

Edytuj keystore.properties tak aby jego treść była:

storePassword=myStorePassword
keyPassword=mykeyPassword
keyAlias=myKeyAlias
storeFile=myStoreFileLocation

Jedyną trudną częścią tutaj jest myStoreFileLocation. To jest ścieżką widzianą z pliku modułu build.gradle podczas budowania. Zazwyczaj oznacza to ścieżkę podobną do: $HOME/projects/mydev/MyApp/app/build.gradle. Aby więc wskazać MyApp-release-key.jks plik, co musimy tu umieścić to:

../../../MyApp-release-key.jks

Tutaj wybraliśmy również alias "myapp" dla klucza. Następnie ostateczny plik powinien wyglądać:

storePassword=myStorePassword
keyPassword=mykeyPassword
keyAlias=myapp
storeFile=../../../MyApp-release-key.jks

(2) Tworzenie pliku podpisu

Drugi plik jest generowany automatycznie podczas tworzenia klucza podpisu. Jeśli nie masz innych aplikacji i to jest twój jedyny keystore, następnie utwórz plik za pomocą:

cd $HOME/projects/mydev/
keytool -genkeypair -v -keystore MyApp-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias myapp

To poprosi Cię o dwa hasła i kilka informacji. (To samo co w Android Studio.) Teraz skopiuj/wklej wcześniej wybrane hasła.

(3) edytuj plik modułu gradle.build, aby użyć powyższego

Następujące części muszą być obecne w pliku Gradle build Twojej aplikacji / modułu. Najpierw dodaj następujące linie Na Zewnątrz I przed Twoim android {} blokiem.

//def keystorePropertiesFile = rootProject.file("$HOME/.android/keystore.properties")
def keystorePropertiesFile = rootProject.file("../../keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

Wtedy, wewnątrz bloku android {}, dodaj:

android {
    ...
    defaultConfig { ... }
    signingConfigs {
            release {
                keyAlias keystoreProperties['keyAlias']
                keyPassword keystoreProperties['keyPassword']
                storeFile file(keystoreProperties['storeFile'])
                storePassword keystoreProperties['storePassword']
            }
        }
    // Tell Gradle to sign your APK
    buildTypes {
        release {
            signingConfig signingConfigs.release
            ...
        }
    }
}

Teraz z powłoki możesz ponownie zbudować swoją aplikację za pomocą:

cd $HOME/projects/mydev/MyApp/app/
./gradlew clean build

Powinno to wygenerować odpowiednio podpisaną aplikację, która może być używana w Google Play.

 20
Author: not2qubit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-05 12:03:59

Jest to odpowiedź na user672009 i dodanie do postasdqali (jego kod zostanie zawieszony przy budowaniu wersji debugowania przez przycisk "Run" IDE):

Możesz użyć następującego kodu:

final Console console = System.console();
if (console != null) {

    // Building from console 
    signingConfigs {
        release {
            storeFile file(console.readLine("Enter keystore path: "))
            storePassword console.readLine("Enter keystore password: ")
            keyAlias console.readLine("Enter alias key: ")
            keyPassword console.readLine("Enter key password: ")
        }
    }

} else {

    // Building from IDE's "Run" button
    signingConfigs {
        release {

        }
    }

}
 17
Author: AChep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26

W nowszym Android Studio istnieje sposób GUI, który jest bardzo łatwy i zapełnia również plik Gradle.

  1. File -> Project Structure

  2. Module -> Wybierz główny moduł ('app' lub inną niestandardową nazwę)

  3. Signing tab - > Plus obrazek do dodania nowej konfiguracji

  4. Wypełnij dane po prawej stronie

  5. OK and Gradle file is automatically created

  6. Będziesz musiał ręcznie dodać linię signingConfig signingConfigs.NameOfYourConfig wewnątrz builtTypes{release{}}

Images:

Tutaj wpisz opis obrazka

Tutaj wpisz opis obrazka

Dwa ważne(!) uwagi:

(EDIT 12/15)

  1. Aby utworzyć podpisany APK, musisz otworzyć kartę Terminal w Android Studio (u dołu głównego interfejsu) i wydać polecenie ./gradlew assembleRelease

  2. Jeśli zapomniałeś keyAlias (co mi się często zdarza), będziesz musiał zainicjować Build -> Generate Signed APK, aby rozpocząć proces i zobaczyć nazwę klucza aliasu.

 14
Author: sandalone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-03 18:44:54

Jeśli zbudujesz apk za pomocą linii poleceń, tak jak ja, możesz podać konfigurację podpisywania jako argumenty.

Dodaj to do swojego build.gradle

def getStore = { ->
    def result = project.hasProperty('storeFile') ? storeFile : "null"
    return result
}

def getStorePassword = { ->
    def result = project.hasProperty('storePassword') ? storePassword : ""
    return result
}

def getKeyAlias = { ->
    def result = project.hasProperty('keyAlias') ? keyAlias : ""
    return result
}

def getKeyPassword = { ->
    def result = project.hasProperty('keyPassword') ? keyPassword : ""
    return result
}

Make your signingConfigs like this

signingConfigs {
    release {
        storeFile file(getStore())
        storePassword getStorePassword()
        keyAlias getKeyAlias()
        keyPassword getKeyPassword()
    }
}

Następnie wykonujesz gradlew w ten sposób

./gradlew assembleRelease -PstoreFile="keystore.jks" -PstorePassword="password" -PkeyAlias="alias" -PkeyPassword="password"
 14
Author: Egis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-14 12:10:35
android {
    compileSdkVersion 17
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 18
    }

    File signFile = rootProject.file('sign/keystore.properties')
    if (signFile.exists()) {
        Properties properties = new Properties()
        properties.load(new FileInputStream(signFile))
        signingConfigs {
            release {
                storeFile rootProject.file(properties['keystore'])
                storePassword properties['storePassword']
                keyAlias properties['keyAlias']
                keyPassword properties['keyPassword']
            }
        }
    }

    buildTypes {
        release {
            runProguard true
            zipAlign true
            proguardFile rootProject.file('proguard-rules.cfg')
            signingConfig signingConfigs.release
        }
        debug {
            runProguard false
            zipAlign true
        }
    }
}
 10
Author: JP Ventura,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-18 16:18:12

Możesz również użyć opcji linii poleceń -P gradle, aby pomóc w podpisywaniu. W Twojej budowie.gradle, dodaj singingConfigs Tak:

signingConfigs {
   release {
       storeFile file("path/to/your/keystore")
       storePassword RELEASE_STORE_PASSWORD
       keyAlias "your.key.alias"
       keyPassword RELEASE_KEY_PASSWORD
   }
}

Następnie wywołaj gradle build Tak:

gradle -PRELEASE_KEYSTORE_PASSWORD=******* -PRELEASE_KEY_PASSWORD=****** build

Możesz użyć opcji-P, aby ustawić storeFile i keyAlias, jeśli wolisz.

Jest to w zasadzie rozwiązanie Destila, ale z opcjami wiersza poleceń.

Aby uzyskać więcej informacji na temat właściwości gradle, sprawdź podręcznik użytkownika gradle.

 8
Author: Andy Shiue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-05 00:27:20

Jeśli masz już plik keystore, może to być tak proste, jak dodanie kilku parametrów do polecenia build:

./gradlew assembleRelease \
 -Pandroid.injected.signing.store.file=$KEYFILE \
 -Pandroid.injected.signing.store.password=$STORE_PASSWORD \
 -Pandroid.injected.signing.key.alias=$KEY_ALIAS \
 -Pandroid.injected.signing.key.password=$KEY_PASSWORD

Żadne stałe zmiany w projekcie Androida nie są konieczne.

Źródło: http://www.tinmith.net/wayne/blog/2014/08/gradle-sign-command-line.htm

 7
Author: janpio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-17 18:03:58

Odpowiedź @ Destil jest dobra, jeśli możesz ponownie użyć tej samej konfiguracji we wszystkich projektach. Alternatywnie, Android Studio pochodzi z pliku local.properties, który może być używany zamiast, ale podobno jest generowany przez IDE i nie mogę znaleźć sposobu, aby rozszerzyć go z poziomu Android Studio.

To jest odmiana@jonbo ' s answer . Ta odpowiedź pozwala na ustawienia specyficzne dla projektu, ale wiąże się z pewnym obciążeniem dewelopera. W szczególności, istotne kotła jest wymagane, aby przenieść signingConfigs definicja w osobnym pliku -- szczególnie jeśli trzeba to zrobić dla wielu projektów, co jest głównym powodem wyboru tego rozwiązania nad Destil' s. może to być nieco złagodzone przez również w tym linii

apply plugin: 'com.android.application'

W pliku poświadczeń, ponieważ pozwoli to na ukończenie IDE.

Wreszcie, większość rozwiązań tutaj Nie pozwala budować projekt w trybie debugowania -- który obsługuje debugowanie-podpisywanie automatycznie -- bez podania składni, jeśli nie poprawna semantycznie definicja signingConfigs. Jeśli nie trzeba produkować release build z danej maszyny, ten dodatkowy krok może być postrzegany jako niepotrzebna przeszkoda. Z drugiej strony może to być pomoc dla ignorantów lub leniwych kolegów uruchamiających debug buildy w produkcji.

To rozwiązanie pozwoli na debugowanie kompilacji bez martwienia się o poświadczenia w ogóle, ale będzie wymagało poprawnych poświadczeń do wytworzenia wersji kompilacji, a to zajmuje bardzo mało boilerplate. Jednak jako minusem Może to zachęcić innych do zastąpienia fałszywych wartości prawdziwymi poświadczeniami i nie ma sposobu, aby się przed tym zabezpieczyć.

// app/build.gradle
// Define this structure in signing.gradle to enable release builds.
ext.signing = [
        storeFilePath : 'path/to/keystore',
        storePassword : 'keystore password',
        keyAlias      : 'key alias',
        keyPassword   : 'key password',
]

if (file('signing.gradle').exists()) {
    apply from: 'signing.gradle'
}

android {
    ...
    signingConfigs {
        release {
            storeFile file(project.signing.storeFilePath)
            storePassword project.signing.storePassword
            keyAlias project.signing.keyAlias
            keyPassword project.signing.keyPassword
        }
    }
    buildTypes {
        debug { ... }
        release {
            signingConfig signingConfigs.release
            ...
        }
    }
}

Tworzy to atrapę właściwości, która służy wyłącznie do wytworzenia poprawnego składniowo pliku kompilacji. Wartości przypisane do właściwości ext.signing są nieistotne w miarę rozwoju debugowania. Aby włączyć release builds, skopiuj ext.signing do signing.gradle i zastąp wartości atrapowe poprawnymi poświadczeniami.

// signing.gradle
ext.signing = [
        storeFilePath : 'real/keystore',
        storePassword : 'real keystore password',
        keyAlias : 'real key alias',
        keyPassword : 'real key password',
]

Oczywiście, signing.gradle powinny być ignorowane przez VCS.

 6
Author: mkjeldsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:54

Prawie wszystkie platformy oferują teraz jakiś brelok do kluczy, więc nie ma powodu, aby zostawiać jasne hasła tekstowe.

Proponuję proste rozwiązanie, które wykorzystuje Moduł Keyring w Pythonie (głównie skrypt konsoli towarzyszącej keyring) i minimalne opakowanie wokół Groovy ['do', 'something'].execute() funkcja :

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

Używając tej funkcji, sekcja signingConfigs staje się:

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

Przed uruchomieniem gradle assembleRelease musisz ustawić hasła w breloku, tylko raz:

$ keyring set google-play android.keystore # will be prompted for the passwords
$ keyring set google-play com.example.app
Happy releases!
 5
Author: naufraghi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-23 22:05:35

Rozszerzając odpowiedź Davida Vavry, Utwórz plik ~/.gradle/gradle.właściwości i dodaj

RELEASE_STORE_FILE=/path/to/.keystore
RELEASE_KEY_ALIAS=XXXXX
RELEASE_STORE_PASSWORD=XXXXXXXXX
RELEASE_KEY_PASSWORD=XXXXXXXXX

Następnie w build.gradle

  signingConfigs {
    release {
    }
  }

  buildTypes {
    release {
      minifyEnabled true
      shrinkResources true

    }
  }

  // make this optional
  if ( project.hasProperty("RELEASE_KEY_ALIAS") ) {
    signingConfigs {
      release {
        storeFile file(RELEASE_STORE_FILE)
        storePassword RELEASE_STORE_PASSWORD
        keyAlias RELEASE_KEY_ALIAS
        keyPassword RELEASE_KEY_PASSWORD
      }
    }
    buildTypes {
      release {
        signingConfig signingConfigs.release
      }
    }
  }
 5
Author: SRC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-17 08:48:38

Dobrze się bawiłem, gdy to rozgryzłem. Oto mój spacer.

A do Z Jak utworzyć plik gradle w IntelliJ (V.13.1. 4) Ten spacer zakłada, że wiesz, jak utworzyć plik keystore. Aby ten samouczek zadziałał, musisz mieć plik keystore, który znajduje się w folderze aplikacji i musisz mieć zipalign.plik exe znajduje się w 'SDK-ROOT\tools'. Ten plik znajduje się zwykle w 'SDK-ROOT\build-tools' i w tym folderze będzie w najwyższym folderze api (alpha lub beta polecam wersję alpha).

Dla tych z Was, którzy chcą wskoczyć prosto tutaj jest plik Gradle build.

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 {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:20.0.0'
    compile 'com.android.support:appcompat-v7:20.0.0'
}

Możesz zbudować część tego pliku (powyżej) z opcji menu: Plik / struktura projektu Stąd wybierz aspekty i kliknij " Android-Gradle(aplikacja). Stąd zobaczysz zakładki: 'właściwości', 'podpisywanie', 'smaki', 'typy budowania' i 'Zależności' w tym kroku będziemy używać 'podpisywania' i ' budowania Typy". W sekcji "Typy kompilacji" (w sekcji Nazwa) wprowadź dowolną nazwę, którą chcesz zidentyfikować w konfiguracji typu kompilacji, a w pozostałych 4 polach Wprowadź informacje o keystore (ustawiając ścieżkę keystore w folderze aplikacji).

W polu 'Build Types' wprowadź wartość 'assembleRelease' w polu Nazwa,' Debuggable 'powinno być ustawione na false,' JNI Debug Build 'powinno być false, Ustaw' Run Proguard 'na true I' ZIP Align ' na true. To wygeneruje plik kompilacji, ale nie jako przedstawione powyżej, będziesz musiał dodać kilka rzeczy do pliku kompilacji później. Lokalizacja pliku ProGuard zostanie tutaj ustawiona ręcznie w pliku gradle build. (jak przedstawiono powyżej)

Kontenery DSL, które będziesz musiał potem dodać, są następujące:

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

Będziesz również musiał dodać:

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

Uwaga powyższy kontener DSL ('zależności') powinien znajdować się na dole pliku konfiguracyjnego, ale nie wewnątrz kontenera DSL systemu android. W celu zbudowania kontenera zależności z menu IntelliJ wybierz: plik/struktura projektu. Stamtąd wybierz ponownie aspekty, a następnie Android-Gradle (aplikacja). Zobaczysz te same zakładki 5, Jak wspomniano powyżej. Wybierz zakładkę "zależności" i dodaj wymagane zależności.

Po tym wszystkim powinieneś zobaczyć Gradle build plik podobny do pliku na górze tego przejścia. Aby utworzyć podpisaną wersję ZIP aligned, musisz otworzyć zadania Gradle. Możesz przejść do tego okna, wybierając Widok / narzędzie Windows / Gradle. Stąd możesz dwukrotnie kliknąć ' assemblasemblerelease. To powinno wygenerować Twój rozkładany APK.

Potencjalne problemy, które mogą wystąpić podczas kompilacji twojego Wydania, to (ale nie tylko): Twój plik Gradle build znajduje się w niewłaściwym miejscu. Istnieją dwa pliki kompilacji Gradle; jeden w folderze głównym aplikacji, a drugi w folderze aplikacji w katalogu głównym aplikacji. Musisz użyć tego ostatniego.

Możesz też mieć problemy z kłaczkami. (Uwaga: Android Developer Studio jest znacznie lepszy w wykrywaniu problemów Lint niż IntelliJ zauważysz to podczas próby wygenerowania podpisanego APK z opcji menu)

Aby ominąć problemy z lint, musisz umieścić następujący kontener DSL w kontenerze Androida (u góry):

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

Umieszczenie tego w kontenerze DSL Androida spowoduje wygenerowanie pliku błędu w folderze kompilacji (bezpośrednio w folderze aplikacji). "lint-results-release-fatal.html ' ten plik powie Ci klasę, w której wystąpił błąd. Innym plikiem, który zostanie wygenerowany, jest plik XML zawierający "identyfikator sprawy" powiązany z błędem lint. Nazwa pliku powinna brzmieć jak ' lint-results-release-fatal.xml". Gdzieś w górnej części pliku zobaczysz węzeł 'issue', wewnątrz którego zobaczysz coś podobnego do 'id =" IDOfYourLintProblem "'

Aby rozwiązać ten problem, otwórz plik w swoim projekcie, który został wymienione w 'lint-results-assembleRelease-fatal.plik html i wprowadź następujący wiersz kodu w pliku klasy Java tuż nad nazwą klasy: @SuppressLint ("IDOfYourLintProblem"). Być może będziesz musiał zaimportować " android.adnotacja.SuppressLint; "

Więc Twój plik klasy java powinien wyglądać następująco:

package com.WarwickWestonWright.developers4u.app.CandidateArea;

import android.annotation.SuppressLint;
... other imports

@SuppressLint("IDOfYourLintProblem")
public class SearchForJobsFragment extends Fragment {... rest of your class definition}

Zauważ, że tłumienie błędów lint nie zawsze jest najlepszym pomysłem, może być lepiej zmienić kod, który spowodował błędy lint.

Kolejny problem, który może potencjalnie występuje, jeśli nie ustawiono zmiennej środowiskowej dla zmiennej środowiskowej Gradle HOME. Ta zmienna nazywa się 'GRADLE_HOME' i powinna być ustawiona na ścieżce katalogu domowego gradle, coś w stylu 'C:\gradle-1.12' Czasami możesz również ustawić zmienną środowiskową dla 'ANDROID_HOME' ustaw to na 'YOUR-SDK-Root \ sdk'

Po wykonaniu tej czynności wróć do okna Zadań Gradle i kliknij dwukrotnie wersję assemblassemblerelease.

If all is successful you powinien być w stanie przejść do folderu app \ build \ apk i znaleźć plik APK do wdrożenia.

 4
Author: user2288580,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-13 02:34:30

Miałem kilka problemów, które umieściłem następujący wiersz w złym miejscu:

signingConfigs {
    release {
        // We can leave these in environment variables
        storeFile file("d:\\Fejlesztés\\******.keystore")
        keyAlias "mykey"

        // These two lines make gradle believe that the signingConfigs
        // section is complete. Without them, tasks like installRelease
        // will not be available!
        storePassword "*****"
        keyPassword "******"
    }
}

Upewnij się, że umieściłeś części signingConfigs wewnątrz sekcji Androida:

android
{
    ....
    signingConfigs {
        release {
          ...
        }
    }
}

Zamiast

android
{
    ....
}

signingConfigs {
   release {
        ...
   }
}
Łatwo jest popełnić ten błąd.
 2
Author: Botond Kopacz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-20 17:42:16

Jeszcze jedno podejście do tego samego problemu. Ponieważ nie zaleca się przechowywania jakichkolwiek poświadczeń w kodzie źródłowym, postanowiliśmy ustawić hasła dla magazynu kluczy i aliasu kluczy w osobnym pliku właściwości w następujący sposób:

key.store.password=[STORE PASSWORD]
key.alias.password=[KEY PASSWORD]

Jeśli używasz Gita, możesz utworzyć plik tekstowy o nazwie na przykład secure.właściwości. Należy upewnić się, aby wykluczyć go z repozytorium (jeśli używasz git, dodając go do .plik gitignore). Następnie należy utworzyć konfigurację podpisywania, jak wskazują inne odpowiedzi. Jedyną różnicą jest to, w jaki sposób można załadować poświadczenia:

android {
    ...
    signingConfigs {
        ...
        release {
            storeFile file('[PATH TO]/your_keystore_file.jks')
            keyAlias "your_key_alias"

            File propsFile = file("[PATH TO]/secure.properties");
            if (propsFile.exists()) {
                Properties props = new Properties();
                props.load(new FileInputStream(propsFile))
                storePassword props.getProperty('key.store.password')
                keyPassword props.getProperty('key.alias.password')
            }
        }
        ...
    }

    buildTypes {
        ...
        release {
            signingConfig signingConfigs.release
            runProguard true
            proguardFile file('proguard-rules.txt')
        }
        ...
    }
}

Nigdy nie zapomnij ręcznie przypisać signingConfig do typu release build (z jakiegoś powodu czasami zakładam, że będzie używany automatycznie). Ponadto włączenie proguard nie jest obowiązkowe, ale jest zalecane.

Podoba nam się to podejście lepiej niż używanie zmiennych środowiskowych lub żądanie wprowadzania danych przez użytkownika, ponieważ można to zrobić z poziomu IDE, przełączając się na realease budować typ i uruchomienie aplikacji, zamiast konieczności korzystania z wiersza poleceń.

 2
Author: argenkiwi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-22 02:42:30

Android Studio Przejdź do Plik - > struktura projektu {[2] } lub naciśnij Ctrl + Alt+Shift + S

Zobacz Obraz

Tutaj wpisz opis obrazka

Kliknij Ok

Następnie signingConfigs wygeneruje się na Twojej kompilacji.plik gradle.

Tutaj wpisz opis obrazka

 2
Author: Ahamadullah Saikat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-12 10:32:07

Aby uzupełnić pozostałe odpowiedzi, Możesz również umieścić swój gradle.Plik Właściwości we własnym folderze modułu, wraz z build.gradle, na wypadek, gdyby twój keystore był specyficzny dla jednego projektu.

 1
Author: cprcrack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-28 19:41:04

Pracuję w Ubuntu14.04. vim ~/bashrc i dodaj export ANDROID_KEYSTORE= export ANDROID_KEYALIAS=

A następnie w build.gradle set.

    final Console console = System.console();
if (console != null) {

    // Building from console
    signingConfigs {
        release {
            storeFile file(System.getenv("KEYSTORE"))
            storePassword new String(System.console().readPassword("\n\$ Enter keystore password: "))
            keyAlias System.getenv("KEY_ALIAS")
            keyPassword new String(System.console().readPassword("\n\$ Enter key password: "))
        }
    }

} else {

    // Building from IDE's "Run" button
    signingConfigs {
        release {

        }
    }

}
 1
Author: ayyb1988,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 06:22:37

Alternatywą jest zdefiniowanie zadania, które działa tylko na release buildach.

android {
  ...
  signingConfigs {
     release {
        // We can leave these in environment variables
        storeFile file('nameOfKeystore.keystore')
        keyAlias 'nameOfKeyAlias'

        // These two lines make gradle believe that the signingConfigs
        // section is complete. Without them, tasks like installRelease
        // will not be available!
        storePassword "notYourRealPassword"
        keyPassword "notYourRealPassword"

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

task setupKeystore << {
final Console console = System.console();
if (console != null) {
    //def keyFile = console.readLine(“\nProject: “ + project.name + “Enter keystore path: "))
    //def keyAlias = console.readLine(“Project: “ + project.name + “Enter key alias: ")
        def storePw = new String(console.readPassword(“Project: “ + project.name + “. Enter keystore password: "))
        def keyPw  = new String(console.readPassword(“Project: “ + project.name + “.Enter keystore password: "))

    //android.signingConfigs.release.storeFile = file(keyFile);
    //android.signingConfigs.release.keyAlias = keyAlias
        android.signingConfigs.release.storePassword = storePw
        android.signingConfigs.release.keyPassword = keyPw
}
}

//Validate t
def isReleaseConfig = gradle.startParameter.taskNames.any {it.contains('Release') }
if (isReleaseConfig) {
    setupKeystore.execute();
}
 1
Author: davidpetter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-08 11:44:02

Możesz zażądać hasła z linii poleceń:

...

signingConfigs {
  if (gradle.startParameter.taskNames.any {it.contains('Release') }) {
    release {
      storeFile file("your.keystore")
      storePassword new String(System.console().readPassword("\n\$ Enter keystore password: "))
      keyAlias "key-alias"
      keyPassword new String(System.console().readPassword("\n\$ Enter keys password: "))
    } 
  } else {
    //Here be dragons: unreachable else-branch forces Gradle to create
    //install...Release tasks.
    release {
      keyAlias 'dummy'
      keyPassword 'dummy'
      storeFile file('dummy')
      storePassword 'dummy'
    } 
  }
}

...

buildTypes {
  release {

    ...

    signingConfig signingConfigs.release
  }

  ...
}

...

Blok if-then-else zapobiega żądaniom haseł podczas tworzenia wydania. Chociaż gałąź else jest nieosiągalna, zmusza Gradle ' a do utworzenia install...Release zadania.

Backstory . Jak zaznaczono przez https://stackoverflow.com/a/19130098/3664487, " Skrypty Gradle mogą podpowiadać o wprowadzeniu danych przez Użytkownika za pomocą systemu.console ().metoda readLine ."Niestety, Gradle zawsze zażąda hasła, nawet podczas tworzenia wydania debugującego (por. Jak utworzyć plik APK z podpisem Wydania za pomocą Gradle?). Na szczęście można to przezwyciężyć, jak pokazałem powyżej.

 1
Author: user2768,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:09

Jeśli nie chcesz widzieć nie można wywołać metody readLine() na obiekcie null. musisz napisać gradle.properties first.

KEYSTORE_PASS=*****
ALIAS_NAME=*****
ALIAS_PASS=*****
 -1
Author: JeasonWong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-25 03:49:23

Jeśli, podobnie jak ja, chcesz po prostu uruchomić wydanie na swoim urządzeniu w celach testowych, rozważ utworzenie drugiego keystore {[2] } do podpisywania, abyś mógł po prostu umieścić hasła do niego w swojej kompilacji.gradle nie martwiąc się o bezpieczeństwo Twojego sklepu z kluczami rynkowymi.

Możesz utworzyć nowy keystore, klikając Build / Generate Signed APK / Create new...

 -1
Author: Torge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-21 08:35:50