Comment obtenir le numéro de la version du manifeste à partir des variables XML (mise en page) de l'application?

184

Je voudrais avoir un moyen de référencer le numéro de version du manifeste du projet dans la partie principale du code. Ce que j'ai fait jusqu'à présent, c'est de lier le numéro de version dans un fichier XML String au manifeste (@ string / Version). Ce que je voudrais faire, c'est le faire dans l'autre sens, lier une variable XML chaîne à la version du manifeste. La raison? Je voudrais seulement avoir à changer le numéro de version dans un seul endroit, le fichier manifeste. Y a-t-il un moyen de faire ça? Merci!

PearsonArtPhoto
la source
17
Ce n'est PAS un doublon. La question en question demande comment faire la même chose dans CODE, je demande en XML. Deux constructions très différentes dans la programmation Android ...
PearsonArtPhoto

Réponses:

367

Je crois que cela a déjà été répondu ici .

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

OU

int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
Konstantin Burov
la source
8
Presque, mais pas tout à fait ... Ce que j'aimerais faire, c'est le référencer à un code XML, mais il semble que ce ne soit peut-être pas possible, alors ...
PearsonArtPhoto
Merci beaucoup!!! J'ai cherché partout pour ceci:String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Aaron Klap
1
@Shubh je ne pense pas.
Konstantin Burov
3
Ajoutez BuildConfig.VERSION_NAME à votre réponse pour les fokes gradle.
jobbert
102

Il n'existe pas de moyen de sortir directement la version, mais deux solutions de contournement peuvent être effectuées.

  1. La version peut être stockée dans une chaîne de ressources et placée dans le manifeste par:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.somepackage"
         android:versionName="@string/version" android:versionCode="20">
  2. On pourrait créer une vue personnalisée et la placer dans le XML. La vue utiliserait ceci pour attribuer le nom:

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

L'une ou l'autre de ces solutions permettrait de placer le nom de la version en XML. Malheureusement, il n'y a pas de solution simple et agréable, comme android.R.string.versionou quelque chose comme ça.

PearsonArtPhoto
la source
14
une petite note à 1 .: ça marche mais je pense que c'est déconseillé puisque je reçois un avertissement me disantThe android:versionName cannot be a resource url, it must be a literal string
Griddo
1
Ce que j'ai fait, c'est de laisser le nom de la version du manifeste intact (mais de le mettre à jour à chaque nouvelle version) et d'utiliser le string.xml pour stocker la valeur que j'utiliserai dans l'application.
numediaweb
1
Car AndroidStudio, le manifeste versionNameest remplacé par celui défini dans le build.gradlefichier
Adrian C.
67

Vous pouvez utiliser les versionNameressources XML in, telles que les présentations d'activités. Créez d'abord une ressource de chaîne dans le app/build.gradleavec l'extrait de code suivant dans le androidnœud:

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

Ainsi, tout build.gradlele contenu du fichier peut ressembler à ceci:

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

Ensuite, vous pouvez utiliser @string/versionNamedans le XML. Android Studio le marquera en rouge, mais l'application se compilera sans problème. Par exemple, cela peut être utilisé comme ceci dans 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>
Arun Shankar
la source
3
@DenisGL michiganlabs.com/…
Arun Shankar
3
C'est mieux que le style programmatique.
Neurotransmetteur
2
Magnifique solution. Merci beaucoup.
Samik Bandyopadhyay
2
J'utilise la dernière et fonctionne toujours pour moi. J'utilise ceci et plusieurs autres variables comme celle-ci. @ k2col quelle erreur obtenez-vous lors de la compilation? Pls post ur gradle code
Arun Shankar
3
Cela devrait être considéré comme la meilleure réponse.
pepan
15

J'ai résolu ce problème en étendant la classe 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);
        }
    }
}

Puis dans mes préférences XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.android.VersionPreference android:title="Version" />
</PreferenceScreen>
seastland
la source
Oups. J'ai dû penser à Preference XML sur la base d'un autre commentaire.
seastland
Néanmoins, je vais de toute façon copier et coller sa réponse.
Mathijs Segers
13

J'utilise BuildConfig.VERSION_NAME.toString();. Quelle est la différence entre cela et l'obtenir à partir du packageManager?

Aucune solution basée sur XML n'a fonctionné pour moi, désolé.

Mullazman
la source
7
BuildConfig.VERSION_NAME est déjà une chaîne, pas besoin d'appeler toString () dessus.
Makotosan le
Habitude. Juste assez
Mullazman
Il y a des cas où l'appel de ceci dans votre projet peut obtenir un résultat différent de ce que vous attendez. Par exemple, si vous utilisez un sous-module Android dans votre projet et que vous l'appelez à partir du code du sous-module, il fera référence à la configuration de construction du sous-module qui peut avoir une version différente. Ou si vous l'appelez à partir du code de votre projet, vous pouvez faire référence par erreur pour construire la configuration de votre sous-module et obtenir le même résultat. Soyez juste prudent et vérifiez que vous faites référence à un package approprié de la configuration de construction.
MikeL
Essayez d'utiliser ce guide: medium.com/@manas
CrandellWS
la différence est que BuilConfig est fourni par Gradle alors que l'obtenir au moment de l'exécution est par PackageManager (OS)
Ishaan Kumar
12

SI vous utilisez Gradle, vous pouvez utiliser le fichier build.gradle pour ajouter par programme de la valeur aux ressources xml au moment de la compilation.

Exemple de code extrait de: 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}"
    }
}

maintenant utiliser @string/app_versionselon les besoins dans XML

Il s'ajoutera .debugau nom de la version comme décrit dans l'article lié en mode débogage.

CrandellWS
la source
1
meilleure réponse jamais !!
Raheel Hasan
2

Vous ne pouvez pas l'utiliser à partir du XML.

Vous devez étendre le widget que vous utilisez dans le XML et ajouter la logique pour définir le texte en utilisant ce qui est mentionné dans la réponse de Konstantin Burov.

Macarse
la source
J'avais peur de ça ... Merci pour l'aide!
PearsonArtPhoto
2
nous pouvons l'utiliser. Veuillez vérifier ma réponse. Je l'utilise dans mon application
Arun Shankar
1

La solution la plus simple est d'utiliser BuildConfig.

J'utilise BuildConfig.VERSION_NAMEdans mon application.

Vous pouvez également utiliser BuildConfig.VERSION_CODEpour obtenir le code de version.

cHAuHaN
la source
-3

En retard dans le jeu, mais vous pouvez le faire sans @string/xyzen utilisant?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"
     />
ddrscott
la source
11
J'utilise comme ceci :, <Preference android:title="Version" android:summary="?android:attr/versionName" ></Preference>mais montrer comme ?16843292. Qu'est-ce qui ne va pas?
Suge du
Je ne suis pas sûr mais je pense que c'est pour les API ultérieures?
Mafro34
@PearsonArtPhoto en fait, où est-ce que ça dit ça?
Mafro34
ne fonctionne pas; renvoie un nombre amusant que @Suge a souligné ci
pepan
ne fonctionne pas du tout et renvoie une valeur aléatoire comme précédemment publié
A_rmas