Как вы можете получить номер версии манифеста из XML-переменных приложения (макета)?

Я хотел бы иметь способ указать номер версии манифеста проекта в основной части кода. Что я делал до сих пор, так это связывал номер версии в файле String XML с манифестом (@string/Version). Я хотел бы сделать это наоборот, связать строковую переменную XML с версией в манифесте. Причина? Я бы хотел изменить номер версии только в одном месте, в файле манифеста. Есть какой-либо способ сделать это? Спасибо!


person PearsonArtPhoto    schedule 17.12.2010    source источник
comment
Это НЕ дубликат. Рассматриваемый вопрос спрашивает, как сделать то же самое в CODE, я спрашиваю в XML. Две очень разные конструкции в программировании для Android...   -  person PearsonArtPhoto    schedule 12.01.2013


Ответы (9)


Я считаю, что на этот вопрос уже ответили здесь.

String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;

OR

int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
person Konstantin Burov    schedule 17.12.2010
comment
Почти, но не совсем... Я бы хотел сослаться на XML-код, но похоже, что это невозможно, так что... - person PearsonArtPhoto; 17.12.2010
comment
Большое спасибо!!! Я везде искал это: String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; - person Aaron Klap; 12.07.2012
comment
@Shubh Я так не думаю. - person Konstantin Burov; 19.07.2013
comment
Добавьте BuildConfig.VERSION_NAME в свой ответ для gradle fokes. - person jobbert; 10.11.2016

Невозможно напрямую получить версию, но есть два обходных пути, которые можно сделать.

  1. Версия может быть сохранена в строке ресурса и помещена в манифест следующим образом:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.somepackage"
         android:versionName="@string/version" android:versionCode="20">
    
  2. Можно создать собственное представление и поместить его в XML. Представление будет использовать это для присвоения имени:

    context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
    

Любое из этих решений позволит разместить имя версии в XML. К сожалению, нет хорошего простого решения, такого как android.R.string.version или что-то в этом роде.

person PearsonArtPhoto    schedule 09.12.2012
comment
небольшое примечание к 1.: это работает, но я думаю, что это не рекомендуется, так как я получаю предупреждение о том, что мне The android:versionName cannot be a resource url, it must be a literal string - person Griddo; 23.04.2013
comment
Что я сделал, так это оставил имя версии манифеста нетронутым (но обновлял его при каждом новом выпуске) и использовал string.xml для хранения значения, которое я буду использовать в приложении. - person numediaweb; 17.09.2013
comment
Для AndroidStudio манифест versionName переопределяется манифестом, установленным в build.gradle файле. - person Adrian C.; 22.03.2016

Вы можете использовать ресурсы versionName в XML, такие как макеты действий. Сначала создайте строковый ресурс в узле app/build.gradle со следующим фрагментом в узле android:

applicationVariants.all { variant ->
    variant.resValue "string", "versionName", variant.versionName
}

Таким образом, все содержимое файла build.gradle может выглядеть так:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion '24.0.0 rc3'
    defaultConfig {
        applicationId 'com.example.myapplication'
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 17
        versionName '0.2.3'
        jackOptions {
            enabled true
        }
    }
    applicationVariants.all { variant ->
        variant.resValue "string", "versionName", variant.versionName
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
} 

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
    compile 'com.android.support:support-v4:23.3.0'
}

Затем вы можете использовать @string/versionName в XML. Android Studio отметит его красным цветом, но приложение скомпилируется без проблем. Например, это можно использовать так в app/src/main/res/xml/preferences.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory
        android:title="About"
        android:key="pref_key_about">

        <Preference
            android:key="pref_about_build"
            android:title="Build version"
            android:summary="@string/versionName" />

    </PreferenceCategory>


</PreferenceScreen>
person Arun Shankar    schedule 07.04.2016
comment
Не могли бы вы объяснить магию (или мое незнание Gradle ;-) за этими строками? - person DenisGL; 06.05.2016
comment
@DenisGL michiganlabs.com/ - person Arun Shankar; 06.05.2016
comment
Это лучше, чем программный стиль. - person Neurotransmitter; 11.05.2016
comment
Замечательное решение. Благодаря тонну. - person Samik Bandyopadhyay; 07.08.2016
comment
Когда я использую эту строку в макете, я получаю предупреждение от Android Studio: Не удалось разрешить ресурс @string/version_name. Любая идея, как избавиться от него? - person DenisGL; 05.11.2016
comment
@DenisGL вы добавили variant.resValue "string", "versionName", variant.versionName в build.gradle ? - person Arun Shankar; 06.11.2016
comment
это казалось отличным ответом, когда я его читал, но, к сожалению, он не работает, по крайней мере, не в последней версии Android Studio. - person k2col; 23.11.2016
comment
Я использую последнюю и все еще работает для меня. Я использую эту и несколько других переменных, подобных этой. @ k2col какую ошибку вы получаете при компиляции? Пожалуйста, опубликуйте свой код градации - person Arun Shankar; 23.11.2016
comment
Это следует считать лучшим ответом. - person pepan; 04.04.2017
comment
Он работал, но показывал красную метку || ошибка в xml, хотя он работает - person A_rmas; 04.04.2017
comment
@A_rmas, какая ошибка появляется, когда вы наводите курсор на красную подсветку? - person Arun Shankar; 04.04.2017
comment
@ArunElectra не может разрешить символ. но он позволяет запускать и генерировать apk. это просто маркировка ошибки. - person A_rmas; 13.04.2017
comment
Не работает для меня. Пытался использовать его в моем TextView, но он говорит, что не найден ресурс, соответствующий заданному имени (в «тексте» со значением «@string/versionName»). - person Patrick; 25.08.2017
comment
это лучшее решение, с помощью этого решения мы можем показывать разные версии для разных вариантов - person Koorosh Ghorbani; 21.12.2018
comment
Вау, отличное решение!!! Плохо только то, что AndroidStudio думает, что строка не распознана, но apk генерируется как надо! - person Andris; 05.12.2019

Я решил эту проблему, расширив класс Preference.

package com.example.android;

import android.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;

public class VersionPreference extends Preference {
    public VersionPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        String versionName;
        final PackageManager packageManager = context.getPackageManager();
        if (packageManager != null) {
            try {
                PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
                versionName = packageInfo.versionName;
            } catch (PackageManager.NameNotFoundException e) {
                versionName = null;
            }
            setSummary(versionName);
        }
    }
}

Затем в моих настройках XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.android.VersionPreference android:title="Version" />
</PreferenceScreen>
person seastland    schedule 23.11.2013
comment
Упс. Должно быть, я думал о Preference XML на основе другого комментария. - person seastland; 24.11.2013
comment
Тем не менее, я все равно просто скопирую и вставлю его ответ. - person Mathijs Segers; 11.06.2015

ЕСЛИ вы используете Gradle, вы можете использовать файл build.gradle для программного добавления значения к ресурсам xml во время компиляции.

Пример кода, извлеченный из: https://medium.com/@manas/manage-your-android-app-s-versioncode-versionname-with-gradle-7f9c5dcf09bf

buildTypes {
    debug {
        versionNameSuffix ".debug"
        resValue "string", "app_version", "${defaultConfig.versionName}${versionNameSuffix}"
    }
    release {
        resValue "string", "app_version", "${defaultConfig.versionName}"
    }
}

теперь используйте @string/app_version по мере необходимости в XML

Он добавит .debug к имени версии, как описано в связанной статье, в режиме отладки.

person CrandellWS    schedule 19.08.2018
comment
лучший ответ!! - person Raheel Hasan; 14.01.2019

Я использую BuildConfig.VERSION_NAME.toString();. В чем разница между этим и получением его из packageManager?

Никакие решения на основе XML не работали для меня, извините.

person Mullazman    schedule 08.01.2016
comment
BuildConfig.VERSION_NAME уже является строкой, для нее не нужно вызывать toString(). - person Makotosan; 04.04.2016
comment
Привычка. Справедливо - person Mullazman; 06.04.2016
comment
Бывают случаи, когда вызов этого в вашем проекте может привести к результату, отличному от ожидаемого. Например, если вы используете подмодуль Android в своем проекте и вызываете его из кода подмодуля, он будет ссылаться на конфигурацию сборки подмодуля, которая может иметь другую версию. Или, если вы вызываете его из кода вашего проекта, вы можете по ошибке сослаться на сборку конфигурации вашего подмодуля и получить тот же результат. Просто будьте осторожны и дважды проверьте, что вы ссылаетесь на правильный пакет конфигурации сборки. - person MikeL; 05.10.2016
comment
Попробуйте использовать это руководство: среда. com/@manas/ - person CrandellWS; 19.08.2018
comment
разница в том, что BuilConfig предоставляется Gradle, тогда как его получение во время выполнения осуществляется с помощью PackageManager (ОС) - person Ishaan Kumar; 24.01.2020

Вы не можете использовать его из XML.

Вам нужно расширить виджет, который вы используете в XML, и добавить логику для установки текста, используя то, что упомянуто в ответе Константина Бурова.

person Macarse    schedule 17.12.2010
comment
Я этого и боялся... Спасибо за помощь! - person PearsonArtPhoto; 18.12.2010
comment
мы можем использовать его. пожалуйста, проверьте мой ответ. Я использую его в своем приложении - person Arun Shankar; 07.04.2016

Самое простое решение - использовать BuildConfig.

Я использую BuildConfig.VERSION_NAME в своем приложении.

Вы также можете использовать BuildConfig.VERSION_CODE для получения кода версии.

person cHAuHaN    schedule 23.06.2019

Поздно в игру, но вы можете сделать это без @string/xyz с помощью ?android:attr

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="?android:attr/versionName"
     />
    <!-- or -->
    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="?android:attr/versionCode"
     />
person ddrscott    schedule 09.09.2013
comment
Я использую так: <Preference android:title="Version" android:summary="?android:attr/versionName" ></Preference>, но отображаю как ?16843292. Что не так? - person Suge; 26.09.2013
comment
Я не уверен, но думаю, что это для более поздних API? - person Mafro34; 10.12.2013
comment
@PearsonArtPhoto на самом деле, где это сказано? - person Mafro34; 15.12.2013
comment
не работает; возвращает смешной номер, который @Suge указал выше - person pepan; 04.04.2017
comment
вообще не работает и возвращает случайное значение, как ранее опубликовано - person A_rmas; 04.04.2017
comment
как отмечено и связано. Это постоянное значение 16843292 (0x0101021c), поэтому @suge получил это конкретное значение - person CrandellWS; 19.08.2018