Сбой проверки приложения, поддерживающего MirrorLink, после подписания APK с ключом разработчика Google

Я работаю над приложением Android с поддержкой MirrorLink и столкнулся с проблемами при проверке Mirrorlink "идентификатора приложения" после подписания APK с помощью ключа разработчика Google.

Я создал пустой проект, сгенерированный с помощью плагина Mirrorlink для студии Android, который создал задачу Gradle, позволяющую генерировать .crt файл с информацией о конфигурации, связанной с Mirrorlink. Я просто скопировал этот скрипт на свой build.gradle файл в главном модуле приложения. Но валидатор приложения с поддержкой Mirrorlink показывает ошибку для подписанного APK (стандартное подписывание приложения для публикации в Google Play), но не находит проблем, если APK не подписан.

Как выяснить проблему, возникшую после подписания приложения?

Что я пробовал: 1) Выровнять скрипт Gradle с примером приложения, предоставленным Mirrorlink - не повезло.

2) Вставка v1SigningEnabled false а также v2SigningEnabled false - не повезло.

3) Выходные данные Gradle для APK со знаком и без знака одинаковы, за исключением имени выходного файла и > Task :app:validateSigningRelease задача.

AndroidManifest.xml Отрезано связанное с Mirrorlink:

<uses-permission android:name="com.mirrorlink.android.service.ACCESS_PERMISSION"/>

<intent-filter>
                <action android:name="com.mirrorlink.android.app.LAUNCH"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>

            <intent-filter>
                <action android:name="com.mirrorlink.android.app.TERMINATE"/>
                <category android:name="android.intent.category.DEFAULT"/>

Build.gradle модуля приложения:

def generateSelfSignedCertificate(version){
    def buildType = version == "release" ? "assembleRelease": "assembleDebug"
    def rerunAssemble = true
    def projectLocation = projectDir.toString()
    def certGeneratorLocation = "certificategenerator-android-studio.jar"
    def certXmlLocation = projectLocation + "/certificate.xml"
    def certificateDestination = projectLocation + "/src/main/assets/self-signed.ccc.crt"
    def certificateFolder = projectLocation + "/src/main/assets/"
    def certificateIssuer = "CN=SELF-SIGNED"
    def developerId = ""
    def apkLocation = ""
    android.applicationVariants.all { variant ->
        if ((variant.name).equals(version)) {
            variant.outputs.each { output ->
                //noinspection GrReassignedInClosureLocalVar
                apkLocation = output.outputFile
            }
        }
    }

    if (project.hasProperty("isLast")) {
        rerunAssemble = !isLast
    }


    if (rerunAssemble) {
        def subdir = new File(certificateFolder)
        if( !subdir.exists() ) {
            subdir.mkdirs()
        }
        exec {
            executable 'java'
            args "-jar", certGeneratorLocation, "generate-certificate", apkLocation,
                    android.defaultConfig.applicationId, android.defaultConfig.versionCode,
                    certXmlLocation, certificateDestination, certificateIssuer, developerId
            println(args)
        }
        if (System.properties['os.name'].toLowerCase().contains("windows")) {
            exec {
                executable "cmd"
                workingDir projectLocation
                args  "/c", "..\\gradlew.bat", buildType, "-PisLast=true"
            }
        } else {
            exec {
                executable "bash"
                workingDir projectLocation
                args "../gradlew", buildType, "-PisLast=true"
            }
        }
    }
}

android {
.....

    signingConfigs {
        storeFile = 'sign.keyStorePath')
            keyAlias = 'sign.keyAlias'
            storePassword = 'sign.storePassword'
            keyPassword = 'sign.keyPassword'
        }
    }

    afterEvaluate {
        if (this.hasProperty("assembleRelease")){
            assembleRelease.finalizedBy generateSelfSignedCertificateForRelase
        }
    }

    task generateSelfSignedCertificateForRelase {
        doLast {
            generateSelfSignedCertificate("release")
        }
    }

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

....
}

Запуск "assesbleRelease" выполняется без проблем - он создает файл.crt с идентификатором приложения Mirrorlink. Но если я помещу этот файл в "Средство проверки приложения, поддерживающее Mirrorlink" - он покажет сообщение об ошибке следующим образом:

Checking com.mirrorlink.android.app.LAUNCH intent - OK
Checking com.mirrorlink.android.app.TERMINATE intent - OK
Checking com.mirrorlink.android.service.ACCESS_PERMISSION permission - OK
Checking DEVELOPER entity - INCONCLUSIVE. DEVELOPER entity not found
Checking if developer certificate exists for serverID="" - INCONCLUSIVE. DEVELOPER entity not found
Checking application id - FAIL. Calculated application ID doesn't mach id provided in self signed certificate
Checking self signed certificate - OK


The APK is not configured correctly.

НО если я удалю строку signingConfig signingConfigs.release валидатор не находит проблем:

Checking com.mirrorlink.android.app.LAUNCH intent - OK
Checking com.mirrorlink.android.app.TERMINATE intent - OK
Checking com.mirrorlink.android.service.ACCESS_PERMISSION permission - OK
Checking DEVELOPER entity - INCONCLUSIVE. DEVELOPER entity not found
Checking if developer certificate exists for serverID="" - INCONCLUSIVE. DEVELOPER entity not found
Checking application id - OK
Checking self signed certificate - OK


The APK is correctly configured as a MirrorLink Aware application.

1 ответ

Решение

Ну, ребята, я нашел проблему:) У меня есть Crashlytics в проекте, и он создает файл crashlytics-build.properties это слегка меняется в каждой сборке.

И да, этот файл считается инструментом Mirrorlink certificategenerator-android-studio.jar который генерирует appID с сертификатом. Я сделал реверс-инжиниринг и проверил, что происходит внутри этого инструмента: он только пропускает assets/self-signed.ccc.crt файл и META-INF/ содержание.

Итак, у меня были немного разные APK на КАЖДОЙ сборке... Отключение плагина Crashlytics решает проблему. Вы можете либо отключить плагин Crashlytics (плохая идея), либо использовать ext.alwaysUpdateBuildId = false параметр, чтобы пропустить создание уникального идентификатора сборки. Узнайте больше здесь.

Другие вопросы по тегам