2

Whether I create the "release" APK by:

  • Using Generate Signed APK in Android Studio
  • Select the Release build variant and use Tools -> Build APK
  • Run the assembleRelease task

... the APK produced always has debuggable=true which I've confirmed by trying to upload them to Google Play, which says:

"Upload failed. You uploaded a debuggable APK. For security reasons you need to disable debugging before it can be published in Google Play."

The (only) manifest has no debuggable attribute specified. Gradle specifies debuggable=false for release, and true for debug, see below.

What am I missing? Where is the debuggable state coming from, and why is the debuggable=false in the release build type declaration being ignored? I do not want to add debuggable=false to the manifest and to have to keep manually enabling/disabling it.

app/build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.0'
    defaultConfig {
        applicationId "com.myapp.android"
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 5
        versionName 5
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {
        release {
            storeFile rootProject.file("keystore.jks")
            if (storeFile.exists()) {
                def config = new Properties()
                config.load(new FileInputStream(rootProject.file("keystore.passwords")))
                storePassword config.KeystorePassword
                keyAlias config.KeyAlias
                keyPassword config.KeyPassword
            }
        }
    }

    buildTypes {
        release {
            debuggable false
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            debuggable true
            applicationIdSuffix ".debug"
        }
    }

    dataBinding {
        enabled = true
    }

    lintOptions {
        disable 'RtlHardcoded'
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    // Copy release APK to project root
    task copyReleaseApk(type: Copy) {
        from 'build/outputs/apk'
        into '..'
        include '**/*release.apk'
    }

    afterEvaluate {
        if (tasks.findByPath("packageRelease") == null) {tasks.create("packageRelease")}
        tasks.findByPath("packageRelease").finalizedBy(copyReleaseApk)
    }

}

ext {
    // Single place to specify the support library version
    supportLibraryVersion = '26.0.0-beta2'
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.google.code.findbugs'
        exclude module: 'espresso-idling-resource'
        exclude group: "javax.inject"
    })
    implementation 'com.android.support.test.espresso:espresso-contrib:2.2.2'

    // Dagger dependency injection
    implementation 'com.google.dagger:dagger:2.10'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.10'
    implementation 'com.google.dagger:dagger-android:2.10'
    implementation 'com.google.dagger:dagger-android-support:2.10'
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.10'

    implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
    implementation "com.android.support:design:$supportLibraryVersion"
    implementation "com.android.support.constraint:constraint-layout:1.0.2"

    implementation "com.jakewharton.timber:timber:4.5.1"
    implementation "com.squareup.phrase:phrase:1.1.0"
    implementation "com.squareup.retrofit2:retrofit:2.2.0"
    implementation "com.squareup.retrofit2:converter-gson:2.2.0"
    implementation "com.squareup.okhttp3:logging-interceptor:3.7.0"
    implementation 'net.danlew:android.joda:2.9.9'

    testImplementation 'junit:junit:4.12'
    implementation 'com.google.firebase:firebase-crash:11.0.0'
    androidTestImplementation 'junit:junit:4.12'
}

apply plugin: 'com.google.gms.google-services'

Update 1: I tried adding debuggable=false to the manifest and it makes no difference, the APK produced still cannot be uploaded to Google Play.

Update 2: I loaded the APKs back into Android Studio using the APK Analyzer that makes it easy to see the manifest, and they all include.... debuggable=true. Where is it coming from?

Update 3: assembleRelease produces a debuggable APK on both my local machine AND on the CI server (BuddyBuild).

Update 4: A clean rebuild (including deleting the build folders) and restarting Android Studio with its caches cleared makes no difference.

Update 5: It seems reasonable to assume that the debuggable=true state could be coming from one of the dependencies, but if that is the case which, and how can that be overridden?

4

2 回答 2

3

由于该项目针对 API 26 并使用 android gradle 插件的 3.0.0-alpha4、26.0.0-beta2 构建工具和 gradle 4.0-rc1,我想我应该检查该问题是否与这些 pre 的问题无关-发布工具。所以我恢复到 API 25 和 gradle 3.3 的稳定版本、gradle 插件 2.3.3 和构建工具 25.0.3。这有点乏味,因为我不得不将所有 Java 8 语法从源代码降级到 Java 7。但是这样做之后,构建过程现在可以按预期工作并生成不包含 debuggable="true" 标志的发布 APK 工件并可以上传到 Google Play。

我不清楚具体原因在哪里,但我已将其记录在 Android 工具错误跟踪器中,因为它似乎可能是一个错误: https ://issuetracker.google.com/issues/62899843

更新:工具团队的回应是这是预期的行为,因为该应用程序针对 API 26 并且处于预览状态。我认为由于 26 个 API 是最终版本,因此可以针对它构建 APK 并发布到 Google Play,但显然不是。

于 2017-06-22T14:57:36.747 回答
0

这是因为您可能有增量构建,默认情况下假定所有增量构建debuggable

SDK Tools Revision 8 的 General Notes 中,它指出:

支持真正的调试构建。开发人员不再需要将 android:debuggable 属性添加到清单中的标签 — 构建工具会自动添加该属性。在 Eclipse/ADT 中,所有增量构建都假定为调试构建,因此工具插入 android:debuggable="true"。导出签名的发布版本时,工具不会添加该属性。在 Ant 中,ant 调试命令会自动插入 android:debuggable="true" 属性,而 ant release 则不会。如果手动设置了 android:debuggable="true",那么 ant release 实际上会进行调试构建,而不是发布构建。

于 2017-06-21T17:33:15.380 回答