573

Gradle を使用してリリース署名済みの apk ファイルを作成するために、Gradle をビルドしたいと考えています。

コードが正しいかどうか、または実行時にパラメーターが欠落しているgradle buildかどうかわかりません。

これは私のgradleファイルのコードの一部です:

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

gradle ビルドは正常に終了し、build/apkフォルダーにはファイル...-release-unsigned.apk...-debug-unaligned.apkファイルのみが表示されます。

これを解決する方法について何か提案はありますか?

4

31 に答える 31

517

以前の回答よりも簡単な方法:

これを入れて~/.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のリファレンスも参照してください。

于 2014-01-09T12:36:23.140 に答える
36

@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 次に、 OR を実行できますgradle build

于 2014-08-19T19:52:44.000 に答える
28

(上記のuser672009への返信。)

パスワードを git リポジトリから除外したい場合は、さらに簡単な解決策です。それでも、build.gradle を含めたい場合は、製品のフレーバーでもうまく機能し、別の gradle ファイルを作成する必要があります。これを「signing.gradle」と呼びましょう (.gitignore に含めます)。build.gradle ファイルからサインインに関連しないすべてのものを差し引いたものと同じように。

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

次に、build.gradle ファイルで、「apply plugin: 'android'」のすぐ下にこの行を含めます。

 apply from: 'signing.gradle'

複数のフレーバーを持っていない、または使用していない場合は、上記の「flavor1」の名前を「release」に変更してください。フレーバーを使用している場合は続行します。

最後に、フレーバーを build.gradle ファイルの正しいsigningConfigにリンクすると、完了です。

  ...

  productFlavors {

      flavor1 {
          ...
          signingConfig signingConfigs.flavor1
      }

      flavor2 {
          ...
          signingConfig signingConfigs.flavor2
      }
  }

  ...
于 2014-02-01T05:22:27.710 に答える
9

Kotlin スクリプトの場合 (build.gradle.kts)

build.gradle.ktsファイルに署名資格情報を直接入れないでください。代わりに、資格情報はバージョン管理下にないファイルから取得する必要があります。

モジュール固有のbuild.gradle.ktsが見つかった場所にファイルsigning.propertiesを置きます。.gitignoreファイルに忘れずに追加してください。

署名.プロパティ

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")
            // ...
        }
    }
}
于 2020-04-13T12:40:27.630 に答える
7

@Destil の答えは、すべてのプロジェクトで同じ構成を再利用できる場合に適しています。あるいは、Android Studio にはlocal.properties代わりに使用できるファイルが付属していますが、おそらく IDE で生成されたものであり、Android Studio 内から拡張する方法が見つかりません。

これは@jonbo の回答のバリエーションです。その答えはプロジェクト固有の設定を許可しますが、開発者のオーバーヘッドが少し伴います。具体的には、signingConfigs定義を別のファイルに移動するには、かなりのボイラープレートが必要です。特に、複数のプロジェクトでそうする必要がある場合は、Destil のソリューションよりもこのソリューションを選択する主な理由です。これは、次の行も含めることで多少軽減できます

apply plugin: 'com.android.application'

これにより、IDE の完了が可能になります。

最後に、ここでのほとんどのソリューションでは、意味的に有効ではないにしても構文的に有効な定義を提供せずに、デバッグ モード (デバッグ署名を自動的に処理する) でプロジェクトをビルドすることはできません。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.signingsigning.gradleて置き換えます。

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

もちろん、signing.gradleVCS は無視する必要があります。

于 2015-01-26T08:05:56.243 に答える
7

現在、ほぼすべてのプラットフォームで何らかのキーリングが提供されているため、平文のパスワードをそのままにしておく理由はありません。

Python Keyring モジュール(主にコンパニオン コンソール スクリプトkeyring) と Groovy['do', 'something'].execute() 機能の最小限のラッパーを使用する単純なソリューションを提案します。

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

ハッピーリリース!

于 2014-03-23T22:05:35.037 に答える
6

私はこれを理解するのがとても楽しかったです。これが私のウォークスルーです。

IntelliJ (v.13.1.4) で gradle ビルド ファイルを作成する方法に関する A から Z のウォークスルー このウォークスルーは、キーストア ファイルの作成方法を知っていることを前提としています。このチュートリアルを機能させるには、キーストア ファイルをアプリ フォルダーに配置し、zipalign.exe ファイルを「SDK-ROOT\tools」に配置する必要があります。このファイルは通常、「SDK-ROOT\build-tools」にあり、このフォルダーの下の最上位の api フォルダーにあります (alpha または beta アルファ バージョンをお勧めします)。

ここに直接ジャンプしたい人のために、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'
}

このビルド ファイル (上記) の一部をメニュー オプションからビルドできます: File/Project Structure ここから Facets を選択し、「Android-Gradle(App)」をクリックします。ここから、「プロパティ」、「署名」、「フレーバー」、「ビルド タイプ」、「依存関係」のタブが表示されます。このウォークスルーでは、「署名」と「ビルド タイプ」のみを使用します。[ビルド タイプ] (名前セクション) の下に、ビルド タイプ構成を識別する任意の名前を入力し、他の 4 つのフィールドにキーストア情報を入力します (キーストア パスをアプリ フォルダーの下のものに設定します)。

「Build Types」の下で、値「assemblyRelease」を名前フィールドに入力します。「Debuggable」は false に設定し、「Jni Debug Build」は false に設定し、「Run Proguard」は true に、「Zip Align」は true に設定します。これによりビルド ファイルが生成されますが、上に示したものとは異なり、後でビルド ファイルにいくつか追加する必要があります。ここでの ProGuard ファイルの場所は、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 コンテナー (「依存関係」) は、構成ファイルの下部にある必要がありますが、Android DSL コンテナー内にある必要はありません。IntelliJ メニューから依存関係コンテナーをビルドするには、ファイル/プロジェクト構造を選択します。そこから再び Facets を選択し、次に Android-Gradle(app) を選択します。上記と同じ 5 つのタブが表示されます。[依存関係] タブを選択し、必要な依存関係を追加します。

これがすべて完了すると、このウォークスルーの冒頭にあるファイルと同様の Gradle ビルド ファイルが表示されます。署名済みの zip アライメント リリースをビルドするには、Gradle タスクを開く必要があります。View/Tool Windows/Gradle を選択すると、このウィンドウにアクセスできます。ここから、「assemblyAssembleRelease」をダブルクリックします。これにより、デプロイ可能な APK が生成されます。

リリースをコンパイルする際に発生する可能性のある問題は次のとおりです (ただし、これらに限定されません): Gradle ビルド ファイルが間違った場所にある。2 つの Gradle ビルド ファイルがあります。1 つはアプリケーション ルート フォルダーにあり、もう 1 つはアプリケーション ルートの下のアプリ フォルダーにあります。後者を使用する必要があります。

糸くずの問題もあるかもしれません。(注: Android Developer Studio は、IntelliJ よりも Lint の問題を見つけるのにはるかに優れています。メニュー オプションから署名付き APK を生成しようとすると、これに気付くでしょう)

lint の問題を回避するには、次の DSL コンテナーを Android コンテナー内 (上部) に配置する必要があります。

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

これを android DSL コンテナー内に配置すると、ビルド フォルダー (アプリ フォルダーの直下) にエラー ファイルが生成されます。ファイル名は「lint-results-release-fatal.html」のようになります。エラーが発生したクラス。生成される別のファイルは、lint エラーに関連付けられた「問題 ID」を含む XML ファイルです。ファイル名は「lint-results-release-fatal.xml」のようなものにする必要があります。ファイルの上部付近に「issue」というノードがあり、その中に「id="IDOfYourLintProblem"」のようなものが表示されます。

この問題を修正するには、「lint-results-assembleRelease-fatal.html」ファイルにリストされているプロジェクトのファイルを開き、Java クラス ファイルのクラス名のすぐ上に次のコード行を入力します。 @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}

lint エラーを抑制することが常に最善のアイデアであるとは限らないことに注意してください。lint エラーの原因となったコードを変更した方がよい場合もあります。

潜在的に発生する可能性のある別の問題は、Gradle HOME 環境変数の環境変数を設定していない場合です。この変数は「GRADLE_HOME」という名前で、「C:\gradle-1.12」のような gradle ホーム ディレクトリのパスを設定する必要があります。場合によっては、「ANDROID_HOME」の環境変数を「YOUR-」に設定することもできます。 SDK-Root\sdk'

これが完了したら、Gradle タスク ウィンドウに戻り、assemblyAssembleRelease をダブルクリックします。

すべてが成功した場合、フォルダ app\build\apk に移動して、デプロイ可能な APK ファイルを見つけることができるはずです。

于 2014-09-13T02:34:30.100 に答える
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')
        }
        ...
    }
}

リリースビルドタイプにsigningConfigを手動で割り当てることを忘れないでください(何らかの理由で、自動的に使用されると想定することがあります)。また、proguard を有効にすることは必須ではありませんが、推奨されます。

環境変数を使用したり、ユーザー入力を要求したりするよりも、このアプローチの方が気に入っています。これは、コマンド ラインを使用するのではなく、realease ビルド タイプに切り替えてアプリを実行することにより、IDE から実行できるためです。

于 2014-08-19T03:48:26.627 に答える
4

Groovy の場合 (build.gradle)

build.gradleファイルに署名資格情報を直接入れないでください。代わりに、資格情報はバージョン管理下にないファイルから取得する必要があります。

モジュール固有のbuild.gradleが見つかった場所にファイルsigning.propertiesを置きます。.gitignoreファイルに忘れずに追加してください。

署名.プロパティ

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
            // ...
        }
    }
}
于 2020-04-13T12:39:17.270 に答える
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();
}
于 2015-07-27T13:54:32.500 に答える
1

私はUbuntu14.04で働いています。vim ~/.bashrc を追加し、 export ANDROID_KEYSTORE= export 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 {

        }
    }

}
于 2015-04-07T06:22:37.850 に答える
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タスクを作成させます。

裏話https://stackoverflow.com/a/19130098/3664487で指摘されているように、「Gradle スクリプトは System.console().readLine メソッドを使用してユーザー入力を求めることができます。」残念ながら、デバッグ リリースをビルドしている場合でも、Gradle は常にパスワードを要求します (参照: Gradle を使用してリリース署名付き apk ファイルを作成する方法は? )。幸いなことに、これは上で示したように克服できます。

于 2015-11-17T19:38:15.273 に答える
-1

私のように、テスト目的でデバイス上でリリースを実行できるようにしたい場合は、署名用の 2 つ目のキーストアを作成することを検討してください。そうすれば、マーケット キーを気にせずに、単純にパスワードを build.gradle に入れることができます。ストアのセキュリティ。

Build/Generate Signed APK/Create new... をクリックして、新しいキーストアを作成できます。

于 2016-03-24T00:38:28.573 に答える