Làm cách nào để tạo một tệp apk đã ký phát hành bằng Gradle?


514

Tôi muốn có bản dựng Gradle của mình để tạo tệp apk có chữ ký phát hành bằng Gradle.

Tôi không chắc liệu mã có đúng hay không nếu tôi thiếu một tham số khi thực hiện gradle build?

Đây là một số mã trong tập tin lớp của tôi:

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

Việc xây dựng lớp hoàn thành THÀNH CÔNG, và trong build/apkthư mục của tôi, tôi chỉ thấy các tệp ...-release-unsigned.apk...-debug-unaligned.apk.

Bất kỳ đề xuất về cách giải quyết này?



ký với phiên bản v1 (chữ ký jar) hoặc v2 (chữ ký apk đầy đủ) từ tệp lớp? giải pháp tại đây: stackoverflow.com/questions/57943259/ từ
user1506104

Câu trả lời:


430

Cách dễ dàng hơn các câu trả lời trước:

Đặt cái này vào ~/.gradle/gradle.properties

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

Sửa đổi của bạn app/build.gradlevà thêm phần này vào bên trong android {khối mã:

...    
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
        }
}
....

Sau đó bạn có thể chạy gradle assembleRelease


Đồng thời xem tài liệu tham khảo cho signingConfigsDSL cấp độ


12
Phương pháp tốt nhất nếu bạn hỏi tôi. Không lưu gì trong thư mục dự án của tôi / SVN và tôi có thể kiểm tra 10 phiên bản dự án của mình mà không phải lo lắng về các khóa.
Frank

8
Nếu bạn đang sử dụng gradlew trên Windows, bạn cần chắc chắn GRADLE_USER_HOME được xác định là biến môi trường để thực hiện công việc này. Tôi đặt nó vào một thư mục phía trên thư mục dự án của tôi và đặt kho khóa của tôi ở đó. Đường dẫn đến kho lưu trữ khóa của bạn trong gradle.properies nên sử dụng dấu gạch chéo (/) hoặc dấu gạch chéo ngược kép (\\), chứ không phải dấu gạch chéo đơn của Windows. Để tạo kho khóa từ dấu nhắc lệnh của Windows, hãy xem stackoverflow.com/questions/3997748/how-can-i-create-a-keystore
Anachronist

3
Đường dẫn có liên quan đến vị trí của tệp build.gradle hoặc liên quan đến thư mục gốc của máy không?
Prem

1
@Prem, file()luôn giả sử các đường dẫn tương đối. Sử dụng new File(path)nếu bạn muốn nó được coi là tuyệt đối.
ars-longa-vita-brevis

4
Điều này làm việc cho tôi và đơn giản nhất. Trong gradle.properies, chỉ định storeFile liên quan đến bản dựng mô-đun của bạn. Nâng cấp như vậy RELEASE_STORE_FILE = .. / mykeystore. Đừng thêm trích dẫn khác xếp hạng đường dẫn
Lakshman Chilukuri

263

Tôi quản lý để giải quyết nó bằng cách thêm mã này và xây dựng với gradle build:

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

Điều này tạo ra một tập tin apk phát hành đã ký.


33
Có cách nào để làm cho nó nhắc tôi mật khẩu không? Hoặc các đề xuất khác để giữ mật khẩu ra khỏi repos git của tôi?
dùng672009

3
Tôi chỉnh sửa build.gradle của mình để trông giống như của bạn nhưng chạy "Được xây dựng> Tạo APK đã ký ..." vẫn cho hộp thoại đó của tôi ("Xem Hướng dẫn sử dụng Gradle để biết thêm thông tin." V.v.) và không có APK.
Semanticer

3
@Semanticer Thực thi gradle buildhoặc gradlew buildtrong lệnh Terminal / Prompt
Phillip Kamikaze

12
@ user672009 bạn có thể đặt mật khẩu vào tệp thuộc tính và loại trừ nó khỏi repos với .gitignore. Bạn có thể thấy liên kết này. gist.github.com/gabrielemariotti/6856974
Gabriele Mariotti

1
@GabrieleMariotti Điều đó vẫn để lại một kho lưu trữ không đầy đủ. Một cách tốt hơn sẽ là tạo một bộ xương ký kết.properies và sau khi cam kết phát hành "git update-index --assume-không thay đổi Sign.properies". Tuy nhiên, điều đó ngăn cản các chỉnh sửa Futura được cam kết. Một cái gì đó giống như tùy chọn đầu tiên mà sdqali gợi ý có vẻ tốt hơn nữa.
dùng672009

67

Lưu ý rằng tập lệnh của @ sdqali sẽ (ít nhất là khi sử dụng Lớp 1.6) yêu cầu mật khẩu bất cứ khi nào bạn gọi bất kỳ tác vụ lớp nào . Vì bạn chỉ cần nó khi thực hiện gradle assembleRelease(hoặc tương tự), bạn có thể sử dụng mẹo sau:

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"
    }
}

Lưu ý rằng tôi cũng phải thêm các mục sau (trong Android) để làm cho nó hoạt động:

buildTypes {
    release {
        signingConfig signingConfigs.release
    }
}

Sau khi thực hiện điều này, installReleasebiến mất khỏi danh sách các nhiệm vụ ... Tại sao?
Kaarel

1
@caspase Ước gì tôi đã nhận xét của bạn về "storePassword" giả mạo và "keyPassword" đó một cách nghiêm túc hơn. Nếu không khởi tạo các thuộc tính này ("" chẳng hạn), * -release.apk đã ký không được tạo, không có lỗi nào được hiển thị và bạn hoàn toàn bối rối chỉ với * -release-unsign.apk trong thư mục PRO DỰ_NAME / build / apk / của bạn . Người đàn ông ...: /
vizZ

Cảm ơn bạn đã lưu ý về việc thêm SignConfig trong buildTypes -> Phát hành. Điều đó đã giải quyết việc ký tự động cho tôi!
mm2001

1
Tôi đã tạo một plugin cấp độ đơn giản yêu cầu mật khẩu khi xây dựng apk phát hành (sử dụng mathod được mô tả trong bài đăng này, nhưng bạn sẽ không cần xác định storePassword & keyPassword giả). Nó cũng có sẵn trong trung tâm maven. github.com/alexvasilkov/AndroidGradleSignPlugin
Alex Vasilkov

Điều đó thật tuyệt. Lưu ý rằng biến môi trường KEYSTOREcần được xác định ngay cả đối với các bản dựng gỡ lỗi và "đồng bộ hóa lớp" trong Android Studio, nếu không, nó sẽ báo lỗi về đường dẫn là null.
Jerry101

63

Nếu bạn muốn tránh mã hóa kho lưu trữ khóa và mật khẩu của mình trong build.gradle , bạn có thể sử dụng tệp thuộc tính như được giải thích ở đây: XỬ LÝ NHỮNG CONFIGS VỚI LỚP

Về cơ bản:

1) tạo tệp myproject.properIES tại /home/[username[/.signing với những nội dung như vậy:

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

2) tạo tệp gradle.properIES (có lẽ ở thư mục gốc của thư mục dự án của bạn) với nội dung:

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

3) tham khảo nó trong build.gradle của bạn như thế này:

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

1
Hoạt động tuyệt vời! Cảm ơn bạn. Mã này phải được thêm vào trước phần buildTypes {} và phần này phải khai báo SignConfig SignConfigs.release như bình thường.
báo

Cuối cùng tôi tìm thấy một giải pháp cho vấn đề này. Điều duy nhất thực sự giúp tôi ra ngoài! Đây có thể là câu trả lời được chấp nhận ...
devnull69

39

Tự động đăng ký ứng dụng với Gradle khi sử dụng git

Thật đáng ngạc nhiên khi có nhiều cách phức tạp để làm điều này. Đây là cách riêng của tôi, nơi tôi cố gắng tuân thủ khuyến nghị của chính Google . Tuy nhiên, lời giải thích của họ không hoàn toàn rõ ràng, vì vậy tôi sẽ mô tả chi tiết quy trình cho Linux.


Sự miêu tả:

Các hướng dẫn mặc định của Google để tự động ký một ứng dụng trong quá trình xây dựng, mà không giữ mật khẩu và tệp chữ ký trong đường dẫn phát triển ứng dụng (GIT) của bạn, khá mơ hồ. Dưới đây là các hướng dẫn từng bước được làm rõ làm thế nào để làm như vậy.

Giả định ban đầu:

Bạn có một ứng dụng có tên "MyApp" trong một thư mục được cung cấp bởi đường dẫn sau : $HOME/projects/mydev/MyApp. Tuy nhiên, thư mục MyApp được sử dụng và kiểm soát bằng GIT.

nhập mô tả hình ảnh ở đây

Vấn đề

Rõ ràng là chúng tôi không muốn có các tệp chữ ký hoặc mật khẩu của mình ở bất kỳ đâu trong thư mục được kiểm soát GIT, ngay cả khi chúng tôi rất có thể sử dụng .gitignore, v.v., nó vẫn quá rủi ro và dễ mắc lỗi. Vì vậy, chúng tôi muốn kho lưu trữ khóa và chữ ký của chúng tôi bên ngoài.

Giải pháp

Chúng ta cần làm ba (3) việc:

  1. Tạo một tệp mật khẩu được Android Studio sử dụng
  2. Tạo tập tin khóa chữ ký
  3. Chỉnh sửa build.gradletệp mô-đun để sử dụng (1) và (2).

Trong ví dụ này, chúng tôi đặt tên cho hai tệp:

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

Chúng tôi có thể đặt cả hai tệp này ở đây:

cd $HOME/projects/mydev/

(1) Tạo tập tin mật khẩu kho khóa

Tệp đầu tiên chứa mật khẩu văn bản rõ ràng được sử dụng trong; và đường dẫn đến tệp khóa phát hành trong (2). Bắt đầu với việc điền này, vì nó sẽ làm cho thao tác sao chép dễ dàng hơn cho bước tiếp theo.

cd $HOME/projects/mydev/

Chỉnh sửa keystore.propertiessao cho nội dung của nó là:

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

Phần khó khăn duy nhất ở đây, là myStoreFileLocation. Đây là đường dẫn như nhìn thấy từbuild.gradle tệp mô-đun trong quá trình xây dựng. Điều này thường có nghĩa là một đường dẫn tương tự và liên quan đến : $HOME/projects/mydev/MyApp/app/build.gradle. Vì vậy, để trỏ đến MyApp-release-key.jks tệp, những gì chúng ta cần đặt ở đây là:

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

Ở đây, chúng tôi cũng chọn bí danh "myapp" cho khóa. Sau đó, tập tin cuối cùng sẽ xem:

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

(2) Tạo tập tin chữ ký

Tệp thứ hai được tạo tự động khi bạn tạo khóa chữ ký. Nếu bạn không có ứng dụng nào khác và đây là kho khóa duy nhất của bạn, thì hãy tạo tệp bằng:

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

Điều này sẽ yêu cầu bạn cho hai mật khẩu và một loạt thông tin. (Tương tự như trong Android Studio.) Bây giờ sao chép / dán mật khẩu đã chọn trước đó của bạn.

(3) Chỉnh sửa gradle.buildtập tin mô-đun của bạn để sử dụng ở trên

Các phần sau đây cần phải có trong tệp bản dựng Gradle của ứng dụng / mô-đun của bạn. Đầu tiên, thêm các dòng sau bên ngoàitrướcandroid {} khối của bạn .

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

Sau đó, bên trong các android {}khối, thêm:

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
            ...
        }
    }
}

Bây giờ từ shell, bạn có thể xây dựng lại ứng dụng của mình với:

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

Điều này sẽ tạo ra một ứng dụng được ký hợp lệ có thể được sử dụng trong Google Play.


CẬP NHẬT: 2019-04-02

Các phiên bản gần đây hơn keytoolmột cái gì đó đang nói với bạn rằng bạn nên sử dụng một keyfile dựa trên PKCS12 thay vì bản gốc / mặc định như tôi sử dụng ở trên. Sau đó họ tiếp tục nói với bạn rằng bạn nên chuyển đổi sang định dạng PKCS12 mở mới. Tuy nhiên, dường như các công cụ phát triển Android chưa hoàn toàn sẵn sàng cho việc này, bởi vì nếu bạn làm vậy, bạn sẽ gặp phải các lỗi kỳ lạ sau:

com.android.ide.common.signing.KeytoolException:Không thể đọc khóa XXX từ cửa hàng "F: \ XXX \ XXX.jks": Nhận khóa không thành công: Cho khối cuối cùng không được đệm đúng cách. Những vấn đề như vậy có thể phát sinh nếu một khóa xấu được sử dụng trong quá trình giải mã.

Vì vậy, đừng sử dụng khóa được chuyển đổi!


Là SignConfigs được lưu bên trong apk và sau đó nó có thể được dịch ngược bởi bất kỳ người dùng nào để lấy mật khẩu hoặc nó không xuất hiện trong apk?
JavierSegoviaCordoba

2
Hoạt động như quyến rũ. Cảm ơn bạn nên đây là câu trả lời được chấp nhận
pratham kesarkar

Điều gì nếu bạn chỉ muốn kho khóa và mật khẩu trên một máy chủ xây dựng? Với giải pháp trên, mọi nhà phát triển trong nhóm cần phải có kho khóa trên máy cục bộ của họ. Nếu không, đồng bộ hóa dự án Gradle sẽ thất bại: keystore.properIES (Không có tệp hoặc thư mục như vậy).
Diana Farin

1
Bạn có thể cam kết một keystore.propertiestệp giả để kiểm soát nguồn, vì vậy các bản dựng hoạt động trên các máy dev. Tôi đã mô tả một thiết lập máy chủ xây dựng ở đây .
dskrvk

1
Lưu ý về cập nhật cuối cùng của bạn về keytoolviệc tạo ra một keystore pkcs12: bạn có thể vượt qua -storetype JKStrong keytoollệnh để thiết lập kiểu keystore để JKS đó là cần thiết bởi các dụng cụ Android.
Trevor Halvorson

35

Giống như @Destil đã nói nhưng cho phép những người khác không có chìa khóa để xây dựng: Cách dễ dàng hơn các câu trả lời trước:

Đặt cái này vào ~/.gradle/gradle.properties

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

Sửa đổi của bạn build.gradlenhư thế này:

...    
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
        }
    }
}
....

Sau đó, bạn có thể chạy gradle assembleRelease HOẶC gradle build


Cách đặt đường dẫn trong windows: đường dẫn đến kho khóa của bạn
reza_khalafi

storeFile file ("C: \\ Users \\ xxxx \\ Documents \\ yyyy \\ mykey.jks") có đúng không?
reza_khalafi

28

(Trả lời người dùng672009 ở trên.)

Một giải pháp thậm chí còn dễ dàng hơn, nếu bạn muốn giữ mật khẩu của mình khỏi kho lưu trữ git; Tuy nhiên, muốn bao gồm build.gradle của bạn trong đó, thậm chí hoạt động tuyệt vời với hương vị sản phẩm, là tạo một tệp lớp riêng biệt. Hãy gọi nó là 'Sign.gradle' (bao gồm nó trong .gitignore của bạn). Giống như là tệp build.gradle của bạn trừ đi mọi thứ không liên quan đến việc đăng nhập.

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

Sau đó, trong tệp build.gradle của bạn bao gồm dòng này ngay bên dưới "áp dụng plugin: 'android'"

 apply from: 'signing.gradle'

Nếu bạn không có hoặc sử dụng nhiều hương vị, hãy đổi tên "hương vị1" thành "phát hành" ở trên và bạn sẽ hoàn thành. Nếu bạn đang sử dụng hương vị tiếp tục.

Cuối cùng, liên kết các hương vị của bạn với SignConfig chính xác trong tệp build.gradle của bạn và bạn sẽ hoàn tất.

  ...

  productFlavors {

      flavor1 {
          ...
          signingConfig signingConfigs.flavor1
      }

      flavor2 {
          ...
          signingConfig signingConfigs.flavor2
      }
  }

  ...

Bạn có thể cụ thể hơn một chút Tôi không thể làm cho nó chạy: "không thể giải quyết ký hiệu SignConfig".
Amio.io

Nếu tôi bao gồm 'Sign.gradle' trong build.gradle - Tôi buộc phải có một kho lưu trữ trong git (nếu không tôi sẽ gặp lỗi 'Sign.gradle không tồn tại'). Và nếu tôi đặt 'Sign.gradle' trong git, nó sẽ đánh bại mục đích. Làm cách nào tôi có thể đưa vào Sign.gradle tùy chọn?
Jaguar

21

Nếu bạn đã có tệp kho khóa, việc này có thể đơn giản như thêm một vài tham số vào lệnh xây dựng của bạn:

./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

Không có thay đổi vĩnh viễn cho dự án Android của bạn cần thiết.

Nguồn: http://www.tinmith.net/wayne/blog/2014/08/gradle-sign-command-line.htmlm


18

Đây là câu trả lời cho user672009 và thêm vào bài đăng của sdqali (mã của anh ấy sẽ bị lỗi khi xây dựng phiên bản gỡ lỗi bằng nút "Run" của IDE):

Bạn có thể sử dụng mã sau đây:

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 {

        }
    }

}

Có cách nào để có một số giá trị mặc định? Kho khóa của tôi thường giống nhau. StorePassword thường giống như keyPassword và keyAlias ​​thường là tên dự án bằng chữ thường.
dùng672009

@ user672009 bạn luôn có thể sử dụng mã Java bên trong tập lệnh.
AChep

1
bạn có thể muốn sử dụng một cái gì đó như thế này: keyPassword new String(console.readPassword("Enter key password: "))để đảm bảo mật khẩu của bạn không được hiển thị trong khi nhập
Alex Semeniuk

Điều này không còn hoạt động nữa, xem github.com/gradle/gradle/issues/1251
SqAR.org

16

Trong Android Studio mới hơn, có một cách GUI rất dễ dàng và nó cũng điền vào tệp Gradle.

  1. File -> Project Structure

  2. Module -> Chọn mô-đun chính ('ứng dụng' hoặc tên tùy chỉnh khác)

  3. Signing tab -> Plus hình ảnh để thêm cấu hình mới

  4. Điền dữ liệu vào bên phải

  5. OK và tập tin Gradle được tạo tự động

  6. Bạn sẽ phải tự thêm một dòng signingConfig signingConfigs.NameOfYourConfigbên trongbuiltTypes{release{}}

Hình ảnh:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Hai lưu ý quan trọng (!):

(EDIT 12/15)

  1. Để tạo APK đã ký, bạn phải mở tab Terminal của Android Studio (phía dưới giao diện chính) và ra lệnh ./gradlew assembleRelease

  2. Nếu bạn quên keyAlias(điều thường xảy ra với tôi), bạn sẽ phải bắt đầu Build -> Generate Signed APKđể bắt đầu quá trình và xem tên của khóa Bí danh.


2
Điều này mã hóa mật khẩu của bạn vào build.gradletập tin, mặc dù, phải không?
Joshua Pinter

16

Nếu bạn xây dựng apk thông qua dòng lệnh như tôi thì bạn có thể cung cấp cấu hình ký làm đối số.

Thêm cái này vào 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
}

Làm signingConfigsnhư thế này

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

Sau đó, bạn thực hiện gradlewnhư thế này

./gradlew assembleRelease -PstoreFile="keystore.jks" -PstorePassword="password" -PkeyAlias="alias" -PkeyPassword="password"

Đó là build.gradlecái gì Cấp cao nhất? Vui lòng thêm mã
Vlad

Để làm rõ, đây là app/build.gradletập tin tôi đang nói về.
Egis

11
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
        }
    }
}

Sử dụng Android Studio 0.5.1, Gradle 1.11 và plugin Gradle 0.9.
JP Ventura

1
Tạo các thuộc tính theo yêu cầu (còn gọi là thuộc tính động) đã không được chấp nhận và dự kiến ​​sẽ bị xóa trong Lớp 2.0
JP Ventura

10

Bạn cũng có thể sử dụng tùy chọn dòng lệnh -P của lớp để giúp ký. Trong build.gradle của bạn, hãy thêm singConfigs như thế này:

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

Sau đó gọi gradle build như thế này:

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

Bạn có thể sử dụng -P để đặt storeFile và keyAlias ​​nếu bạn thích.

Về cơ bản, đây là giải pháp của Destil nhưng với các tùy chọn dòng lệnh.

Để biết thêm chi tiết về các thuộc tính lớp, kiểm tra hướng dẫn sử dụng lớp .


7

Câu trả lời của @ Destil là tốt nếu bạn có thể sử dụng lại cấu hình tương tự trên tất cả các dự án. Ngoài ra, Android Studio đi kèm với mộtlocal.properties tệp có thể được sử dụng thay thế, nhưng được cho là do IDE tạo và tôi không thể tìm cách mở rộng tệp từ trong Android Studio.

Đây là một biến thể của câu trả lời của @ jonbo . Câu trả lời đó cho phép các cài đặt cụ thể của dự án nhưng nó đi kèm với một chút chi phí phát triển. Cụ thể, bản tóm tắt quan trọng được yêu cầu để chuyển signingConfigsđịnh nghĩa thành một tệp riêng - đặc biệt nếu bạn cần làm như vậy cho nhiều dự án, đó là lý do chính để chọn giải pháp này trên Destil. Điều này có thể phần nào giảm bớt bằng cách cũng bao gồm các dòng

apply plugin: 'com.android.application'

trong tệp thông tin đăng nhập, vì điều này sẽ cho phép hoàn thành IDE.

Cuối cùng, hầu hết các giải pháp ở đây không cho phép xây dựng dự án ở chế độ gỡ lỗi - tự động xử lý ký gỡ lỗi - mà không cung cấp cú pháp nếu không hợp lệ về mặt ngữ nghĩasigningConfigs định nghĩa nghĩa. Nếu bạn không cần tạo bản dựng phát hành từ một máy nhất định, bước bổ sung này có thể được xem là một trở ngại không cần thiết. Mặt khác, nó có thể là một trợ giúp chống lại các đồng nghiệp dốt nát hoặc lười biếng chạy các bản dựng gỡ lỗi trong sản xuất.

Giải pháp này sẽ cho phép các bản dựng gỡ lỗi mà không phải lo lắng về thông tin xác thực, nhưng nó sẽ yêu cầu thông tin xác thực hợp lệ để tạo bản dựng phát hành và phải mất rất ít bản tóm tắt. Tuy nhiên, vì nhược điểm, nó có thể khuyến khích người khác thay thế các giá trị giả bằng thông tin xác thực và không có cách nào để bảo vệ chống lại điều đó.

// 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
            ...
        }
    }
}

Điều này tạo ra một thuộc tính giả phục vụ hoàn toàn để tạo ra tệp xây dựng có giá trị cú pháp. Các giá trị được gán cho ext.signingcác thuộc tính không liên quan đến các bản dựng gỡ lỗi. Để cho phép xây dựng bản phát hành, sao chép ext.signingvào signing.gradlevà thay thế các giá trị giả bằng thông tin xác thực hợp lệ.

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

Tất nhiên, signing.gradlenên bỏ qua bởi VCS.


6

Hầu như tất cả các nền tảng hiện cung cấp một số loại khóa, vì vậy không có lý do gì để để lại mật khẩu văn bản rõ ràng xung quanh.

Tôi đề xuất một giải pháp đơn giản sử dụng mô-đun Python key (chủ yếu là tập lệnh bảng điều khiển đồng hành keyring) và trình bao bọc tối thiểu xung quanh ['do', 'something'].execute() tính năng Groovy :

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

Sử dụng chức năng này, signingConfigsphần trở thành:

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

Trước khi chạy, gradle assembleReleasebạn phải đặt mật khẩu trong khóa, chỉ một lần:

$ keyring set google-play android.keystore # will be prompted for the passwords
$ keyring set google-play com.example.app

Chúc mừng phát hành!


5

Mở rộng câu trả lời của David Vavra, tạo tệp ~ / .gradle / gradle.properies và thêm

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

Sau đó, trong 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

Tôi đã có khá nhiều niềm vui để tìm ra điều này. Đây là hướng dẫn của tôi.

Hướng dẫn từ A đến Z về cách tạo tệp xây dựng lớp trong IntelliJ (c.13.1.4) Hướng dẫn này giả định rằng bạn biết cách tạo tệp kho khóa. Để hướng dẫn này hoạt động, bạn sẽ cần tệp kho khóa của bạn được đặt trong thư mục ứng dụng của bạn và bạn sẽ cần phải có tệp zipalign.exe của mình trong 'SDK-ROOT \ tools'. Tệp này thường được tìm thấy trong 'SDK-ROOT \ build-tools' và trong thư mục này, nó sẽ nằm trong thư mục api cao nhất (alpha hoặc beta tôi khuyên dùng phiên bản alpha).

Đối với những người muốn nhảy thẳng vào đây là tập tin xây dựng lớp.

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'
}

Bạn có thể xây dựng một phần của tệp xây dựng này (ở trên) từ tùy chọn menu: Cấu trúc tệp / dự án Từ đây chọn Facets và nhấp vào 'Android-Gradle (Ứng dụng). Từ đây, bạn sẽ thấy các tab: 'Thuộc tính', 'Ký', 'Hương vị', 'Loại xây dựng' và 'Phụ thuộc' cho hướng dẫn này, chúng tôi sẽ chỉ sử dụng 'Ký' và 'Kiểu xây dựng'. Trong 'Loại bản dựng' (trong phần tên), hãy nhập bất kỳ tên nào bạn muốn xác định cấu hình loại bản dựng và trong 4 trường khác, nhập thông tin kho khóa của bạn (đặt đường dẫn kho khóa theo tên trong thư mục ứng dụng của bạn).

Trong phần 'Kiểu xây dựng', nhập giá trị 'assemblybleRelease' vào trường tên, 'Debuggable' nên được đặt thành false, 'Jni Debug Build' nên sai, đặt 'Chạy Proguard' thành true và 'Zip Align' thành true. Điều này sẽ tạo tệp xây dựng, nhưng không được mô tả ở trên, bạn sẽ phải thêm một vài thứ vào tệp xây dựng sau đó. Vị trí tệp ProGuard ở đây sẽ được đặt thủ công trong tệp xây dựng lớp. (như mô tả ở trên)

Các container DSL bạn sẽ phải thêm sau đó như sau:

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

Bạn cũng sẽ phải thêm:

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'
}

lưu ý bộ chứa DSL này ở trên ('phụ thuộc') phải ở dưới cùng của tệp cấu hình nhưng không nằm trong bộ chứa DSL của Android. Để xây dựng bộ chứa phụ thuộc từ menu IntelliJ, chọn: Cấu trúc tệp / dự án. Từ đó chọn Facets một lần nữa và sau đó là Android-Gradle (ứng dụng). Bạn sẽ thấy 5 tab tương tự như đã đề cập ở trên. Chọn tab 'Phụ thuộc' và thêm các phụ thuộc bạn yêu cầu.

Sau khi hoàn thành tất cả những điều này, bạn sẽ thấy tệp xây dựng Gradle tương tự như tệp ở đầu trang này. Để xây dựng bản phát hành được căn chỉnh zip đã ký, bạn sẽ cần mở các tác vụ Gradle. Bạn có thể đến cửa sổ này bằng cách chọn View / Tool Windows / Gradle. Từ đây, bạn có thể nhấp đúp vào 'assemblybleAssembleRelease. Điều này sẽ tạo APK có thể triển khai của bạn.

Các vấn đề tiềm ẩn có thể xảy ra khi biên dịch bản phát hành của bạn là (nhưng không giới hạn ở): Tệp bản dựng Gradle của bạn nằm sai vị trí. Có hai tập tin xây dựng Gradle; một trong thư mục gốc ứng dụng của bạn và một trong thư mục ứng dụng dưới thư mục gốc của ứng dụng. Bạn phải sử dụng cái sau.

Bạn cũng có thể có vấn đề lint. (Lưu ý: Android Developer Studio tốt hơn nhiều trong việc phát hiện các sự cố Lint so với IntelliJ, bạn sẽ nhận thấy điều này khi cố gắng tạo APK có chữ ký từ các tùy chọn menu)

Để giải quyết các vấn đề khó khăn, bạn sẽ cần đặt bộ chứa DSL sau vào bộ chứa Android (ở trên cùng):

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

Đặt cái này vào trong bộ chứa DSL Android của bạn sẽ khiến một tệp lỗi được tạo trong thư mục bản dựng (ngay trong thư mục ứng dụng của bạn), tên tệp phải là một cái gì đó như 'lint-results-release-fatal.html', tệp này sẽ cho bạn biết lớp xảy ra lỗi. Một tệp khác sẽ được tạo là một tệp XML có chứa 'ID vấn đề' liên quan đến lỗi lint. Tên tệp phải là một cái gì đó như 'lint-results-release-fatal.xml'. Ở đâu đó gần đầu tập tin, bạn sẽ thấy một nút 'vấn đề' bên trong mà bạn sẽ thấy một cái gì đó tương tự như 'id = "IDOfYourLintPro Hiệu"'

Để khắc phục sự cố này, hãy mở tệp trong dự án của bạn được liệt kê trong tệp 'lint-results-assemblybleRelease-fatal.html' và nhập dòng mã sau vào tệp Lớp Java ngay phía trên tên lớp: @SuppressLint ("IDOfYourLintPro Hiệu "). Bạn có thể phải nhập 'android.annotation.SuppressLint;'

Vì vậy, tệp lớp java của bạn sẽ xuất hiện như sau:

package com.WarwickWestonWright.developers4u.app.CandidateArea;

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

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

Lưu ý rằng việc loại bỏ lỗi lint không phải lúc nào cũng là IDEA tốt nhất, bạn có thể nên thay đổi mã gây ra lỗi lint.

Một vấn đề khác có khả năng có thể xảy ra là nếu bạn chưa đặt biến môi trường cho biến môi trường Gradle HOME. Biến này được đặt tên là 'GRADLE_HOME' và nên được đặt đường dẫn của thư mục nhà lớp, giống như 'C: \ gradle-1.12' Đôi khi, bạn cũng có thể muốn đặt biến môi trường cho 'ANDROID_HOME' đặt này thành 'CỦA BẠN- Root-Root \ sdk '

Sau khi hoàn thành, quay trở lại cửa sổ nhiệm vụ Gradle và nhấp đúp vào tệp lắp rápAssembleRelease.

Nếu tất cả đều thành công, bạn sẽ có thể truy cập ứng dụng thư mục \ build \ apk và tìm tệp APK có thể triển khai của mình.


+1 cho nỗ lực và: 'lintOptions {abortOnError false}'
Raz Tourgman

4

Một cách tiếp cận khác cho cùng một vấn đề. Vì không nên lưu trữ bất kỳ loại thông tin xác thực nào trong mã nguồn, chúng tôi đã quyết định đặt mật khẩu cho kho lưu trữ khóa và bí danh khóa trong một tệp thuộc tính riêng biệt như sau:

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

Nếu bạn sử dụng git, bạn có thể tạo một tệp văn bản có tên, ví dụ: safe.properIES. Bạn nên đảm bảo loại trừ nó khỏi kho lưu trữ của bạn (nếu sử dụng git, thêm nó vào tệp .gitignore). Sau đó, bạn sẽ cần tạo một cấu hình ký, giống như một số câu trả lời khác chỉ ra. Sự khác biệt duy nhất là cách bạn sẽ tải thông tin đăng nhập:

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')
        }
        ...
    }
}

Không bao giờ quên gán SignConfig cho loại bản dựng phát hành theo cách thủ công (vì một số lý do đôi khi tôi cho rằng nó sẽ được sử dụng tự động). Ngoài ra, không bắt buộc phải kích hoạt proguard, nhưng nó được khuyến khích.

Chúng tôi thích cách tiếp cận này tốt hơn là sử dụng các biến môi trường hoặc yêu cầu đầu vào của người dùng vì nó có thể được thực hiện từ IDE, bằng cách chuyển sang loại xây dựng realease và chạy ứng dụng, thay vì phải sử dụng dòng lệnh.


1
Gradle không biên dịch bằng cách sử dụng này: props = new Properties (); Không thể đặt giá trị của 'đạo cụ' thuộc tính chỉ đọc
ghép vào

Bạn đúng @ m3n0R. Tôi đã chỉnh sửa một dòng phản hồi của mình để phản ánh bản sửa lỗi mà chúng tôi phải giới thiệu trong ứng dụng của mình để nó vẫn được biên dịch bằng các phiên bản mới nhất của Gradle. Về cơ bản, đạo cụ phải được khai báo là một biến cục bộ.
argenkiwi

làm thế nào điều này có thể được chấp nhận bằng cách sử dụng các công cụ CI / CD trên đám mây .... / path / to / keystore và /path/to/secure.props đang ném tôi .... mặc dù vậy, cảm ơn vì điều này.
sirvon

4

Android Studio Chuyển đến Tệp -> Cấu trúc dự án hoặc nhấn Ctrl + Alt + Shift + S

Xem hình ảnh

nhập mô tả hình ảnh ở đây

Nhấp vào Ok

Sau đó, SignConfigs sẽ tạo trên tệp build.gradle của bạn.

nhập mô tả hình ảnh ở đây


Và đây chính xác là những gì bạn không muốn làm. Bằng cách này, tất cả mật khẩu của bạn đều ở dạng văn bản rõ ràng và là một phần của dự án của bạn và rất dễ dàng vô tình bao gồm, ngay cả trong bản dựng phân tán của bạn.
not2qubit

2

Tôi đã có một số vấn đề mà tôi đặt dòng sau ở sai vị trí:

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 "******"
    }
}

Đảm bảo rằng bạn đặt các phần SignConfigs bên trong phần Android:

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

thay vì

android
{
    ....
}

signingConfigs {
   release {
        ...
   }
}

Rất dễ mắc sai lầm này.


2

Đó là năm 2019 và tôi cần ký APK với chữ ký V1 (chữ ký jar) hoặc V2 (chữ ký APK đầy đủ). Tôi đã googled "tạo lớp apk có chữ ký" và nó đã đưa tôi đến đây. Vì vậy, tôi đang thêm giải pháp ban đầu của tôi ở đây.

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

Câu hỏi ban đầu của tôi: Cách sử dụng V1 (chữ ký Jar) hoặc V2 (Chữ ký APK đầy đủ) từ tệp build.gradle


Không cần bán dấu hai chấm; nó sẽ cung cấp cho bạn một lỗi.
Takeshi Kaga

Đúng vậy Cảm ơn. Tôi chỉnh sửa câu trả lời.
user1506104

1

Để bổ sung cho các câu trả lời khác, bạn cũng có thể đặt tệp gradle.properIES của mình trong thư mục mô-đun của riêng bạn, cùng với build.gradle, chỉ trong trường hợp kho khóa của bạn dành riêng cho một dự án.


1

tôi đang làm việc trong Ubuntu14.04. vim ~ / .bashrc và thêm xuất ANDROID_KEYSTORE = xuất ANDROID_KEUALIAS =

và sau đó trong 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 {

        }
    }

}

IMHO dường như là giải pháp tốt nhất, nhưng thật không may, nó đã ngừng hoạt động trên các phiên bản mới hơn của Gradle : System.console()return null.
Antonio Vinicius Menezes Medei

1

Một cách khác là xác định một tác vụ chỉ chạy trên các bản dựng phát hành.

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();
}

Những điều sau đây có vẻ thích hợp hơn với tôi: stackoverflow.com/a/19130098/3664487 Làm thế nào để hai cách tiếp cận so sánh?
dùng2768

1

Bạn có thể yêu cầu mật khẩu từ dòng lệnh:

...

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
  }

  ...
}

...

Các if-then-elsekhối ngăn cản yêu cầu mật khẩu khi bạn đang xây dựng một thông cáo. Mặc dù elsechi nhánh không thể truy cập được, nhưng nó lừa Gradle tạo ra một install...Releasenhiệm vụ.

Cốt truyện . Như được lưu ý bởi https://stackoverflow.com/a/19130098/3664487 , "Tập lệnh Gradle có thể nhắc nhập dữ liệu của người dùng bằng phương thức System.console (). ReadLine ." Thật không may, Gradle sẽ luôn yêu cầu mật khẩu, ngay cả khi bạn đang xây dựng một bản phát hành gỡ lỗi (xem Cách tạo một bản phát hành apk có chữ ký bằng Gradle? ). May mắn thay, điều này có thể được khắc phục, như tôi đã chỉ ra ở trên.


Câu trả lời trước đây của tôi gặp vấn đề do stackoverflow.com/questions/33897802/ . Tôi đã sửa đổi câu trả lời của tôi để loại bỏ vấn đề này.
dùng2768

@Haroon, nó hoạt động kể từ ngày 24 tháng 11 năm 15. Cộng đồng có thể giúp giải quyết vấn đề của bạn, nhưng bạn sẽ cần cung cấp thêm chi tiết.
dùng2768

Tôi như giải pháp này vì nó tránh đặt mật khẩu trong văn bản rõ ràng trong một file văn bản nhưng System.Console (). ReadLine không làm việc trong gradle do này vấn đề gây phiền nhiễu.
morpheus

@morpheus, tôi chưa bao giờ gặp vấn đề. Ở trên là làm việc cho tôi.
dùng2768

Tôi nghĩ bạn chạy tập lệnh từ trong IDE. nếu đoạn script được chạy từ terminal, bạn sẽ thấy lỗi. nhưng cảm ơn vì câu trả lời này đây là những gì tôi đang tìm kiếm
morpheus

0

Thêm cách của tôi để làm điều đó trong React-Native bằng cách sử dụng gói Reac -igen -config .
Tạo tệp .env:

RELEASE_STORE_PASSWORD=[YOUR_PASSWORD]
RELEASE_KEY_PASSWORD=[YOUR_PASSWORD]

lưu ý điều này không nên là một phần của kiểm soát phiên bản.

trong của bạn build.gradle:

signingConfigs {
        debug {
            ...
        }
        release {
            storeFile file(RELEASE_STORE_FILE)
            storePassword project.env.get('RELEASE_STORE_PASSWORD')
            keyAlias RELEASE_KEY_ALIAS
            keyPassword project.env.get('RELEASE_KEY_PASSWORD')
        }
    }

0

Trong trường hợp của tôi, tôi đã tải lên apk sai, phát hành ứng dụng khác.


0

Dành cho Groovy (build.gradle)

Bạn không nên đặt thông tin đăng nhập của mình trực tiếp vào tệp build.gradle . Thay vào đó, thông tin đăng nhập phải đến từ một tệp không thuộc kiểm soát phiên bản.

Đặt một tệp tên.properies nơi tìm thấy build.gradle cụ thể của mô-đun . Đừng quên thêm nó vào tập tin .gitignore của bạn !

ký kết.

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

xây dựng. nâng cấp

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
            // ...
        }
    }
}

0

Đối với tập lệnh Kotlin (build.gradle.kts)

Bạn không nên đặt thông tin đăng nhập của mình trực tiếp vào build.gradle.kts tệp . Thay vào đó, thông tin đăng nhập phải đến từ một tệp không thuộc kiểm soát phiên bản.

Đặt một tệp tên.properies nơi tìm thấy mô-đun cụ thể build.gradle.kts . Đừng quên thêm nó vào tập tin .gitignore của bạn !

ký kết.

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

build.gradle.kts

android {
    // ...
    signingConfigs {
        create("release") {
            val properties = Properties().apply {
                load(File("signing.properties").reader())
            }
            storeFile = File(properties.getProperty("storeFilePath"))
            storePassword = properties.getProperty("storePassword")
            keyPassword = properties.getProperty("keyPassword")
            keyAlias = "release"
        }
    }

    buildTypes {
        getByName("release") {
            signingConfig = signingConfigs.getByName("release")
            // ...
        }
    }
}

-1

nếu bạn không muốn xem phương thức không thể gọi readLine () trên đối tượng null. bạn cần viết bằng gradle.properies trước.

KEYSTORE_PASS=*****
ALIAS_NAME=*****
ALIAS_PASS=*****
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.