Jak uzyskać numer wersji manifestu ze zmiennych XML aplikacji (układu)?


184

Chciałbym mieć sposób na odniesienie się do numeru wersji manifestu projektu w głównej części kodu. Do tej pory robiłem, aby połączyć numer wersji w pliku XML typu String z manifestem (@ string / Version). Chciałbym to zrobić na odwrót, połączyć zmienną łańcuchową XML z wersją w manifeście. Powód? Chciałbym tylko zmienić numer wersji w jednym miejscu, pliku manifestu. Czy jest na to sposób? Dzięki!


17
To NIE jest duplikat. Pytanie to dotyczy tego, jak zrobić to samo w KODIE, pytam w XML. Dwie bardzo różne konstrukcje w programowaniu na Androida ...
PearsonArtPhoto

Odpowiedzi:


367

Uważam, że tutaj już udzielono odpowiedzi .

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

LUB

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

8
Prawie, ale niezupełnie ... Chciałbym odnieść się do kodu XML, ale wygląda na to, że może to nie być możliwe, więc ...
PearsonArtPhoto

Dziękuję bardzo!!! Szukałem tego wszędzie:String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Aaron Klap,

1
@Shubh Nie sądzę.
Konstantin Burov

3
Dodaj BuildConfig.VERSION_NAME do swojej odpowiedzi na stopnie procentowe.
jobbert

102

Nie ma sposobu, aby bezpośrednio wydać wersję, ale istnieją dwa sposoby obejścia tego problemu.

  1. Wersja może być przechowywana w łańcuchu zasobów i umieszczana w manifeście przez:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.somepackage"
         android:versionName="@string/version" android:versionCode="20">
    
  2. Można utworzyć niestandardowy widok i umieścić go w pliku XML. Widok użyłby tego do przypisania nazwy:

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

Każde z tych rozwiązań pozwoliłoby na umieszczenie nazwy wersji w XML. Niestety nie ma przyjemnego, prostego rozwiązania, android.R.string.versionani czegoś takiego.


14
trochę uwaga do 1 .: to działa, ale myślę, że to zniechęca, ponieważ dostaję ostrzeżenie mówi miThe android:versionName cannot be a resource url, it must be a literal string
Griddo

1
To, co zrobiłem, to pozostawienie nazwy wersji manifestu nietkniętej (ale zaktualizuj ją za każdym razem, gdy nowa wersja) i użyj pliku string.xml do przechowywania wartości, której będę używać w aplikacji.
numediaweb

1
Bo AndroidStudiomanifest versionNamejest nadpisywany przez ten ustawiony w build.gradlepliku
Adrian C.

66

Możesz użyć versionNamezasobów XML, takich jak układy działań. Najpierw utwórz zasób ciągu app/build.gradlez następującym fragmentem kodu w androidwęźle:

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

Cała build.gradlezawartość pliku może więc wyglądać następująco:

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'
}

Następnie możesz użyć @string/versionNamew XML. Android Studio oznaczy go na czerwono, ale aplikacja będzie się kompilować bez problemów. Na przykład można to wykorzystać w następujący sposób 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
To jest lepsze niż styl programowy.
Neurotransmitter

2
Cudowne rozwiązanie. Wielkie dzięki.
Samik Bandyopadhyay

2
Korzystam z najnowszych i nadal działa dla mnie. Używam tej i kilku innych zmiennych takich jak ta. @ k2col jaki błąd pojawia się podczas kompilacji? Proszę o przesłanie kodu pocztowego
Arun Shankar,

3
To należy uznać za najlepszą odpowiedź.
pepan

15

Rozwiązałem ten problem, rozszerzając klasę preferencji.

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);
        }
    }
}

Następnie w moich preferencjach XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.android.VersionPreference android:title="Version" />
</PreferenceScreen>

Ups Musiałem myśleć o Preferencji XML na podstawie innego komentarza.
seastland

Niemniej jednak skopiuję i wkleję jego odpowiedź.
Mathijs Segers,

13

Używam BuildConfig.VERSION_NAME.toString();. Jaka jest różnica między tym a uzyskaniem go z menedżera pakietów?

Niestety, żadne rozwiązania oparte na XML nie działały dla mnie.


7
BuildConfig.VERSION_NAME jest już ciągiem, nie trzeba na nim wywoływać funkcjiString ().
Makotosan,

Nawyk. W
porządku

Zdarzają się przypadki, gdy wywołanie tego w twoim projekcie może uzyskać inny wynik niż oczekiwany. Na przykład, jeśli korzystasz z podmodułu Androida w swoim projekcie i wywołujesz go z kodu podmodułu, będzie on odnosił się do budowania konfiguracji podmodułu, który może mieć inną wersję. Lub jeśli wywołasz go z kodu swojego projektu, możesz przez pomyłkę odwołać się do zbudowania konfiguracji swojego podmodułu i uzyskać ten sam wynik. Bądź ostrożny i dokładnie sprawdź, czy odwołujesz się do odpowiedniego pakietu konfiguracji kompilacji.
MikeL,

Spróbuj skorzystać z tego przewodnika: medium.com/@manas/…
CrandellWS,

Różnica polega na tym, że BuilConfig jest dostarczany przez Gradle, podczas gdy pobieranie w czasie wykonywania jest wykonywane przez PackageManager (OS)
Ishaan Kumar

12

JEŻELI używasz Gradle, możesz użyć pliku build.gradle, aby programowo zwiększyć wartość zasobów xml w czasie kompilacji.

Przykładowy kod wyodrębniony z: 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}"
    }
}

teraz używaj @string/app_versionw razie potrzeby w XML

Zostanie dodany .debugdo nazwy wersji zgodnie z opisem w połączonym artykule w trybie debugowania.


1
najlepsza odpowiedź w historii !!
Raheel Hasan

2

Nie możesz go użyć z XML.

Musisz rozszerzyć widżet, którego używasz w XML i dodać logikę, aby ustawić tekst przy użyciu tego, co wspomniano w odpowiedzi Konstantina Burowa.


Bałam się tego ... Dzięki za pomoc!
PearsonArtPhoto

2
możemy go użyć. proszę sprawdź moją odpowiedź. Używam go w mojej aplikacji
Arun Shankar,

1

Najłatwiejszym rozwiązaniem jest użycie BuildConfig.

Używam BuildConfig.VERSION_NAMEw mojej aplikacji.

Możesz także użyć, BuildConfig.VERSION_CODEaby uzyskać kod wersji.


-3

Późno do gry, ale możesz to zrobić bez @string/xyzużycia?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
Używam w ten <Preference android:title="Version" android:summary="?android:attr/versionName" ></Preference>sposób ?16843292:, ale pokaż jako .Co jest nie tak?
Suge

Nie jestem pewien, ale czy to dotyczy późniejszych interfejsów API?
Mafro34,

@ PearsonArtPhoto właściwie, gdzie to mówi?
Mafro34,

nie działa; zwraca śmieszny numer, który @Suge wskazał powyżej
pepan

w ogóle nie działa i zwraca losową wartość, jak wcześniej opublikowano
A_rmas,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.