196

I would like to have a way to reference the project's manifest version number in the main part of the code. What I have been doing up until now is to link the version number in a String XML file to the manifest (@string/Version). What I would like to do is to do it the other way around, link a string XML variable to the version in the manifest. The reason? I'd like to only have to change the version number in one location, the manifest file. Is there any way to do this? Thanks!

1
  • 1
    If you're looking for how to do this in Java or Kotlin code rather than in XML, please see this other question.
    – Ryan M
    Commented Feb 25, 2023 at 3:50

8 Answers 8

104

There is not a way to directly get the version out, but there are two work-arounds that could be done.

  1. The version could be stored in a resource string, and placed into the manifest by:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.somepackage"
         android:versionName="@string/version" android:versionCode="20">
    
  2. One could create a custom view, and place it into the XML. The view would use this to assign the name:

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

Either of these solutions would allow for placing the version name in XML. Unfortunately there isn't a nice simple solution, like android.R.string.version or something like that.

3
  • 16
    a little note to 1.: it's working but I think it's discouraged since I get a warning telling me The android:versionName cannot be a resource url, it must be a literal string
    – Gerrit-K
    Commented Apr 23, 2013 at 10:44
  • 1
    What I did is leave the manifest version name untouched (but update it whenever a new release) and use the string.xml to store the value that I'll be using across the app.
    – numediaweb
    Commented Sep 16, 2013 at 23:39
  • 1
    For AndroidStudio, the manifest versionName is override by the one set in build.gradle file
    – Adrian C.
    Commented Mar 22, 2016 at 11:32
83

You can use the versionName in XML resources, such as activity layouts. First create a string resource in the app/build.gradle with the following snippet in the android node:

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

So the whole build.gradle file contents may look like this:

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

Then you can use @string/versionName in the XML. Android Studio will mark it red, but the app will compile without issues. For example, this may be used like this in 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>
15
  • 3
    @DenisGL michiganlabs.com/… Commented May 6, 2016 at 18:24
  • 3
    This is better, than programmatic style. Commented May 10, 2016 at 21:28
  • 2
    Wonderful solution. Thanks a ton. Commented Aug 7, 2016 at 5:51
  • 2
    I am using the latest and still works for me. I use this and several other variables like this. @k2col what error do u get while compiling? Pls post ur gradle code Commented Nov 23, 2016 at 15:49
  • 4
    This should be considered the best answer.
    – pepan
    Commented Apr 3, 2017 at 21:29
17

IF you are using Gradle you can use the build.gradle file to programmatically add value to the xml resources at compile time.

Example Code extracted from: 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}"
    }
}

now use @string/app_version as needed in XML

It will add .debug to the version name as describe in the linked article when in debug mode.

1
  • 1
    best answer ever!! Commented Jan 14, 2019 at 1:25
15

I solved this issue by extending the Preference class.

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

Then in my preferences XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.android.VersionPreference android:title="Version" />
</PreferenceScreen>
2
  • Oops. I must have been thinking Preference XML based on another comment.
    – seastland
    Commented Nov 24, 2013 at 18:44
  • Nevertheless, I will just copy and paste his answer anyway. Commented Jun 11, 2015 at 8:24
15

I use BuildConfig.VERSION_NAME.toString();. What's the difference between that and getting it from the packageManager?

No XML based solutions have worked for me, sorry.

5
  • 8
    BuildConfig.VERSION_NAME is already a string, no need to call toString() on it.
    – Makotosan
    Commented Apr 4, 2016 at 19:52
  • Habit. Fair enough
    – Mullazman
    Commented Apr 6, 2016 at 9:12
  • There are cases when calling this in your project may get different result from what you would expect. For example if you use an android submodule in your project and you call it from the code of the submodule it will reference to build config of the submodule which may have different version. Or if you call it from the code of your project you may reference by mistake to build config of your submodule and get the same result. Just be careful and double check that you reference to a proper package of the build config.
    – MikeL
    Commented Oct 5, 2016 at 19:55
  • Try using this guide: medium.com/@manas/…
    – CrandellWS
    Commented Aug 19, 2018 at 2:30
  • difference is BuilConfig is provided by Gradle whereas getting it at runtime is by PackageManager (OS) Commented Jan 24, 2020 at 17:58
3

You can't use it from the XML.

You need to extend the widget you are using in the XML and add the logic to set the text using what's mentioned on Konstantin Burov's answer.

2
  • I was afraid of that... Thanks for the help! Commented Dec 17, 2010 at 21:52
  • 2
    we can use it. please check my answer. I am using it in my app Commented Apr 7, 2016 at 6:48
1

Easiest solution is to use BuildConfig.

I use BuildConfig.VERSION_NAME in my application.

You can also use BuildConfig.VERSION_CODE to get version code.

-1

Late to the game, but you can do it without @string/xyz by using ?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"
     />
6
  • 11
    I use like this:<Preference android:title="Version" android:summary="?android:attr/versionName" ></Preference>, but show as ?16843292.What's wrong?
    – Suge
    Commented Sep 26, 2013 at 9:17
  • I'm not sure but think this is for later API's?
    – Mafro34
    Commented Dec 10, 2013 at 13:59
  • @PearsonArtPhoto actually, where does it say that?
    – Mafro34
    Commented Dec 14, 2013 at 22:21
  • doesn't work; returns funny number which @Suge pointed out above
    – pepan
    Commented Apr 3, 2017 at 21:34
  • doesnot work at all and returns random value as previously posted
    – A_rmas
    Commented Apr 4, 2017 at 8:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.