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


184

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


17
Это не дубликат. Вопрос в том, как сделать то же самое в CODE, который я задаю в XML. Две совершенно разные конструкции в программировании на Android ...
PearsonArtPhoto

Ответы:


367

Я считаю, что здесь уже был дан ответ .

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

ИЛИ

int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;

8
Почти, но не совсем ... Я хотел бы сослаться на XML-код, но, похоже, это невозможно, поэтому ...
PearsonArtPhoto

Огромное спасибо!!! Я искал повсюду это:String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Аарон Клап

1
@ Шуб, я так не думаю.
Константин Буров

3
Добавьте BuildConfig.VERSION_NAME к своему ответу для фальшивых подписей.
Jobbert

102

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

  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или чего-то в этом роде.


14
небольшое примечание к 1 .: это работает, но я думаю, что это обескураживает, так как я получаю предупреждение, говорящее мнеThe android:versionName cannot be a resource url, it must be a literal string
Griddo

1
Что я сделал, так это оставил имя версии манифеста нетронутым (но обновлял его при каждом новом выпуске) и использовал string.xml для хранения значения, которое я буду использовать в приложении.
numediaweb

1
Ибо AndroidStudioманифест versionNameпереопределяется одним набором в build.gradleфайле
Adrian C.

67

Вы можете использовать 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>


3
Это лучше, чем программный стиль.
Нейротрансмиттер

2
Прекрасное решение. Благодаря тонну.
Самик Bandyopadhyay

2
Я использую последние и до сих пор работает для меня. Я использую эту и несколько других переменных, как это. @ k2col какую ошибку ты получаешь при компиляции? Просьба опубликовать ваш код gradle
Арун Шанкар

3
Это следует считать лучшим ответом.
ЭЧАЯ

15

Я решил эту проблему, расширив класс 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>

К сожалению. Должно быть, я думал о предпочтениях XML на основе другого комментария.
Seastland

Тем не менее, я все равно просто скопирую и вставлю его ответ.
Mathijs Segers

13

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

Извините, у меня нет решений на основе XML.


7
BuildConfig.VERSION_NAME уже является строкой, нет необходимости вызывать toString () для нее.
Макотосан

Привычка. Достаточно справедливо
Mullazman

Есть случаи, когда вызов этого в вашем проекте может получить результат, отличный от ожидаемого. Например, если вы используете подмодуль Android в своем проекте и вызываете его из кода подмодуля, он будет ссылаться на конфигурацию сборки подмодуля, которая может иметь другую версию. Или, если вы вызываете его из кода вашего проекта, вы можете по ошибке сослаться на конфигурацию вашего подмодуля и получить тот же результат. Просто будьте осторожны и дважды проверьте, что вы ссылаетесь на соответствующий пакет конфигурации сборки.
MikeL

Попробуйте использовать это руководство: medium.com/@manas/…
CrandellWS

Разница в том, что BuilConfig предоставляется Gradle, тогда как получение его во время выполнения осуществляется PackageManager (OS)
Ишаан Кумар

12

Если вы используете 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к названию версии, как описано в связанной статье, в режиме отладки.


1
лучший ответ когда-либо !!
Рахил Хасан

2

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

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


Я боялся этого ... Спасибо за помощь!
PearsonArtPhoto

2
мы можем использовать это. пожалуйста, проверьте мой ответ. Я использую его в своем приложении
Арун Шанкар

1

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

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

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


-3

Поздно к игре, но вы можете сделать это без @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"
     />

11
Я использую как это:, <Preference android:title="Version" android:summary="?android:attr/versionName" ></Preference>но показать как. ?16843292Что не так?
Suge

Я не уверен, но думаю, что это для более поздних API?
Mafro34

@PearsonArtPhoto на самом деле, где это говорит?
Mafro34

не работает; смешной номер вывел следующую который @Suge указано выше
ЭЧАЯ

вообще не работает и возвращает случайное значение, как было ранее опубликовано
A_rmas
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.