gradle을 사용하여 APK 파일 이름에서 versionName을 설정하는 방법은 무엇입니까?


169

gradle 자동 생성 APK 파일 이름에 특정 버전 번호를 설정하려고합니다.

이제 gradle이 생성 myapp-release.apk되지만 다음과 같이 보이기를 원합니다 myapp-release-1.0.apk.

지저분한 것 같은 이름 바꾸기 옵션을 시도했습니다. 이를 수행하는 간단한 방법이 있습니까?

buildTypes {
    release {
       signingConfig signingConfigs.release
       applicationVariants.each { variant ->
       def file = variant.outputFile
       variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" +    defaultConfig.versionName + ".apk"))
    }
}

나는 운이없이 위의 코드를 시도했습니다. 어떤 제안? (그라들 1.6 사용)

답변:


225

한 곳에서 버전 이름 만 변경하면됩니다. 코드도 간단합니다.

아래 예제는 선택한 빌드 변형에 따라 이름이 MyCompany-MyAppName-1.4.8-debug.apk 또는 MyCompany-MyAppName-1.4.8-release.apk 인 apk 파일을 만듭니다 .

이 솔루션 은 APK 및 앱 번들 (.aab 파일) 모두에서 작동 합니다 .

다음 사항도 참조 : Android 프로젝트 용 gradle에서 proguard 매핑 파일 이름을 변경하는 방법

최근 Gradle 플러그인 솔루션

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 13
        targetSdkVersion 21
        versionCode 14       // increment with every release
        versionName '1.4.8'   // change with every release
        setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName")
    }
}

위의 솔루션은 다음 Android Gradle 플러그인 버전에서 테스트되었습니다.

  • 3.5.2 (2019 년 11 월)
  • 3.3.0 (2019 년 1 월)
  • 3.1.0 (2018 년 3 월)
  • 3.0.1 (2017 년 11 월)
  • 3.0.0 (2017 년 10 월)
  • 2.3.2 (2017 년 5 월)
  • 2.3.1 (2017 년 4 월)
  • 2.3.0 (2017 년 2 월)
  • 2.2.3 (2016 년 12 월)
  • 2.2.2
  • 2.2.0 (2016 년 9 월)
  • 2.1.3 (2016 년 8 월)
  • 2.1.2
  • 2.0.0 (2016 년 4 월)
  • 1.5.0 (2015/11/12)
  • 1.4.0- 베타 6 (2015/10/05)
  • 1.3.1 (2015/08/11)

새 버전이 나오면이 게시물을 업데이트하겠습니다.

버전 1.1.3-1.3.0에서만 테스트 된 솔루션

다음 솔루션은 다음 Android Gradle 플러그인 버전에서 테스트되었습니다.

  • 1.3.0 (2015/07/30)- 작동하지 않음, 1.3.1에서 수정 될 예정인 버그
  • 1.2.3 (2015/07/21)
  • 1.2.2 (2015/04/28)
  • 1.2.1 (2015/04/27)
  • 1.2.0 (2015/04/26)
  • 1.2.0- 베타 1 (2015/03/25)
  • 1.1.3 (2015/03/06)

앱 gradle 파일 :

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 13
        targetSdkVersion 21
        versionCode 14       // increment with every release
        versionName '1.4.8'   // change with every release
        archivesBaseName = "MyCompany-MyAppName-$versionName"
    }
}

11
파일 이름을 바꾸는 다른 작업을 작성하는 대신 이것이 올바른 방법이라고 생각합니다.
Nandish A

5
당신이 강박증을 가지고 할 경우 "$ versionName을-MyAppName- MyCompany"는 +에 대해 경고 AS 원하지 archivesBaseName로 변경 =
ligi

4
찾기는 쉽지만 버전 코드가 다른 맛에는 적합하지 않습니다. 그들은 모두 동일한 버전 코드로 끝납니다.
weston

2
variant.buildType.name이름 을 추가 할 수 있는 방법이 있습니까? 나는이 관련되지 않은 정말 기본 설정을 알고,하지만 난 구식 제거하는 방법을 알아 내려고 노력하고있어 variantOutput.getAssemble()경고
앨런 W

2
apk name last '-debug'/ '-release'에서 제거 할 수 있습니까?
ilyamuromets

173

이건 내 문제를 해결 : 사용하는 applicationVariants.all대신applicationVariants.each

buildTypes {
      release {
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            def file = variant.outputFile
            variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk")) 
        }
    }       
}

최신 정보:

따라서 이것은 0.14 이상 버전의 Android 스튜디오 gradle 플러그인에서 작동하지 않는 것 같습니다.

이것은 트릭을 수행합니다 (이 질문의 참조 ) :

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(
                    output.outputFile.parent,
                    output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
        }
    }
}

3
gradle config 대신에 versionName정의 된 경우 작동시키는 방법을 알고 AndroidManifest.xml있습니까? myapp-release-null.apk지금 나 에게 준다 .
Iwo Banas

1
이 답변은 0.14+ 버전의 gradle 플러그인에서는 작동하지 않습니다. 그들과 함께 작동하는 업데이트?
Argyle

1
@withoutclass 나는 이것이 자체 질문으로 이것을 물었고 여기에 대답했다 : stackoverflow.com/questions/27068505/…
Argyle

2
사람들 Gradle을 4로 업데이트 : 변화 eachalloutput.outputFileoutputFileName. 누군가가 이것을 확인하면 다음과 같이 편집 할 수 있습니다 :)
PHPirate

6
@PHPirate : 거의 작동 :Error:(34, 0) Cannot set the value of read-only property 'name'
Mooing Duck

47

(Android Studio 3.0 및 Gradle 4에서 작동하도록 편집 됨)

더 복잡한 apk 파일 이름 변경 옵션을 찾고 있었고 다른 사람에게 도움이되기를 바랍니다. 다음 데이터로 apk의 이름을 바꿉니다.

  • 빌드 타입
  • 버전
  • 데이트

gradle 클래스에 대한 약간의 연구와 다른 답변의 약간의 복사 / 붙여 넣기가 필요했습니다. gradle 3.1.3을 사용 하고 있습니다.

build.gradle에서 :

android {

    ...

    buildTypes {
        release {
            minifyEnabled true
            ...
        }
        debug {
            minifyEnabled false
        }
    }

    productFlavors {
        prod {
            applicationId "com.feraguiba.myproject"
            versionCode 3
            versionName "1.2.0"
        }
        dev {
            applicationId "com.feraguiba.myproject.dev"
            versionCode 15
            versionName "1.3.6"
        }
    }

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def project = "myProject"
            def SEP = "_"
            def flavor = variant.productFlavors[0].name
            def buildType = variant.variantData.variantConfiguration.buildType.name
            def version = variant.versionName
            def date = new Date();
            def formattedDate = date.format('ddMMyy_HHmm')

            def newApkName = project + SEP + flavor + SEP + buildType + SEP + version + SEP + formattedDate + ".apk"

            outputFileName = new File(newApkName)
        }
    }
}

오늘 (13-10-2016) 10:47에 컴파일하면 선택한 플레이버 및 빌드 유형에 따라 다음 파일 이름이 표시됩니다.

  • dev 디버그 : myProject_ dev_debug_1.3.6 _131016_1047.apk
  • dev 출시 : myProject_ dev_release_1.3.6 _131016_1047.apk
  • prod 디버그 : myProject_ prod_debug_1.2.0 _131016_1047.apk
  • 제품 출시 : myProject_ prod_release_1.2.0 _131016_1047.apk

참고 : 정렬되지 않은 버전 apk 이름은 여전히 ​​기본 이름입니다.


훌륭한 솔루션. 나는 그것을 시도했고 내 문제에 완벽합니다. 감사!
Pabel

Xamarin Studio에서 동일한 접근 방식을 사용할 수 있습니까?
Alessandro Caliaro

가능하다면 좋을 것입니다. 그러나 지금 Xamarin 코스를 시작하고 있으며 가능 여부를 알기에는 아직 연습이 충분하지 않습니다. 나는이 질문을하고 다시 올 것이다.
Fer

강의 교사의 의견 : "생성 된 파일의 이름을 변경하기 위해 명령을 사용할 수있는 옵션이 있습니다". 따라서 Xamarin에서 사용하는 방법은 Android Studio 용으로 작성한 방법과 달라야합니다. 죄송합니다.
Fer

3
오류 해결하려면 읽기 전용 속성 '출력 _'의 값을 설정할 수 없습니다을 하는 것에 대해서 이전 코멘트에서 언급 한 바와 같이 - "변화 eachalloutput.outputFileoutputFileName" -이 게시물은 몇 가지 세부 사항을 제공 : stackoverflow.com/a/44265374/2162226를
Gene Bo

19

요약하면 build.gradle(나 같은) 패키지를 가져 오는 방법을 모르는 경우 다음을 사용하십시오 buildTypes.

buildTypes {
      release {
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            def file = variant.outputFile
            def manifestParser = new com.android.builder.core.DefaultManifestParser()
            variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile) + ".apk")) 
        }
    }       
}

===== 편집 =====

당신은 당신의 설정 한 경우 versionCodeversionName귀하의에서 build.gradle이 같은 파일 :

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 19
    versionCode 1
    versionName "1.0.0"
}

다음과 같이 설정해야합니다.

buildTypes {   
        release {
            signingConfig signingConfigs.releaseConfig
            applicationVariants.all { variant ->
                def file = variant.outputFile
                variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
            }
        }
}


====== Android Studio 1.0으로 편집 ======

Android Studio 1.0을 사용하는 경우 다음과 같은 오류가 발생합니다.

Error:(78, 0) Could not find property 'outputFile' on com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated@67e7625f.

build.Types부분을 ​​다음과 같이 변경해야 합니다.

buildTypes {
        release {
            signingConfig signingConfigs.releaseConfig
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
                }
            }
        }
    }

이것은 잘 작동합니다. 그러나 gradle 빌드에서 매니페스트 버전을 늘리기 때문에 이전 (증가 전) 값으로 APK를 만듭니다. gradle 스크립트가 버전 번호를 증가시킨 후에 이것이 적용되는지 확인하는 방법은 무엇입니까?
Guy

1
@Guy 미안 너무 오래 걸렸습니다. 답변을 편집하여 문제를 해결할 수 있는지 확인하십시오.
웨슬리

17

당신이 defaultConfig 블록에 versionName을 지정하지 않는 경우 defaultConfig.versionName에 발생합니다null

매니페스트에서 versionName을 얻으려면 build.gradle에 다음 코드를 작성할 수 있습니다.

import com.android.builder.DefaultManifestParser

def manifestParser = new DefaultManifestParser()
println manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)

7
나는 최신 버전의 gradle을 사용하면 com.android.builder.core.DefaultManifestParser
Ryan S

8

제 경우에는 다른 apk이름 releasedebug변형 을 자동으로 생성하는 방법을 찾고 싶었습니다 . 이 스 니펫을 다음과 같은 자식으로 사용하여 쉽게 수행 할 수 있습니다 android.

applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def appName = "My_nice_name_"
        def buildType = variant.variantData.variantConfiguration.buildType.name
        def newName
        if (buildType == 'debug'){
            newName = "${appName}${defaultConfig.versionName}_dbg.apk"
        } else {
            newName = "${appName}${defaultConfig.versionName}_prd.apk"
        }
        output.outputFile = new File(output.outputFile.parent, newName)
    }
}

새로운 Android gradle plugin 3.0.0의 경우 다음과 같이 할 수 있습니다.

 applicationVariants.all { variant ->
    variant.outputs.all {
        def appName = "My_nice_name_"
        def buildType = variant.variantData.variantConfiguration.buildType.name
        def newName
        if (buildType == 'debug'){
            newName = "${appName}${defaultConfig.versionName}_dbg.apk"
        } else {
            newName = "${appName}${defaultConfig.versionName}_prd.apk"
        }
        outputFileName = newName
    }
}

이것은 다음과 같은 것을 생성합니다 : My_nice_name_3.2.31_dbg.apk


6

다른 대안은 다음을 사용하는 것입니다.

String APK_NAME = "appname"
int VERSION_CODE = 1
String VERSION_NAME = "1.0.0"

project.archivesBaseName = APK_NAME + "-" + VERSION_NAME;

    android {
      compileSdkVersion 21
      buildToolsVersion "21.1.1"

      defaultConfig {
        applicationId "com.myapp"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode VERSION_CODE
        versionName VERSION_NAME
      }

       .... // Rest of your config
}

"appname-1.0.0"이 모든 APK 출력으로 설정됩니다.


죄송합니다. 더 이상 작동하지 않습니다. No such property: archivesBaseName for class: org.gradle.api.internal.project.DefaultProject_Decorated
Martin

어떤 gradle 버전을 사용하고 있습니까?
Marco RS

6

그레들 6+

Android Studio 4.0 및 Gradle 6.4에서 다음을 사용하고 있습니다.

android {
    defaultConfig {
        applicationId "com.mycompany.myapplication"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 15
        versionName "2.1.1"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "ApplicationName-${variant.name}-${variant.versionName}.apk"
                }
            }
        }
    }
}

그레들 4

구문에서 Gradle을 4 (안드로이드 스튜디오 3 이상) (에 약간의 변경 output.outputFileoutputFileName,에서 생각 이 대답은 지금이다 :

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def newName = outputFileName
            newName.replace(".apk", "-${variant.versionName}.apk")
            outputFileName = new File(newName)
        }
    }
}

gradle 6 에서이 문제를 해결하는 방법에 대한 아이디어가 있습니까?
spartygw

@spartygw 답변 업데이트
PHPirate

5

@Jon 답변에 따라 APK의 이름을 바꾸는 올바른 방법

defaultConfig {
        applicationId "com.irisvision.patientapp"
        minSdkVersion 24
        targetSdkVersion 22
        versionCode 2  // increment with every release
        versionName "0.2" // change with every release
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        //add this line
        archivesBaseName = "AppName-${versionName}-${new Date().format('yyMMdd')}"
    }   

또는 다른 방법으로 동일한 결과를 얻을 수 있습니다

android {
    ...

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def formattedDate = new Date().format('yyMMdd')
            outputFileName = "${outputFileName.replace(".apk","")}-v${defaultConfig.versionCode}-${formattedDate}.apk"
        }
    }
}

이것에 좋은 하나! 나는 이것을 현재보다 잘하고 다른 방법을 좋아한다.
드로이드 크리스

3

전체 또는 일부 수정 후에 올바른 답변이 많이 있습니다. 그러나 스크립트를 사용하여 preBuild작업 에 연결하여 VersionName 및 VersionCode를 동적으로 생성하기 때문에 모두 문제가 발생했기 때문에 어쨌든 광산을 추가 할 것입니다 .

비슷한 접근 방식을 사용하는 경우 다음 코드가 작동합니다.

project.android.applicationVariants.all { variant ->
    variant.preBuild.doLast {
    variant.outputs.each { output ->
        output.outputFile = new File(
                output.outputFile.parent,
                output.outputFile.name.replace(".apk", "-${variant.versionName}@${variant.versionCode}.apk"))
        }
    }
}

설명 : 첫 번째 작업에서 버전 코드와 이름을 재정의 하므로이 preBuild작업 끝에 파일 이름을 바꾸어야합니다. 따라서이 경우 gradle이 수행하는 작업은 다음과 같습니다.

버전 코드 삽입 / 이름-> 사전 빌드 작업 수행-> APK의 이름 바꾸기


생성 된 versionCode 및 versionName 변수를 어디에 설정합니까?
Mars

내가 기억하는 것처럼 사용자 정의 gradle 플러그인 내부에서 수행되었습니다. 사전 빌드 태스크의 마지막 조치로 실행이 호출되었습니다.
Igor Čordaš

2
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
        }
    }

이 코드 스 니펫은 문제를 해결할 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 실제로 도움이됩니다. 앞으로 독자들에게 질문에 대한 답변을 제공하므로 해당 사람들이 코드 제안의 이유를 모를 수도 있습니다.
Rosário Pereira Fernandes

1

내 경우에는이 방법 으로이 오류를 해결합니다.

디버그 버전에 SUFFIX 추가,이 경우 "-DEBUG"텍스트를 디버그 배포에 추가

 buildTypes {
        release {

            signingConfig signingConfigs.release
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'


        }
        debug {

            defaultConfig {
                debuggable true

                versionNameSuffix "-DEBUG"
            }
        }
    }

APK 파일 이름은 변경되지 않습니다.
Tom

1
이것은 실제로 좋은 팁입니다. 올바른 질문은 아니지만 좋은 질문입니다. 그것에 대해 더 읽을 수있는 곳은 어디입니까? versionNameSuffixGIT 브랜치를 기반으로 사용할 수 있습니까? 예를 들어, 그것은 "마스터"에이 아니라면, 항상하더라도, 릴리스 버전 접미사가
안드로이드 개발자

0

최신 gradle 버전의 경우 다음 스 니펫을 사용할 수 있습니다.

응용 프로그램 매니페스트 위치를 먼저 설정

 sourceSets {
        main {
            manifest.srcFile 'src/main/AndroidManifest.xml'
        {
    }

그리고 나중에 build.gradle에서

import com.android.builder.core.DefaultManifestParser

def getVersionName(manifestFile) {
    def manifestParser = new DefaultManifestParser();
    return manifestParser.getVersionName(manifestFile);
}

def manifestFile = file(android.sourceSets.main.manifest.srcFile);
def version = getVersionName(manifestFile)

buildTypes {
    release {
       signingConfig signingConfigs.release
       applicationVariants.each { variant ->
       def file = variant.outputFile
       variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" +    versionName + ".apk"))
    }
}

빌드 유형마다 매니페스트가 다른 경우 조정하십시오. 그러나 나는 하나를 가지고 있기 때문에-나에게 완벽하게 작동합니다.


클래스 파일에서 apk name으로 문자열을 추가 할 수 있습니까 ??
Upendra Shah

0

Android Studio 1.1.0 부터이 조합 은 파일 의 Android 본문 에서 작동했습니다 build.gradle. 매니페스트 XML 파일 데이터를 가져 오는 방법을 알 수없는 경우입니다. Android Studio에서 더 많이 지원되기를 원하지만 원하는 apk 이름 출력을 얻을 때까지 값을 가지고 놀아보십시오.

defaultConfig {
        applicationId "com.package.name"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 6
        versionName "2"
    }
    signingConfigs {
        release {
            keyAlias = "your key name"
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            signingConfig signingConfigs.release
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace("app-release.apk", "appName_" + versionName + ".apk"))
                }
            }
        }
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.