วิธีสร้างไฟล์ apk ที่ลงนามแล้วโดยใช้ Gradle


514

ฉันต้องการให้ Gradle build ของฉันสร้างไฟล์ apk ที่ลงชื่อแล้วโดยใช้ Gradle

ฉันไม่แน่ใจว่ารหัสถูกต้องหรือไม่หากฉันทำพารามิเตอร์หายไปgradle build?

นี่คือรหัสบางส่วนในไฟล์ gradle ของฉัน:

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

โครงสร้างการไล่ระดับสีเสร็จสิ้นความสำเร็จและในbuild/apkโฟลเดอร์ของฉันฉันเห็น...-release-unsigned.apkและ...-debug-unaligned.apkไฟล์เท่านั้น

ข้อเสนอแนะเกี่ยวกับวิธีการแก้ปัญหานี้?



ลงชื่อด้วย v1 (ลายเซ็น jar) หรือ v2 (เวอร์ชัน apk เต็มรูปแบบ) จากไฟล์ gradle หรือไม่ วิธีแก้ปัญหาที่นี่: stackoverflow.com/questions/57943259/…
user1506104

คำตอบ:


429

วิธีที่ง่ายกว่าคำตอบก่อนหน้า:

ใส่ลงไป ~/.gradle/gradle.properties

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

แก้ไขของคุณapp/build.gradleและเพิ่มสิ่งนี้ในandroid {บล็อครหัส:

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

จากนั้นคุณสามารถเรียกใช้ gradle assembleRelease


ดูการอ้างอิงสำหรับsigningConfigsGradle DSL


12
วิธีที่ดีที่สุดถ้าคุณถามฉัน ไม่ต้องบันทึกอะไรในโฟลเดอร์โปรเจค / SVN และฉันสามารถเช็คเอาต์ 10 โปรเจคของฉันได้โดยไม่ต้องกังวลเรื่องกุญแจ
แฟรงค์

8
หากคุณกำลังใช้ gradlew บน Windows คุณต้องแน่ใจว่า GRADLE_USER_HOME ได้รับการกำหนดให้เป็นตัวแปรสภาพแวดล้อมเพื่อใช้งานได้ ฉันตั้งไว้ที่หนึ่งไดเรกทอรีเหนือไดเรกทอรีโครงการของฉันและวางที่เก็บคีย์ของฉัน พา ธ ไปยังที่เก็บคีย์ของคุณใน gradle.properties ควรใช้เครื่องหมายทับซ้าย (/) หรือแบ็กสแลชสองครั้ง (\\) ไม่ใช่แบ็กสแลชเดี่ยวของ Windows เพื่อสร้าง keystore จากคำสั่งของ Windows พรอมต์ให้ดูstackoverflow.com/questions/3997748/how-can-i-create-a-keystore
Anachronist

3
พา ธ สัมพันธ์กับตำแหน่งของไฟล์ build.gradle หรือสัมพันธ์กับไดเร็กทอรีรูทของเครื่องหรือไม่?
เปรม

1
@Prem ให้file()ถือว่าเส้นทางที่สัมพันธ์กันเสมอ ใช้new File(path)ถ้าคุณต้องการให้ถือว่าเป็นแบบสัมบูรณ์
ars-longa-vita-brevis

4
สิ่งนี้ใช้ได้กับฉันและสิ่งที่ง่ายที่สุด ใน gradle.properties ระบุ storeFile ที่เกี่ยวข้องกับโมดูล build.gradle ของคุณเช่นนั้น RELEASE_STORE_FILE = .. / mykeystore อย่าเพิ่มราคาอื่น ๆ ไล่ระดับความสับสนเส้นทาง
Lakshman Chilukuri

263

ฉันจัดการเพื่อแก้ไขมันเพิ่มรหัสนี้และสร้างด้วยgradle build:

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

สิ่งนี้จะสร้างไฟล์ apk ที่ลงนามแล้ว


33
มีวิธีทำให้รหัสผ่านสำหรับฉันหรือไม่ หรือคำแนะนำอื่น ๆ เพื่อป้องกันรหัสผ่านจาก repos git ของฉัน
user672009

3
ฉันแก้ไข build.gradle ให้ดูเหมือนของคุณ แต่ใช้งาน "สร้าง> สร้าง APK ที่ลงชื่อแล้ว ... " ยังคงให้กล่องโต้ตอบนั้น ("ดูคู่มือผู้ใช้ Gradle สำหรับข้อมูลเพิ่มเติม" ฯลฯ ) และไม่มี APK
Semanticer

3
@Semanticer Execute gradle buildหรือgradlew buildใน Terminal / Prompt Command
Phillip Kamikaze

12
@ user672009 คุณสามารถใส่รหัสผ่านในไฟล์คุณสมบัติและแยกออกจาก repos ด้วย. gitignore คุณสามารถดูลิงค์นี้ gist.github.com/gabrielemariotti/6856974
Gabriele Mariotti

1
@GabrieleMariotti ยังคงมีที่เก็บข้อมูลไม่สมบูรณ์ วิธีที่ดีกว่าคือการสร้างโครงกระดูกการลงทะเบียนคุณสมบัติและหลังจากยอมรับการออก "git update-index --assume-unchanged registration.properties" อย่างไรก็ตามสิ่งนี้ทำให้การแก้ไขฟิทูร่าไม่ได้เกิดขึ้น สิ่งที่ชอบ sdqali ตัวเลือกแรกดูเหมือนว่าจะดียิ่งขึ้น
user672009

67

โปรดทราบว่าสคริปต์ของ @ sdqali จะ (อย่างน้อยเมื่อใช้ Gradle 1.6) ขอรหัสผ่านเมื่อใดก็ตามที่คุณเรียกใช้งานการไล่ระดับสีใด ๆ เนื่องจากคุณต้องการเพียงเมื่อทำgradle assembleRelease(หรือคล้ายกัน) คุณสามารถใช้เคล็ดลับต่อไปนี้:

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

โปรดทราบว่าฉันยังต้องเพิ่มต่อไปนี้ (ภายใต้ Android) เพื่อให้ทำงาน:

buildTypes {
    release {
        signingConfig signingConfigs.release
    }
}

หลังจากใช้งานแล้วinstallReleaseหายไปจากรายการงาน ... เพราะอะไร
Kaarel

1
@caspase หวังว่าฉันได้แสดงความคิดเห็นของคุณเกี่ยวกับ "storePassword" และ "keyPassword" ปลอมอย่างจริงจังมากขึ้น หากไม่มีการเริ่มต้นคุณสมบัติเหล่านี้ ("ตัวอย่าง") * * -release.apk ที่ลงนามแล้วจะไม่ถูกสร้างขึ้นไม่มีข้อผิดพลาดปรากฏขึ้นและคุณจะงงอย่างสมบูรณ์ด้วย * * -release-unsigned.apk ในไดเรกทอรี PROJECT_NAME / build / apk / ของคุณ . ผู้ชาย ... : /
vizZ

ขอขอบคุณสำหรับข้อควรทราบเกี่ยวกับการเพิ่มการลงนามในรูปแบบภายใต้ buildTypes -> Release นั่นเป็นการแก้ไขการลงชื่ออัตโนมัติสำหรับฉัน!
mm2001

1
ฉันสร้างปลั๊กอิน gradle ง่ายๆที่ถามรหัสผ่านเมื่อสร้าง apk (โดยใช้ mathod ที่อธิบายไว้ในโพสต์นี้ แต่คุณไม่จำเป็นต้องกำหนด store store รหัสผ่าน & keyPassword ปลอม) มันยังมีอยู่ในส่วนกลาง maven github.com/alexvasilkov/AndroidGradleSignPlugin
Alex Vasilkov

มันเยี่ยมมาก ระวังว่าตัวแปรสภาพแวดล้อมKEYSTOREจะต้องมีการกำหนดแม้กระทั่งสำหรับ debug builds และสำหรับ "gradle sync" ใน Android Studio มิฉะนั้นจะทำให้เกิดข้อผิดพลาดเกี่ยวกับเส้นทางที่เป็นโมฆะ
Jerry101

63

หากคุณต้องการหลีกเลี่ยงการเข้ารหัสที่เก็บคีย์และรหัสผ่านในbuild.gradleคุณสามารถใช้ไฟล์คุณสมบัติตามที่อธิบายไว้ที่นี่: การจัดการการกำหนดค่าการกำหนดด้วย GRADLE

โดยทั่วไป:

1) สร้างไฟล์ myproject.properties ที่ / home/ [ชื่อผู้ใช้เหมือนกัน] / การเซ็นชื่อด้วยเนื้อหาดังกล่าว:

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

2) สร้างไฟล์ gradle.properties (อาจอยู่ที่รูทของไดเรกทอรีโครงการของคุณ) พร้อมเนื้อหา:

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

3) อ้างถึงในbuild.gradleเช่นนี้:

    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
ใช้งานได้ดี! ขอบคุณ. รหัสนี้จะต้องเพิ่มก่อนส่วน buildTypes {} และส่วนจะต้องประกาศการลงนามการลงนาม Configs.release ตามปกติ
theczechsensation

ในที่สุดฉันก็พบทางออกสำหรับปัญหานี้ สิ่งเดียวที่ช่วยฉันได้จริงๆ! นี่อาจเป็นคำตอบที่ได้รับการยอมรับ ...
devnull69

39

แอพลงชื่ออัตโนมัติด้วย Gradle เมื่อใช้ git

มันน่าอัศจรรย์ที่มีวิธีการที่ซับซ้อนมากมายในการทำสิ่งนี้ นี่คือวิธีการของตัวเองที่ฉันพยายามที่จะยึดมั่นในตัวเองของ Google ข้อเสนอแนะ อย่างไรก็ตามคำอธิบายของพวกเขายังไม่ชัดเจนดังนั้นฉันจะอธิบายขั้นตอนสำหรับ Linux โดยละเอียด


รายละเอียด:

คำแนะนำเริ่มต้นของ Googleสำหรับการลงชื่อแอปโดยอัตโนมัติในระหว่างการสร้างโดยไม่ต้องเก็บรหัสผ่านและไฟล์ลายเซ็นต์ในเส้นทางการพัฒนาแอป (GIT) ของคุณค่อนข้างคลุมเครือ นี่คือคำแนะนำทีละขั้นตอนชี้แจงวิธีการทำ

สมมติฐานเบื้องต้น:

คุณมี app ที่เรียกว่า "แอปของฉัน" $HOME/projects/mydev/MyAppในไดเรกทอรีที่กำหนดโดยเส้นทางต่อไปนี้: อย่างไรก็ตามไดเรกทอรี MyApp จะใช้และควบคุมด้วย GIT

ป้อนคำอธิบายรูปภาพที่นี่

ปัญหา

เห็นได้ชัดว่าเราไม่ต้องการมีไฟล์ลายเซ็นหรือรหัสผ่านของเราที่ใดก็ได้ในไดเรกทอรีควบคุม GIT แม้ว่าเราจะสามารถใช้งานได้.gitignoreฯลฯ ก็ยังมีความเสี่ยงและง่ายต่อการเข้าใจผิด ดังนั้นเราต้องการไฟล์ที่เก็บคีย์และลายเซ็นของเรานอก

สารละลาย

เราต้องทำสามสิ่ง:

  1. สร้างไฟล์รหัสผ่านที่จะใช้โดย Android Studio
  2. สร้างไฟล์คีย์ลายเซ็น
  3. แก้ไขbuild.gradleไฟล์โมดูลที่จะใช้ (1) และ (2)

สำหรับตัวอย่างนี้เราตั้งชื่อไฟล์สองไฟล์:

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

เราสามารถใส่ไฟล์ทั้งสองนี้ได้ที่นี่:

cd $HOME/projects/mydev/

(1) สร้างไฟล์รหัสผ่านที่เก็บคีย์

ไฟล์แรกมีรหัสผ่านข้อความที่ชัดเจนที่ใช้ใน และพา ธ ไปยังไฟล์ release-key ใน (2) เริ่มต้นด้วยการกรอกสิ่งนี้เนื่องจากจะทำให้การวางสำเนาได้ง่ายขึ้นสำหรับขั้นตอนถัดไป

cd $HOME/projects/mydev/

แก้ไขkeystore.propertiesเพื่อให้เนื้อหาเป็น:

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

ส่วนที่ยุ่งยากเพียง myStoreFileLocationแต่ที่นี่เป็น นี่คือพา ธที่เห็นได้จากbuild.gradleไฟล์โมดูลระหว่างการบิลด์ $HOME/projects/mydev/MyApp/app/build.gradleนี้มักจะหมายถึงเส้นทางที่คล้ายกันและเมื่อเทียบกับ: ดังนั้นเพื่อให้ชี้ไปที่MyApp-release-key.jks ไฟล์สิ่งที่เราต้องใส่ที่นี่คือ:

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

ที่นี่เรายังเลือกนามแฝง "myapp" สำหรับกุญแจ จากนั้นไฟล์สุดท้ายควรมีลักษณะ:

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

(2) สร้างไฟล์ลายเซ็น

ไฟล์ที่สองจะถูกสร้างขึ้นโดยอัตโนมัติเมื่อคุณสร้างคีย์ลายเซ็น หากคุณไม่มีแอพอื่นและนี่เป็นที่เก็บคีย์เดียวของคุณให้สร้างไฟล์ด้วย:

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

นี่จะขอรหัสผ่านสองชุดจากคุณและข้อมูล (เช่นเดียวกับใน Android Studio) ตอนนี้คัดลอก / วางรหัสผ่านที่คุณเลือกไว้ก่อนหน้า

(3) แก้ไขgradle.buildไฟล์โมดูลของคุณเพื่อใช้งานด้านบน

ชิ้นส่วนต่อไปนี้จำเป็นต้องมีอยู่ในไฟล์ Gradle build ของแอพ / โมดูล ก่อนอื่นให้เพิ่มบรรทัดต่อไปนี้ภายนอกและก่อนandroid {}บล็อกของคุณ

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

จากนั้นภายในandroid {}บล็อกเพิ่ม:

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

ตอนนี้จาก shell คุณสามารถสร้างแอปของคุณใหม่ด้วย:

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

สิ่งนี้ควรสร้างแอปที่ลงชื่ออย่างเหมาะสมซึ่งสามารถใช้ใน Google Play


ปรับปรุง: 2019-04-02

รุ่นที่ใหม่กว่าkeytoolและมีบางอย่างกำลังบอกคุณว่าคุณควรใช้คีย์ไฟล์ที่ใช้PKCS12แทนไฟล์ดั้งเดิม / ค่าเริ่มต้นตามที่ฉันใช้ด้านบน จากนั้นพวกเขาก็จะบอกคุณว่าคุณควรแปลงเป็นรูปแบบ PKCS12 แบบเปิดใหม่ อย่างไรก็ตามดูเหมือนว่าเครื่องมือพัฒนา Android ยังไม่พร้อมสำหรับเรื่องนี้เพราะถ้าคุณทำคุณจะได้รับข้อผิดพลาดแปลก ๆ ดังต่อไปนี้:

com.android.ide.common.signing.KeytoolException:ไม่สามารถอ่านคีย์ XXX จากร้านค้า "F: \ XXX \ XXX.jks": รับคีย์ล้มเหลว: บล็อกสุดท้ายที่ได้รับนั้นไม่ถูกต้อง ปัญหาดังกล่าวสามารถเกิดขึ้นได้หากมีการใช้คีย์ที่ไม่ดีในระหว่างการถอดรหัส

ดังนั้นอย่าใช้คีย์แปลง!


การลงชื่อเข้าใช้Configsถูกบันทึกไว้ใน apk หรือไม่จากนั้นผู้ใช้รายใดสามารถถอดรหัสรหัสผ่านหรือไม่ปรากฏใน apk หรือไม่
JavierSegoviaCordoba

2
ทำงานเหมือนจับใจ ขอบคุณนี่น่าจะเป็นคำตอบที่ได้รับการยอมรับ
pratham kesarkar

ถ้าคุณต้องการที่เก็บคีย์และรหัสผ่านบนบิลด์เซิร์ฟเวอร์ ด้วยวิธีแก้ไขปัญหาข้างต้นผู้พัฒนาทุกคนในทีมจะต้องมีที่เก็บคีย์บนเครื่องของพวกเขา มิฉะนั้นการซิงค์โครงการ Gradle จะล้มเหลว: keystore.properties (ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว)
Diana Farin

1
คุณสามารถส่งkeystore.propertiesไฟล์ดัมมี่ไปยังตัวควบคุมแหล่งที่มาดังนั้นสร้างงานบนเครื่อง dev ผมได้อธิบายการตั้งค่าการสร้างเซิร์ฟเวอร์ที่นี่
dskrvk

1
ทราบเกี่ยวกับการปรับปรุงครั้งล่าสุดของคุณเกี่ยวกับkeytoolการสร้างที่เก็บคีย์ PKCS12: คุณสามารถส่งผ่าน-storetype JKSในkeytoolคำสั่งเพื่อกำหนดประเภท keystore ที่จะจางกึนซอกซึ่งเป็นที่ต้องการโดยการขับรถของ Android
Trevor Halvorson

35

Like @Destil กล่าว แต่อนุญาตให้ผู้อื่นที่ไม่มีคีย์เพื่อสร้าง: วิธีที่ง่ายกว่าคำตอบก่อนหน้า:

ใส่ลงไป ~/.gradle/gradle.properties

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

แก้ไขของคุณbuild.gradleเช่นนี้:

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

จากนั้นคุณสามารถเรียกใช้gradle assembleRelease หรือ gradle build


วิธีตั้งค่าพา ธ ใน windows: พา ธ ไปยังที่เก็บคีย์ของคุณ
reza_khalafi

ไฟล์ storeFile ("C: \\ Users \\ xxxx \\ Documents \\ yyyy \\ mykey.jks") ถูกต้องหรือไม่
reza_khalafi

28

(ในการตอบกลับไปยังผู้ใช้672009ด้านบน)

ทางออกที่ง่ายยิ่งขึ้นถ้าคุณต้องการเก็บรหัสผ่านของคุณออกจากที่เก็บ git; ยังต้องการรวม build.gradle ของคุณไว้ในที่ทำงานได้ดีกับรสชาติของผลิตภัณฑ์คือการสร้างไฟล์ gradle แยกต่างหาก มาเรียกมันว่า 'Sign.gradle' (รวมไว้ใน. gitignore ของคุณ) ราวกับว่ามันเป็นไฟล์ build.gradle ของคุณลบทุกอย่างที่ไม่เกี่ยวข้องกับการลงชื่อเข้าใช้

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

จากนั้นในไฟล์ build.gradle ของคุณจะรวมบรรทัดนี้ไว้ใต้ "ใช้ปลั๊กอิน: 'android'"

 apply from: 'signing.gradle'

หากคุณไม่มีหรือใช้หลายรสชาติให้เปลี่ยนชื่อ "flavor1" เป็น "release" ด้านบนและคุณควรทำให้เสร็จ หากคุณใช้รสชาติต่อไป

ในที่สุดเชื่อมโยงรสชาติของคุณเข้ากับการลงนามที่ถูกต้องในไฟล์ build.gradle ของคุณและคุณควรจะเสร็จ

  ...

  productFlavors {

      flavor1 {
          ...
          signingConfig signingConfigs.flavor1
      }

      flavor2 {
          ...
          signingConfig signingConfigs.flavor2
      }
  }

  ...

คุณเป็นคนพิเศษมากกว่านี้ได้ไหม ฉันไม่สามารถเรียกใช้: "ไม่สามารถแก้ไขสัญลักษณ์การลงนาม Config"
Amio.io

ถ้าฉันรวม 'การลงนาม. กราน' ใน build.gradle - ฉันถูกบังคับให้มีหนึ่งในที่เก็บคอมไพล์ (อื่นฉันได้รับข้อผิดพลาด และถ้าฉันใส่ 'การลงนาม. กราน' ในคอมไพล์มันเอาชนะวัตถุประสงค์ ฉันจะรวมการลงชื่อเข้าใช้แกรมตัวเลือกได้อย่างไร
Jaguar

21

หากคุณมีไฟล์ที่เก็บคีย์อยู่แล้วมันอาจจะง่ายพอ ๆ กับการเพิ่มพารามิเตอร์บางตัวลงในคำสั่ง build ของคุณ:

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

ไม่จำเป็นต้องเปลี่ยนแปลงโครงการ Android ของคุณอย่างถาวร

ที่มา: http://www.tinmith.net/wayne/blog/2014/08/gradle-sign-command-line.htm


18

นี่คือการตอบกลับไปยังผู้ใช้672009และนอกจากนี้โพสต์ของ sdqali (รหัสของเขาจะผิดพลาดในการสร้างเวอร์ชั่นการแก้ปัญหาด้วยปุ่ม "Run" ของ IDE):

คุณสามารถใช้รหัสต่อไปนี้:

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 {

        }
    }

}

มีวิธีที่จะมีค่าเริ่มต้นบ้างไหม? ที่เก็บคีย์ของฉันมักจะเหมือนกัน storePassword มักจะเหมือนกับ keyPassword และ keyAlias ​​มักจะชื่อโครงการเป็นตัวพิมพ์เล็ก
user672009

@ user672009 คุณสามารถใช้รหัส Java ภายในสคริปต์
AChep

1
คุณอาจต้องการที่จะใช้สิ่งนี้: keyPassword new String(console.readPassword("Enter key password: "))เพื่อให้แน่ใจว่ารหัสผ่านของคุณจะไม่ปรากฏในระหว่างการป้อนข้อมูล
Alex Semeniuk

วิธีนี้ใช้ไม่ได้อีกต่อไปดูgithub.com/gradle/gradle/issues/1251
SqAR.org

16

ใน Android Studio ที่ใหม่กว่ามีวิธี GUI ซึ่งง่ายมากและเติมข้อมูลไฟล์ Gradle ด้วย

  1. File -> Project Structure

  2. Module -> เลือกโมดูลหลัก ('แอป' หรือชื่อที่กำหนดเองอื่น ๆ )

  3. Signing แท็บ -> บวกภาพเพื่อเพิ่มการกำหนดค่าใหม่

  4. เติมข้อมูลทางด้านขวา

  5. ตกลงและไฟล์ Gradle จะถูกสร้างขึ้นโดยอัตโนมัติ

  6. ด้วยตนเองคุณจะต้องเพิ่มบรรทัดsigningConfig signingConfigs.NameOfYourConfigภายในbuiltTypes{release{}}

รูปภาพ:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุสำคัญสองรายการ (!):

(แก้ไข 12/15)

  1. ในการสร้าง APK ที่ลงชื่อคุณต้องเปิดแท็บ Terminal ของ Android Studio (ด้านล่างของอินเทอร์เฟซหลัก) และออกคำสั่ง ./gradlew assembleRelease

  2. หากคุณลืมkeyAlias(เกิดอะไรขึ้นกับฉันบ่อยครั้ง) คุณจะต้องเริ่มBuild -> Generate Signed APKต้นกระบวนการและดูชื่อของรหัสนามแฝง


2
นี่จะเข้ารหัสรหัสผ่านของคุณลงในbuild.gradleไฟล์ใช่ไหม
Joshua Pinter

16

หากคุณสร้าง apk ผ่านทางบรรทัดคำสั่งอย่างฉันคุณสามารถให้การกำหนดค่าการลงชื่อเป็นอาร์กิวเมนต์

เพิ่มไปยังของคุณ 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
}

ทำของคุณsigningConfigsเช่นนี้

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

จากนั้นคุณดำเนินการgradlewเช่นนี้

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

ซึ่งเป็นbuild.gradle? ระดับสูง? กรุณาเพิ่มรหัสเพิ่มเติม
Vlad

เพื่อชี้แจงนี้เป็นapp/build.gradleไฟล์ที่ฉันพูดถึง
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
        }
    }
}

ใช้ Android Studio 0.5.1, Gradle 1.11 และปลั๊กอิน Gradle 0.9
JP Ventura

1
การสร้างคุณสมบัติตามต้องการ (หรือคุณสมบัติไดนามิก) ได้รับการคัดค้านและมีกำหนดที่จะถูกลบใน Gradle 2.0
JP Ventura

10

คุณยังสามารถใช้ตัวเลือกบรรทัดคำสั่ง-Pของ gradle เพื่อช่วยในการเซ็นชื่อ ใน build.gradle ของคุณเพิ่ม SingConfigs แบบนี้:

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

จากนั้นเรียก gradle build ดังนี้:

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

คุณสามารถใช้ -P เพื่อตั้งค่า storeFile และ keyAlias ​​หากคุณต้องการ

นี่คือโซลูชันของ Destil โดยทั่วไป แต่มีตัวเลือกบรรทัดคำสั่ง

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับคุณสมบัติ gradle ตรวจสอบคู่มือผู้ใช้ gradle


7

@ คำตอบของ Destil นั้นดีถ้าคุณสามารถนำโครงแบบเดิมมาใช้ใหม่ในทุกโครงการ อีกวิธีหนึ่งคือ Android Studio มาพร้อมกับlocal.propertiesไฟล์ที่สามารถนำมาใช้แทนได้ แต่มันควรจะเป็น IDE ที่สร้างขึ้นและฉันไม่สามารถหาวิธีที่จะขยายจากภายใน Android Studio

นี่คือการเปลี่ยนแปลงของคำตอบของ @ jonbo คำตอบนั้นอนุญาตการตั้งค่าเฉพาะโครงการ แต่มาพร้อมกับค่าใช้จ่ายในการพัฒนาเล็กน้อย โดยเฉพาะจำเป็นต้องมีแผ่นสำเร็จรูปสำคัญเพื่อย้ายsigningConfigsคำจำกัดความไปยังไฟล์แยกต่างหาก - โดยเฉพาะอย่างยิ่งหากคุณจำเป็นต้องทำเช่นนั้นสำหรับหลายโครงการซึ่งเป็นเหตุผลสำคัญในการเลือกโซลูชันนี้เหนือ Destil นี้สามารถที่จะบรรเทาได้บ้างโดยยังรวมถึงสาย

apply plugin: 'com.android.application'

ในไฟล์หนังสือรับรองเนื่องจากจะทำให้ IDE สมบูรณ์

ในที่สุดการแก้ปัญหาส่วนใหญ่ที่นี่ไม่อนุญาตให้สร้างโครงการในโหมดดีบัก - ซึ่งจัดการการลงนามการดีบักโดยอัตโนมัติ - โดยไม่ต้องมี syntactically ถ้าไม่ได้signingConfigsนิยามความหมายถูกต้อง หากคุณไม่จำเป็นต้องสร้างบิลด์จากเครื่องที่กำหนดขั้นตอนพิเศษนี้สามารถมองเห็นเป็นอุปสรรคที่ไม่จำเป็น ในทางกลับกันก็สามารถช่วยเพื่อนร่วมงานที่ไม่รู้หรือขี้เกียจที่ทำงานแก้ปัญหาสร้างในการผลิต

โซลูชันนี้จะช่วยให้การตรวจแก้จุดบกพร่องสร้างโดยไม่ต้องกังวลเกี่ยวกับข้อมูลประจำตัวที่ทั้งหมด แต่จะต้องมีข้อมูลประจำตัวที่ถูกต้องในการผลิตรุ่นสร้างและมันต้องใช้สำเร็จรูปน้อยมาก อย่างไรก็ตามข้อเสียอาจสนับสนุนให้ผู้อื่นแทนที่ค่าดัมมี่ด้วยข้อมูลประจำตัวจริงและไม่มีวิธีที่จะปกป้องมัน

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

สิ่งนี้จะสร้างคุณสมบัติดัมมีที่ทำหน้าที่สร้างไฟล์บิลด์ที่ถูกต้องทางไวยากรณ์ ค่าที่กำหนดให้กับext.signingคุณสมบัติของไม่เกี่ยวข้องเท่าที่การตรวจแก้จุดบกพร่องสร้างไป ต้องการเปิดใช้งานรุ่นสร้างคัดลอกext.signingลงในsigning.gradleและแทนที่ค่าหุ่นที่มีสิทธิที่ถูกต้อง

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

แน่นอนว่าsigning.gradleควรถูกละเว้นโดย VCS


6

แพลตฟอร์มเกือบทั้งหมดในขณะนี้มีพวงกุญแจบางประเภทดังนั้นจึงไม่มีเหตุผลที่จะต้องทิ้งรหัสผ่านข้อความที่ชัดเจน

ฉันเสนอวิธีแก้ปัญหาง่าย ๆ ที่ใช้โมดูล Python Keyring (ส่วนใหญ่เป็นสคริปต์คอนโซลร่วมkeyring) และ wrapper น้อยที่สุดเกี่ยวกับ['do', 'something'].execute() คุณลักษณะ Groovy :

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

การใช้ฟังก์ชั่นนี้signingConfigsส่วนจะกลายเป็น:

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

ก่อนเริ่มใช้งานgradle assembleReleaseคุณต้องตั้งรหัสผ่านในพวงกุญแจของคุณเพียงครั้งเดียว:

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

ขอให้มีความสุข!


5

ขยายคำตอบโดย David Vavra สร้างไฟล์ ~ / .gradle / gradle.properties และเพิ่ม

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

จากนั้นใน 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

ฉันสนุกมากกับการหาอันนี้ นี่คือการเดินผ่านของฉัน

A ถึง Z walk-through เกี่ยวกับวิธีสร้างไฟล์ gradle build ใน IntelliJ (v.13.1.4) walk-through นี้จะถือว่าคุณรู้วิธีสร้างไฟล์ keystore เพื่อให้บทเรียนนี้ทำงานได้คุณจะต้องวางไฟล์ keystore ของคุณในโฟลเดอร์แอพของคุณและคุณจะต้องมีไฟล์ zipalign.exe ของคุณอยู่ใน 'SDK-ROOT \ tools' ไฟล์นี้มักจะพบใน 'SDK-ROOT \ build-tools' และภายใต้โฟลเดอร์นี้มันจะอยู่ในโฟลเดอร์ api ที่สูงที่สุด (อัลฟ่าหรือเบต้าฉันแนะนำรุ่นอัลฟ่า)

สำหรับผู้ที่ต้องการข้ามไปที่นี่คือไฟล์ build gradle

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

คุณสามารถสร้างส่วนหนึ่งของไฟล์บิลด์ (ด้านบน) จากตัวเลือกเมนู: โครงสร้างไฟล์ / โครงการจากที่นี่เลือก Facets และคลิก 'Android-Gradle (App) จากที่นี่คุณจะเห็นแท็บ: 'คุณสมบัติ', 'การลงนาม', 'รสชาติ', 'ประเภทการสร้าง' และ 'การอ้างอิง' สำหรับการแนะนำแบบนี้เราจะใช้ 'การลงชื่อ' และ 'ประเภทการสร้าง' ใต้ 'ประเภทการสร้าง' (ในส่วนชื่อ) ให้ป้อนชื่อใด ๆ ที่คุณต้องการระบุการกำหนดค่าประเภทการสร้างของคุณและในฟิลด์ 4 อื่น ๆ ให้ป้อนข้อมูลที่เก็บคีย์ของคุณ (การตั้งค่าเส้นทางที่เก็บคีย์ที่อยู่ภายใต้โฟลเดอร์แอป

ภายใต้ 'ประเภทการสร้าง' ป้อนค่า 'assembleRelease' ลงในฟิลด์ชื่อ 'Debuggable' ควรถูกตั้งค่าเป็นเท็จ 'Jni Debug Build' ควรเป็นเท็จตั้ง 'Run Proguard' เป็นจริงและ 'Zip Align' เป็นจริง สิ่งนี้จะสร้างไฟล์บิลด์ แต่ไม่ได้อธิบายไว้ข้างต้นคุณจะต้องเพิ่มบางสิ่งลงในไฟล์บิลด์หลังจากนั้น ตำแหน่งไฟล์ ProGuard ที่นี่จะถูกตั้งค่าด้วยตนเองในไฟล์ build gradle (ตามภาพด้านบน)

คอนเทนเนอร์ DSL ที่คุณจะต้องเพิ่มหลังจากนั้นมีดังนี้:

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

คุณจะต้องเพิ่ม:

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

โปรดทราบว่าคอนเทนเนอร์ DSL ด้านบนนี้ ('การอ้างอิง') ควรอยู่ที่ด้านล่างของไฟล์กำหนดค่า แต่ไม่อยู่ในคอนเทนเนอร์ DSL ของ Android ในการสร้างคอนเทนเนอร์อ้างอิงจากเมนู IntelliJ ให้เลือก: โครงสร้างไฟล์ / โครงการ จากนั้นเลือก Facets อีกครั้งจากนั้น Android-Gradle (แอพ) คุณจะเห็นแท็บ 5 แท็บเหมือนที่กล่าวไว้ข้างต้น เลือกแท็บ 'การพึ่งพา' และเพิ่มการอ้างอิงที่คุณต้องการ

หลังจากทั้งหมดนี้เสร็จสิ้นคุณจะเห็นไฟล์ build แบบ Gradle คล้ายกับไฟล์ที่ด้านบนของ walk-through นี้ ในการสร้างการวางแนวซิปที่มีการเซ็นชื่อคุณจะต้องเปิดงาน Gradle คุณสามารถไปที่หน้าต่างนี้ได้โดยเลือก View / Tool Windows / Gradle จากที่นี่คุณสามารถดับเบิลคลิก 'assembleAssembleRelease สิ่งนี้จะสร้าง APK ที่สามารถติดตั้งได้ของคุณ

ปัญหาที่อาจเกิดขึ้นเมื่อทำการคอมไพล์รีลีสของคุณคือ (แต่ไม่ จำกัด เฉพาะ): ไฟล์บิลเดอร์ Gradle ของคุณอยู่ผิดที่ มีไฟล์ Gradle build สองไฟล์; หนึ่งอันในโฟลเดอร์รูทแอปพลิเคชันของคุณและอีกอันในโฟลเดอร์แอปภายใต้รูทแอปพลิเคชัน คุณต้องผู้ใช้หลัง

คุณอาจมีปัญหาที่เป็นขุย (หมายเหตุ: Android Developer Studio ดีกว่าในการตรวจพบปัญหาผ้าสำลีมากกว่า IntelliJ คุณจะสังเกตเห็นสิ่งนี้เมื่อพยายามสร้าง APK ที่ลงชื่อจากตัวเลือกเมนู)

หากต้องการแก้ไขปัญหาเกี่ยวกับผ้าสำลีคุณจะต้องวางคอนเทนเนอร์ DSL ต่อไปนี้ไว้ในคอนเทนเนอร์ Android (ที่ด้านบน):

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

การวางสิ่งนี้ไว้ในคอนเทนเนอร์ DSL ของ Android จะทำให้เกิดไฟล์ข้อผิดพลาดในโฟลเดอร์บิลด์ (ใต้โฟลเดอร์แอพของคุณโดยตรง) ชื่อไฟล์ควรเป็นชื่ออย่างเช่น 'lint-results-release-fatal.html' ไฟล์นี้จะบอกคุณ ชั้นเรียนที่ข้อผิดพลาดเกิดขึ้น ไฟล์อื่นที่จะสร้างขึ้นคือไฟล์ XML ที่มี 'รหัสปัญหา' ที่เกี่ยวข้องกับข้อผิดพลาดที่เป็นขุย ชื่อไฟล์ควรเป็น 'lint-results-release-fatal.xml' บางแห่งใกล้ด้านบนของไฟล์คุณจะเห็นโหนด 'ปัญหา' ซึ่งคุณจะเห็นบางสิ่งที่คล้ายกับ 'id = "IDOfYourLintProblem"'

เพื่อแก้ไขปัญหานี้ให้เปิดไฟล์ในโครงการของคุณที่ระบุไว้ในไฟล์ 'lint-results-assembleRelease-fatal.html' และป้อนบรรทัดของรหัสต่อไปนี้ในไฟล์ Java Class เหนือชื่อคลาส: @SuppressLint ("IDOfYourLintProblem" ") คุณอาจต้องนำเข้า 'android.annotation.SuppressLint;'

ดังนั้นไฟล์คลาส java ของคุณควรปรากฏดังนี้:

package com.WarwickWestonWright.developers4u.app.CandidateArea;

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

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

โปรดทราบว่าการระงับข้อผิดพลาดของผ้าสำลีไม่ได้เป็น IDEA ที่ดีที่สุดเสมอไปคุณอาจจะเปลี่ยนรหัสที่ทำให้เกิดข้อผิดพลาดของผ้าสำลีได้

ปัญหาอื่นที่อาจเกิดขึ้นคือถ้าคุณไม่ได้ตั้งค่าตัวแปรสภาพแวดล้อมสำหรับตัวแปรสภาพแวดล้อม Gradle HOME ตัวแปรนี้มีชื่อว่า 'GRADLE_HOME' และควรกำหนดเส้นทางของไดเรกทอรีบ้าน gradle บางอย่างเช่น 'C: \ gradle-1.12' บางครั้งคุณอาจต้องการตั้งค่าตัวแปรสภาพแวดล้อมสำหรับ 'ANDROID_HOME' ตั้งค่านี้เป็น 'YOUR- SDK ราก \ SDK'

หลังจากเสร็จสิ้นให้กลับไปที่หน้าต่างงาน Gradle และดับเบิลคลิกที่ assembleAssembleRelease

หากประสบความสำเร็จคุณควรไปที่โฟลเดอร์แอพ \ build \ apk และค้นหาไฟล์ APK ที่ปรับใช้ได้ของคุณ


+1 สำหรับความพยายามและ: 'lintOptions {abortOnError false}'
Raz Tourgman

4

อีกวิธีหนึ่งในการแก้ไขปัญหาเดียวกัน เนื่องจากไม่แนะนำให้เก็บข้อมูลประเภทใด ๆ ไว้ในซอร์สโค้ดเราจึงตัดสินใจตั้งรหัสผ่านสำหรับที่เก็บคีย์และชื่อแทนคีย์ในไฟล์คุณสมบัติแยกต่างหากดังนี้:

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

หากคุณใช้ git คุณสามารถสร้างไฟล์ข้อความที่เรียกว่าเช่น secure.properties คุณควรตรวจสอบให้แน่ใจว่าได้แยกออกจากที่เก็บของคุณ (หากใช้ git ให้เพิ่มไปยังไฟล์. gitignore) จากนั้นคุณจะต้องสร้างการกำหนดค่าการลงชื่อเช่นเดียวกับคำตอบอื่น ๆ ที่ระบุ ข้อแตกต่างเพียงอย่างเดียวคือวิธีที่คุณจะโหลดหนังสือรับรอง:

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

อย่าลืมกำหนดให้ลงนามConfigให้กับรุ่นบิลด์ด้วยตนเอง (ด้วยเหตุผลบางครั้งฉันคิดว่ามันจะถูกใช้โดยอัตโนมัติ) นอกจากนี้ยังไม่จำเป็นต้องเปิดใช้ proguard แต่แนะนำให้ใช้

เราชอบวิธีนี้ดีกว่าการใช้ตัวแปรสภาพแวดล้อมหรือการร้องขออินพุตของผู้ใช้เพราะสามารถทำได้จาก IDE โดยเปลี่ยนไปใช้ประเภทบิลด์ realease และเรียกใช้แอปแทนที่จะต้องใช้บรรทัดคำสั่ง


1
Gradle ไม่ได้รวบรวมโดยใช้สิ่งนี้: props = คุณสมบัติใหม่ (); ไม่สามารถตั้งค่า 'พร็อพเพอร์ตี้' แบบอ่านอย่างเดียว
cesards

คุณถูกต้อง @ m3n0R ฉันแก้ไขบรรทัดการตอบสนองของฉันเพื่อสะท้อนถึงการแก้ไขที่เราต้องนำเสนอในแอปของเราดังนั้นมันจะยังคงรวบรวมโดยใช้ Gradle รุ่นล่าสุด โดยทั่วไปอุปกรณ์จะต้องมีการประกาศเป็นตัวแปรท้องถิ่น
argenkiwi

สิ่งนี้จะนำมาใช้ได้อย่างไรโดยใช้เครื่องมือ CI / CD บนคลาวด์ .... the / path / to / keystore และ /path/to/secure.props กำลังขว้างฉัน .... ขอบคุณสำหรับสิ่งนี้
sirvon

4

Android Studio ไปที่ไฟล์ -> โครงสร้างโครงการหรือกด Ctrl + Alt + Shift + S

ดูภาพ

ป้อนคำอธิบายรูปภาพที่นี่

คลิกตกลง

จากนั้น SignConfigs จะสร้างไฟล์ build.gradle ของคุณ

ป้อนคำอธิบายรูปภาพที่นี่


และนี่คือสิ่งที่คุณไม่ต้องการทำ วิธีนี้รหัสผ่านทั้งหมดของคุณจะเป็นข้อความที่ชัดเจนและเป็นส่วนหนึ่งของโครงการของคุณและง่ายมากที่จะรวมไว้โดยไม่ตั้งใจแม้ในการสร้างแบบกระจายของคุณ
not2qubit

2

ฉันมีปัญหาหลายอย่างที่ทำให้บรรทัดต่อไปนี้ผิดที่:

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

ตรวจสอบให้แน่ใจว่าคุณใส่ส่วนของการลงนามค่าคอนในส่วน android:

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

แทน

android
{
    ....
}

signingConfigs {
   release {
        ...
   }
}

มันง่ายที่จะทำผิดพลาดนี้


2

มันคือ 2019 และฉันต้องลงชื่อ APK ด้วย V1 (ลายเซ็น jar) หรือ V2 (ลายเซ็น APK เต็ม) ฉัน googled "สร้าง apk gradle ที่ลงนามแล้ว" และนำฉันมาที่นี่ ดังนั้นฉันจึงเพิ่มโซลูชันดั้งเดิมของฉันที่นี่

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

คำถามเดิมของฉัน: วิธีใช้ V1 (ลายเซ็น Jar) หรือ V2 (ลายเซ็น APK เต็ม) จากไฟล์ build.gradle


ไม่จำเป็นต้องมี semi-colons; มันจะทำให้คุณมีข้อผิดพลาด
Takeshi Kaga

มันถูกต้องแล้ว. ขอบคุณ ฉันแก้ไขคำตอบ
user1506104

1

เพื่อเติมเต็มคำตอบอื่น ๆ คุณสามารถวางไฟล์ gradle.properties ในโฟลเดอร์โมดูลของคุณเองพร้อมกับ build.gradle ในกรณีที่ที่เก็บคีย์ของคุณเฉพาะโครงการหนึ่ง


1

ฉันทำงานใน Ubuntu14.04 vim ~ / .bashrc และเพิ่มการส่งออก ANDROID_KEYSTORE = ส่งออก ANDROID_KEYALIAS =

และจากนั้นในชุด build.gradle

    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 ที่น่าจะเป็นทางออกที่ดีที่สุด แต่โชคร้ายที่มันหยุดการทำงานในรุ่นใหม่ของ Gradle : ผลตอบแทนSystem.console() null
Antonio Vinicius Menezes Medei

1

อีกทางเลือกหนึ่งคือการกำหนดงานที่ทำงานเฉพาะในรุ่นบิลด์

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

ต่อไปนี้น่าจะเป็นที่ต้องการของฉันมากกว่า: stackoverflow.com/a/19130098/3664487ทั้งสองวิธีเปรียบเทียบกันอย่างไร
user2768

1

คุณสามารถขอรหัสผ่านจากบรรทัดคำสั่ง:

...

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
  }

  ...
}

...

if-then-elseบล็อกป้องกันไม่ให้ร้องขอสำหรับรหัสผ่านเมื่อคุณกำลังสร้างปล่อย แม้ว่าelseสาขาจะไม่สามารถเข้าถึงได้ แต่มันจะหลอกลวง Gradle ในการสร้างinstall...Releaseงาน

backstory ตามที่ระบุไว้โดยhttps://stackoverflow.com/a/19130098/3664487 " สคริปต์ Gradle สามารถแจ้งให้ผู้ใช้ป้อนโดยใช้วิธี System.console (). readLine " น่าเสียดายที่ Gradle จะขอรหัสผ่านเสมอแม้ในขณะที่คุณกำลังสร้างการเปิดตัวดีบั๊ก (cf. จะสร้างไฟล์ apk ที่ลงนามแล้วโดยใช้ Gradle ได้อย่างไร ) โชคดีที่สิ่งนี้สามารถเอาชนะได้ดังที่ฉันได้แสดงไว้ด้านบน


คำตอบก่อนหน้านี้ฉันวิ่งเข้าไปในปัญหาที่เกิดขึ้นเนื่องจากการstackoverflow.com/questions/33897802/... ฉันได้แก้ไขคำตอบเพื่อแก้ไขปัญหานี้แล้ว
2768

@ ฮารูนมันทำงานตั้งแต่ 24 พ.ย. 58 ชุมชนอาจช่วยแก้ไขปัญหาของคุณได้ แต่คุณจะต้องให้รายละเอียดเพิ่มเติม
2768

ผมชอบวิธีนี้เพราะมันหลีกเลี่ยงการใส่รหัสผ่านในข้อความที่ชัดเจนในแฟ้มข้อความ แต่ System.Console (). readLine ไม่ทำงานใน gradle เนื่องจากนี้ปัญหาที่น่ารำคาญ
morpheus

@ morpheus ฉันไม่เคยมีปัญหา ข้างต้นใช้งานได้สำหรับฉัน
user2768

ฉันคิดว่าคุณเรียกใช้สคริปต์จากภายใน IDE ถ้าสคริปต์รันจากเทอร์มินัลคุณจะเห็นข้อผิดพลาด แต่ขอบคุณสำหรับคำตอบนี้ นี่คือสิ่งที่ฉันกำลังมองหา
morpheus

0

การเพิ่มวิธีของฉันใน React-Native โดยใช้แพคเกจreact-native-config
สร้างไฟล์. env:

RELEASE_STORE_PASSWORD=[YOUR_PASSWORD]
RELEASE_KEY_PASSWORD=[YOUR_PASSWORD]

โปรดทราบว่านี่ไม่ควรเป็นส่วนหนึ่งของการควบคุมเวอร์ชัน

ในของคุณ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

ในกรณีของฉันฉันอัปโหลด apk ที่ไม่ถูกต้องไปยังแอปอื่นของรีลีส


0

สำหรับ Groovy (build.gradle)

คุณไม่ควรใส่หนังสือรับรองการลงชื่อของคุณโดยตรงในไฟล์build.gradle แต่ข้อมูลประจำตัวควรมาจากไฟล์ที่ไม่อยู่ภายใต้การควบคุมเวอร์ชัน

วางไฟล์การลงนามคุณสมบัติที่พบเฉพาะbuild.gradleโมดูล อย่าลืมเพิ่มลงในไฟล์. gitignoreของคุณ!

signing.properties

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

build.gradle

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

สำหรับ Kotlin Script (build.gradle.kts)

คุณไม่ควรใส่ข้อมูลรับรองการเซ็นของคุณลงในไฟล์build.gradle.ktsโดยตรง แต่ข้อมูลประจำตัวควรมาจากไฟล์ที่ไม่อยู่ภายใต้การควบคุมเวอร์ชัน

ใส่ไฟล์signing.propertiesที่โมดูลเฉพาะbuild.gradle.ktsพบ อย่าลืมเพิ่มลงในไฟล์. gitignoreของคุณ!

signing.properties

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

หากคุณไม่ต้องการที่จะเห็นไม่สามารถเรียกวิธี readLine () บนวัตถุ null คุณต้องเขียนในgradle.propertiesก่อน

KEYSTORE_PASS=*****
ALIAS_NAME=*****
ALIAS_PASS=*****
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.