Что вызывает ошибку Android APK Upload: "Non-upgradeable APK"

У меня есть Android APK в магазине Google Play с целевым SDK из 23.

Я выпустил новую версию (тот же целевой SDK), и Google показывает мне эту ошибку:

Если я продолжу (я усердно научился), то ни один из текущих пользователей не сможет перейти на эту версию. Мне пришлось восстановить код, увеличить номер сборки и перестроить APK для "отката" в полезную версию.

Однако я не могу понять, почему Google показывает мне эту ошибку. Обратите внимание: "0 поддерживаемых Android-устройств" - это красно-селедка - это известная проблема в Google Play за последние 24 часа - если вы публикуете APK, отображается реальное количество устройств.

Пожалуйста, дайте мне несколько подсказок о том, какая разница или что вызывает эту ошибку:

Не обновляемый APK ПРЕДУПРЕЖДЕНИЕ Ни один из пользователей этого APK не сможет обновить ни один из новых APK, добавленных в эту версию. НАКОНЕЧНИК Убедитесь, что все ваши новые APK добавлены в этот выпуск. введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь

Ответ 1

Мне удалось решить эту проблему: -

Проблема была в коде версии - я уверен, что вы не определили какой-либо код версии в своем приложении, и он создается с помощью этой формулы:

 versionCode = MAJOR * 10000 + MINOR * 100 + PATCH

Но иногда автоматически сгенерированное значение версии версии последней версии становится меньше, чем предыдущая версия (в вашем случае 10403 и 104028), и поэтому он показывает не обновляемый APK.

Что вам нужно сделать: -

В вашем теге config.xml добавьте код версии, как показано ниже: -

android-versionCode="104280" 

104280 будет работать для вас, поскольку он больше, чем более старая версия.

Теперь опубликуйте его без ошибок.

Спасибо Санни

Ответ 2

Я использую VS-TACO и столкнулся с этой проблемой.

Чтобы немного разъяснить ответ Санни, который исправил проблему для меня. По-видимому, где-то по пути вычислялась версия android-versionCode с использованием этой формулы:

MAJOR * 100000 + MINOR * 1000 + PATCH * 10

но теперь он вычисляется с использованием версии Sanny:

MAJOR * 10000 + MINOR * 100 + PATCH

Так, например, если ваша версия была 1.3.1, версия android-версия была рассчитана как "103010"

теперь вы меняете версию на 1.3.2, и она вычисляется по-новому, поэтому версия "10302" меньше, чем "103010".

Итак, чтобы обойти эту проблему (я думаю, навсегда, если версия для Android продолжает вычисляться по-новому), вы можете добавить тег версии в свой файл config.xml:

<?xml version="1.0" encoding="utf-8"?>
<widget android-versionCode="103020" ...

или вы можете перейти в Visual Studio и использовать визуальный редактор для config.xml, перейдите в раздел "Android" и измените значение "Код версии:".

Ответ 3

У меня возникла аналогичная проблема, но я смог решить ее с помощью следующего Node script, используемого как часть моего конвейера непрерывного развертывания.

Примечание:

Это читается из файла VERSION.md, который содержит текущую версию приложения.

Он также может быть запущен с аргументом --version только для обновления текущей версии в config.xml без установки версий сборки.

#!/usr/bin/env node

var fs = require('fs');
var xml2js = require('xml2js');
const cliArgs = require('command-line-args');
const options = cliArgs([
    {name: 'version', type: Boolean}
]); 

// Read config.xml
var xml = fs.readFileSync('config.xml', 'utf8');

// Parse XML to JS Obj
xml2js.parseString(xml, function (err, result) {
    if(err) {
        return console.log(err);
    }

    // Get JS Obj
    var obj = result;
    const version = fs.readFileSync('VERSION.md', 'utf8');

    if (options.version){
        // Write current version
        obj['widget']['$']['version'] = version;
    } else {
        // Increment build numbers (separately for iOS and Android)
        obj['widget']['$']['ios-CFBundleVersion'] = version;
        // remove all periods to create an integer for Android
        const [major, minor, patch] = version.split('.')
        obj['widget']['$']['android-versionCode'] = major+pad_number(minor)+pad_number(patch);
    }

    // Build XML from JS Obj
    var builder = new xml2js.Builder();
    var xml = builder.buildObject(obj);

    // Write config.xml
    fs.writeFile('config.xml', xml, function(err) {
        if(err) {
            return console.log(err);
        }

        console.log('Build number successfully incremented');
    });

});

/**
 * Pad a number with prepending zeros if less than 10
 * @see [Javascript function to pad a string](https://stackoverflow.com/questions/2686855/is-there-a-javascript-function-that-can-pad-a-string-to-get-to-a-determined-leng)
 */
function pad_number(orig) {
    return ("00"+orig).slice(-2);
}

Ответ 4

Для тех из вас, кто использует Android Studio, у меня была эта проблема после обновления с Eclipse до Android Studio, а не для правильной настройки файлов gradle.

Убедитесь, что код версии в файле build.gradle по умолчаниюConfig {} верен.

...
defaultConfig {
    ...
    versionCode 373
    versionName "3.73"

Ответ 5

Я столкнулся с этой проблемой, потому что в моем кордове config.xml предыдущая версия была 0.0.51, а новая версия была 0.0.6. Но в консоли playstore эти номера были преобразованы в 51 и 6 для номера APK. Нельзя "обновить" с 51 до 6. Поэтому я изменил xml на 0.0.60, что сделало APK-номер 60, и voila, я могу обновить от 51 до 60.

Ответ 6

У меня просто была та же проблема с версиями, когда я обновил реактивную версию до 0.60.5 Поэтому я рассчитал разницу между отсутствующей версией versionCode

Version 1.9 = VersionCode => 4194313

Version 1.10 = VersionCode = 3145739

Difference: 194313 - 3145739 = 1048574

Каждый APK для каждой архитектуры будет использовать эту формулу

versionCodes.get(abi) * 1048576 + defaultConfig.versionCode

Я немного изменил мою формулу

versionCodes.get(abi) * 1048576 + defaultConfig.versionCode + 1048574

// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
    variant.outputs.each { output ->
        // For each separate APK per architecture, set a unique version code as described here:
        // https://developer.android.com/studio/build/configure-apk-splits.html
        def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
        def abi = output.getFilter(OutputFile.ABI)
        if (abi != null) {  // null for the universal-debug, universal-release variants
            output.versionCodeOverride =
                    versionCodes.get(abi) * 1048576 + defaultConfig.versionCode + 1048575;
        }

    }