Мобильная разработка

Как создать подписанный APK файл для релиза с помощью Gradle

Пошаговое руководство по созданию подписанного APK файла для релиза с помощью Gradle. Решение проблем с unsigned APK и настройка signingConfigs.

4 ответа 2 просмотра

Как создать подписанный APK файл для релиза с помощью Gradle?

Я хочу, чтобы мой Gradle-сборка создавала подписанный APK файл для релиза. Не уверен, что код написан правильно или что я пропускаю какой-то параметр при выполнении команды gradle build?

Вот часть кода из моего файла build.gradle/build.gradle.kts:

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

Сборка Gradle завершается успешно, но в папке build/apk я вижу только файлы ...-release-unsigned.apk и ...-debug-unaligned.apk.

Какие есть предложения по решению этой проблемы?

Чтобы создать подписанный APK файл для релиза с помощью Gradle, необходимо правильно настроить signingConfigs и привязать его к buildTypes.release. Выполнив команду ./gradlew assembleRelease, вы получите подписанный APK в папке app/build/outputs/apk/release/. Если у вас остаются только не подписанные файлы, проверьте, что signingConfig привязан к release и что путь к keystore корректен.


Содержание


Настройка signingConfigs в build.gradle для создания подписанного APK

Основная проблема, с которой вы сталкиваетесь, заключается в том, что вы настроили signingConfigs, но не привязали его к buildTypes.release. В Gradle для Android это необходимо сделать явным образом.

Вот как должен выглядеть ваш build.gradle файл:

groovy
android {
 ...
 signingConfigs {
 release {
 storeFile file("release.keystore")
 storePassword "your_store_password"
 keyAlias "your_key_alias"
 keyPassword "your_key_password"
 // Современные параметры подписи
 v1SigningEnabled true
 v2SigningEnabled true
 }
 }
 
 buildTypes {
 release {
 // Вот эта строка отсутствовала в вашей конфигурации!
 signingConfig signingConfigs.release
 // Другие параметры release типа
 minifyEnabled true
 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 }
 }
}

Обратите внимание на строку signingConfig signingConfigs.release внутри buildTypes.release. Именно эта привязка заставляет Gradle использовать вашу конфигурацию подписи при сборке релиза.

Важно: пароли лучше хранить не прямо в файле build.gradle, а в gradle.properties или через переменные окружения. Это безопасность!


Команды Gradle для сборки подписанного APK (assembleRelease vs build)

После правильной настройки signingConfigs вам нужно выполнить правильную команду Gradle. Есть несколько вариантов:

Основные команды:

  1. ./gradlew assembleRelease - создает только подписанный APK для релиза
  2. ./gradlew build - создает все варианты сборки (debug и release)

Почему ваша сборка создает unsigned APK?

  • Если вы используете gradle assembleDebug, вы получите debug APK
  • Если signingConfig не привязан к buildTypes.release, Gradle проигнорирует его
  • Если путь к keystore неверный, Gradle создаст unsigned APK без ошибок

Где найти подписанный APK:

После успешной сборки подписанный APK будет находиться в:

app/build/outputs/apk/release/app-release.apk

Если вы видите только app-release-unsigned.apk, значит что-то пошло не так с процессом подписи.

Команда для проверки:

Вы можете проверить, какой signingConfig используется для каждого типа сборки:

bash
./gradlew app:buildTypes

Эта команда покажет информацию о всех типах сборки, включая используемые signingConfigs.


Хранение данных подписи в безопасности (gradle.properties)

Хранить пароли прямо в build.gradle - плохая практика. Вот безопасные способы:

Метод 1: gradle.properties

Создайте файл gradle.properties в корне проекта или в ~/.gradle/gradle.properties:

properties
# Безопасное хранение данных подписи
RELEASE_STORE_FILE=path/to/your/keystore.keystore
RELEASE_STORE_PASSWORD=your_store_password
RELEASE_KEY_ALIAS=your_key_alias
RELEASE_KEY_PASSWORD=your_key_password

В build.gradle используйте эти переменные:

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

Метод 2: Загрузка из внешнего файла

Для дополнительной безопасности можно использовать отдельный файл свойств:

groovy
// В build.gradle
if (project.hasProperty("signing.properties")
 && new File(project.property("signing.properties")).exists()) {
 
 def props = new Properties()
 props.load(new FileInputStream(file(project.property("signing.properties"))))
 
 android {
 signingConfigs {
 release {
 storeFile file(props['keystore'])
 storePassword props['keystore.password']
 keyAlias props['keyAlias']
 keyPassword props['keyPassword']
 }
 }
 }
}

Метод 3: Переменные окружения

Для CI/CD систем используйте переменные окружения:

groovy
android {
 signingConfigs {
 release {
 storeFile file(System.getenv("KEYSTORE_PATH"))
 storePassword System.getenv("KEYSTORE_PASSWORD")
 keyAlias System.getenv("KEY_ALIAS")
 keyPassword System.getenv("KEY_PASSWORD")
 }
 }
}

Распространенные проблемы и решения при создании подписанного APK

Проблема 1: Файл keystore не найден

Симптом: Сборка завершается успешно, но APK не подписан

Решение:

bash
// Проверьте путь к keystore
ls -la path/to/your/keystore.keystore

// Используйте абсолютный путь в build.gradle
storeFile file("/absolute/path/to/your/keystore.keystore")

Проблема 2: Неверные пароли

Симптом: Ошибка сборки или unsigned APK

Решение:

  • Проверьте пароли в файле.properties
  • Убедитесь, что пароли содержат только разрешенные символы
  • Проверьте регистр символов (пароли чувствительны к регистру)

Проблема 3: Неверный ключевой псевдоним (keyAlias)

Симптом: Ошибка “Failed to configure project :app”

Решение:

bash
// Просмотрите содержимое keystore
keytool -list -v -keystore your.keystore

// Вывод покажет доступные псевдонимы
Alias name: mykey
Creation date: Jan 1, 2023
Entry type: PrivateKeyEntry
...

Проблема 4: Проблемы с путями в Windows

Симптом: Ошибка “Could not find file” на Windows

Решение:

groovy
// Используйте двойные обратные слэши на Windows
storeFile file("C:\\path\\to\\keystore.keystore")

// Или forward slashes (работают и на Windows)
storeFile file("C:/path/to/keystore.keystore")

Проблема 5: Конфликт с плагинами

Симптом: Подпись работает в одной версии Gradle, но не в другой

Решение:
Проверьте совместимость между:

  • Версией Android Gradle Plugin
  • Версией Gradle
  • Версиями других плагинов

Обновите или синхронизируйте версии в build.gradle:

groovy
dependencies {
 classpath 'com.android.tools.build:gradle:8.1.0'
}

Современные параметры подписи APK (v1SigningEnabled и v2SigningEnabled)

В современных версиях Android Gradle Plugin появились новые параметры управления подписью APK:

groovy
signingConfigs {
 release {
 // ...
 v1SigningEnabled true // JAR подпись (Android 6.0 и ниже)
 v2SigningEnabled true // APK подпись (Android 7.0 и выше)
 }
}

Что означают эти параметры?

v1SigningEnabled (JAR Signature):

  • Подпись APK как ZIP-архива
  • Поддерживается на всех версиях Android
  • Медленнее, чем v2
  • Дает возможность частичного обновления приложения

v2SigningEnabled (APK Signature Scheme v2):

  • Более современная схема подписи
  • Быстрее, чем v1
  • Поддерживается Android 7.0 (Nougat) и выше
  • Предотвращает модификацию APK после подписи

Рекомендуемые настройки:

Версия Android Настройки
Android 7.0+ v1SigningEnabled true, v2SigningEnabled true
Только Android 6.0- v1SigningEnabled true, v2SigningEnabled false
Максимальная совместимость v1SigningEnabled true, v2SigningEnabled true

Как проверить подпись APK:

bash
// Проверьте v1 подпись
jarsigner -verify -verbose -certs app-release.apk

// Проверьте v2 подпись (требует Android SDK)
zipalign -f -v 4 app-release.apk app-release-aligned.apk
apksigner verify -v app-release-aligned.apk

Альтернативные методы передачи данных подписи для CI/CD

Для автоматизации сборки в CI/CD системах существуют несколько безопасных методов передачи данных подписи:

Метод 1: Параметры командной строки

Выполните сборку с передачей данных через параметры:

bash
./gradlew assembleRelease \
 -Pandroid.injected.signing.store.file=$KEYSTORE_PATH \
 -Pandroid.injected.signing.store.password=$KEYSTORE_PASSWORD \
 -Pandroid.injected.signing.key.alias=$KEY_ALIAS \
 -Pandroid.injected.signing.key.password=$KEY_PASSWORD

Метод 2: Secrets Manager (AWS/GCP/Azure)

Для облачных платформ:

groovy
// Пример для AWS Secrets Manager
import com.amazonaws.services.secretsmanager.AWSSecretsManager
import com.amazonaws.services.secretsmanager.model.GetSecretValueRequest

android {
 signingConfigs {
 release {
 def secret = getSecretFromAWS("your-secret-name")
 storeFile file(secret.keystorePath)
 storePassword secret.keystorePassword
 keyAlias secret.keyAlias
 keyPassword secret.keyPassword
 }
 }
}

def getSecretFromAWS(String secretName) {
 // Код для получения секрета из AWS Secrets Manager
}

Метод 3: Encrypted Files

Шифруйте файлы keystore и используйте их прямо в CI:

bash
# На локальной машине
openssl aes-256-cbc -in keystore.keystore -out keystore.enc -k encryption_key

# В CI/CD
openssl aes-256-cbc -d -in keystore.enc -out keystore.keystore -k $ENCRYPTION_KEY

Метод 4: GitHub Actions Secrets

Для GitHub Actions:

yaml
name: Build and Release
on: [push]
jobs:
 build:
 runs-on: ubuntu-latest
 steps:
 - uses: actions/checkout@v2
 - name: Set up JDK
 uses: actions/setup-java@v1
 with:
 java-version: '17'
 - name: Build Release APK
 run: ./gradlew assembleRelease
 env:
 KEYSTORE_PATH: ${{ secrets.KEYSTORE_PATH }}
 KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
 KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
 KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}

Метод 5: Firebase App Distribution

Используйте Firebase для автоматического распределения подписанных APK:

groovy
// build.gradle
plugins {
 id 'com.google.gms.google-services'
 id 'com.google.firebase.crashlytics'
 id 'com.google.firebase.firebase-perf'
 id 'com.google.appdistribution'
}

// appdistributionRelease - специальная задача для Firebase

Источники

  1. Android Developers Documentation — Официальное руководство по настройке подписи APK с помощью Gradle: https://minimum-viable-product.github.io/marshmallow-docs/tools/building/building-cmdline.html

  2. Stack Overflow Community Solutions — Комплексное руководство по созданию подписанного APK с различными методами хранения данных подписи: https://stackoverflow.com/questions/18328730/how-to-create-a-release-signed-apk-file-using-gradle

  3. Repeato Technical Guide — Практические советы по устранению проблем при создании подписанного APK и настройке современных параметров подписи: https://www.repeato.app/creating-a-release-signed-apk-file-using-gradle/

  4. Android Gradle Plugin Reference — Документация по signingConfigs DSL и современным параметрам подписи APK: https://developer.android.com/studio/build/build-gradle-plugin

  5. Google Security Guidelines — Рекомендации по безопасному хранению данных подписи и использованию v1/v2 подписи: https://developer.android.com/studio/publish/app-signing


Заключение

Создание подписанного APK файла для релиза с помощью Gradle требует правильной настройки signingConfigs и его привязки к buildTypes.release. Основные шаги:

  1. Добавьте signingConfigs с корректными путями к keystore и паролями
  2. Привяжите signingConfig signingConfigs.release к buildTypes.release
  3. Используйте команду ./gradlew assembleRelease для создания подписанного APK
  4. Храните пароли безопасно через gradle.properties или переменные окружения
  5. Настройте v1SigningEnabled и v2SigningEnabled для совместимости с разными версиями Android

Если сборка создает только unsigned APK, проверьте привязку signingConfig к release типу и корректность путей к keystore. Для CI/CD используйте безопасные методы передачи данных подписи через параметры командной строки или секреты.

Android Developers / Документационная платформа

В Gradle-сборке для подписанного APK необходимо задать signingConfigs и привязать его к buildTypes.release. В build.gradle добавьте:

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

После этого выполните ./gradlew assembleRelease (или gradlew build). В каталоге app/build/outputs/apk/release/ появится app-release.apk, который уже подписан и упакован zipalign. Если вы видите только -release-unsigned.apk, значит signingConfig не привязан к release-варианту либо путь к keystore неверный. Убедитесь, что файл keystore находится в указанном месте и что пароли корректны.

J

Easier way than previous answers:
Put this into ~/.gradle/gradle.properties
RELEASE_STORE_FILE={path to your keystore}
RELEASE_STORE_PASSWORD=*****
RELEASE_KEY_ALIAS=*****
RELEASE_KEY_PASSWORD=*****

Modify your app/build.gradle, and add this inside the android { code block:

signingConfigs {

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

// Optional, specify signing versions used
v1SigningEnabled true
v2SigningEnabled true
}
}

buildTypes {
release {
signingConfig signingConfigs.release
}
}

Then you can run gradle assembleRelease
Also see the reference for the signingConfigs Gradle DSL

I managed to solve it adding this code, and building with gradle build:
android {

signingConfigs {
release {
storeFile file(“release.keystore”)
storePassword “"
keyAlias "

keyPassword “******”
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
This generates a signed release apk file.

If you want to avoid hardcoding your keystore & password in build.gradle, you can use a properties file as explained here: HANDLING SIGNING CONFIGS WITH GRADLE
Basically:

  1. create a myproject.properties file at /home/[username]/.signing with such contents:
    keystore=[path to]\release.keystore
    keystore.password=*********
    keyAlias=***********
    keyPassword=********
  2. create a gradle.properties file (perhaps at the root of your project directory) with the contents:
    MyProject.properties=/home/[username]/.signing/myproject.properties
  3. refer to it in your build.gradle like this:
    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’]
}
}
}

If you have the keystore file already, it can be as simple as adding a few parameters to your build command:
./gradlew assembleRelease
-Pandroid.injected.signing.store.file=KEYFILE Pandroid.injected.signing.store.password=KEYFILE \ -Pandroid.injected.signing.store.password=STORE_PASSWORD
-Pandroid.injected.signing.key.alias=KEYALIAS Pandroid.injected.signing.key.password=KEY_ALIAS \ -Pandroid.injected.signing.key.password=KEY_PASSWORD
No permanent changes to your Android project necessary.

Stephan Petzl / Технический писатель

Для получения подписанного APK сначала убедитесь, что в gradle.properties заданы переменные RELEASE_STORE_FILE, RELEASE_STORE_PASSWORD, RELEASE_KEY_ALIAS и RELEASE_KEY_PASSWORD.

Затем в build.gradle добавьте блок signingConfigs с v1SigningEnabled true и v2SigningEnabled true, и в buildTypes подключите signingConfig signingConfigs.release. После этого выполните ./gradlew assembleRelease – он создаст подписанный APK в build/outputs/apk/release. Если в build/apk остаются только -release-unsigned.apk и -debug-unaligned.apk, значит сборка использует тип debug или не применяет signingConfig; проверьте, что buildTypes.release действительно ссылается на signingConfigs.release. Также убедитесь, что путь к keystore и пароли корректны – иначе Gradle создаст unsigned APK. При возникновении ошибок проверьте, что все переменные правильно экспортированы и что файл keystore доступен по указанному пути.

Процесс создания подписанного APK файла для релиза с помощью Gradle
Авторы
J
Разработчик
D
Эксперт Google по Android
J
Разработчик
I
Mobile Android Developer
N
Разработчик
J
Разработчик
G
Разработчик
W
Разработчик
Stephan Petzl / Технический писатель
Технический писатель
Источники
Android Developers / Документационная платформа
Документационная платформа
Stack Overflow / Q&A платформа
Q&A платформа
Repeato.app / Техническая документация
Техническая документация
Проверено модерацией
Модерация
Как создать подписанный APK файл для релиза с помощью Gradle