Как создать подписанный APK файл для релиза с помощью Gradle
Пошаговое руководство по созданию подписанного APK файла для релиза с помощью Gradle. Решение проблем с unsigned APK и настройка signingConfigs.
Как создать подписанный APK файл для релиза с помощью Gradle?
Я хочу, чтобы мой Gradle-сборка создавала подписанный APK файл для релиза. Не уверен, что код написан правильно или что я пропускаю какой-то параметр при выполнении команды gradle build?
Вот часть кода из моего файла build.gradle/build.gradle.kts:
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
- Команды Gradle для сборки подписанного APK (assembleRelease vs build)
- Хранение данных подписи в безопасности (gradle.properties)
- Распространенные проблемы и решения при создании подписанного APK
- Современные параметры подписи APK (v1SigningEnabled и v2SigningEnabled)
- Альтернативные методы передачи данных подписи для CI/CD
Настройка signingConfigs в build.gradle для создания подписанного APK
Основная проблема, с которой вы сталкиваетесь, заключается в том, что вы настроили signingConfigs, но не привязали его к buildTypes.release. В Gradle для Android это необходимо сделать явным образом.
Вот как должен выглядеть ваш build.gradle файл:
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. Есть несколько вариантов:
Основные команды:
./gradlew assembleRelease- создает только подписанный APK для релиза./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 используется для каждого типа сборки:
./gradlew app:buildTypes
Эта команда покажет информацию о всех типах сборки, включая используемые signingConfigs.
Хранение данных подписи в безопасности (gradle.properties)
Хранить пароли прямо в build.gradle - плохая практика. Вот безопасные способы:
Метод 1: gradle.properties
Создайте файл gradle.properties в корне проекта или в ~/.gradle/gradle.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 используйте эти переменные:
android {
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
}
Метод 2: Загрузка из внешнего файла
Для дополнительной безопасности можно использовать отдельный файл свойств:
// В 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 систем используйте переменные окружения:
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 не подписан
Решение:
// Проверьте путь к 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”
Решение:
// Просмотрите содержимое 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
Решение:
// Используйте двойные обратные слэши на 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:
dependencies {
classpath 'com.android.tools.build:gradle:8.1.0'
}
Современные параметры подписи APK (v1SigningEnabled и v2SigningEnabled)
В современных версиях Android Gradle Plugin появились новые параметры управления подписью APK:
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:
// Проверьте 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: Параметры командной строки
Выполните сборку с передачей данных через параметры:
./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)
Для облачных платформ:
// Пример для 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:
# На локальной машине
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:
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:
// 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
Источники
-
Android Developers Documentation — Официальное руководство по настройке подписи APK с помощью Gradle: https://minimum-viable-product.github.io/marshmallow-docs/tools/building/building-cmdline.html
-
Stack Overflow Community Solutions — Комплексное руководство по созданию подписанного APK с различными методами хранения данных подписи: https://stackoverflow.com/questions/18328730/how-to-create-a-release-signed-apk-file-using-gradle
-
Repeato Technical Guide — Практические советы по устранению проблем при создании подписанного APK и настройке современных параметров подписи: https://www.repeato.app/creating-a-release-signed-apk-file-using-gradle/
-
Android Gradle Plugin Reference — Документация по signingConfigs DSL и современным параметрам подписи APK: https://developer.android.com/studio/build/build-gradle-plugin
-
Google Security Guidelines — Рекомендации по безопасному хранению данных подписи и использованию v1/v2 подписи: https://developer.android.com/studio/publish/app-signing
Заключение
Создание подписанного APK файла для релиза с помощью Gradle требует правильной настройки signingConfigs и его привязки к buildTypes.release. Основные шаги:
- Добавьте signingConfigs с корректными путями к keystore и паролями
- Привяжите signingConfig signingConfigs.release к buildTypes.release
- Используйте команду ./gradlew assembleRelease для создания подписанного APK
- Храните пароли безопасно через gradle.properties или переменные окружения
- Настройте v1SigningEnabled и v2SigningEnabled для совместимости с разными версиями Android
Если сборка создает только unsigned APK, проверьте привязку signingConfig к release типу и корректность путей к keystore. Для CI/CD используйте безопасные методы передачи данных подписи через параметры командной строки или секреты.

В 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 находится в указанном месте и что пароли корректны.
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:
- create a myproject.properties file at /home/[username]/.signing with such contents:
keystore=[path to]\release.keystore
keystore.password=*********
keyAlias=***********
keyPassword=******** - create a gradle.properties file (perhaps at the root of your project directory) with the contents:
MyProject.properties=/home/[username]/.signing/myproject.properties - 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=STORE_PASSWORD
-Pandroid.injected.signing.key.alias=KEY_PASSWORD
No permanent changes to your Android project necessary.
Для получения подписанного 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 доступен по указанному пути.


