提问



我需要弄清楚如何为我的Android应用程序获取或制作内部版本号。我需要在UI中显示内部版本号。


我必须对AndroidManifest.xml做些什么吗?

最佳参考


使用:


try {
    PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
    String version = pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}


您可以使用此方法获取版本代码


int verCode = pInfo.versionCode;

其它参考1


如果您正在使用Gradle插件/Android Studio,从版本0.7.0开始,版本代码和版本名称在BuildConfig中静态可用。确保导入应用程序包 ,而不是另一个BuildConfig:[71]


import com.yourpackage.BuildConfig;
...
int versionCode = BuildConfig.VERSION_CODE;
String versionName = BuildConfig.VERSION_NAME;


不需要Context对象!


另外,请确保在build.gradle文件中指定它们而不是AndroidManifest.xml


defaultConfig {
    versionCode 1
    versionName "1.0"
}

其它参考2


如果您只想要版本名称,则稍微缩短版本。


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

其它参考3


使用Gradle和BuildConfig



从BuildConfig获取VERSION_NAME



BuildConfig.VERSION_NAME


是的,现在这很容易。


是否为VERSION_NAME返回空字符串?



如果您为BuildConfig.VERSION_NAME获取空字符串,请继续阅读。


我一直为BuildConfig.VERSION_NAME得到一个空字符串,因为我没有在我的成绩构建文件中设置versionName(我从ANT迁移到Gradle)。所以,这里是确保你重新设置你的指示VERSION_NAME通过Gradle。


的build.gradle


def versionMajor = 3
def versionMinor = 0
def versionPatch = 0
def versionBuild = 0 // bump for dogfood builds, public betas, etc.

android {

  defaultConfig {
    versionCode versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild

    versionName "${versionMajor}.${versionMinor}.${versionPatch}"
  }

}


注意:这是来自杰出的杰克沃顿。 [72]


AndroidManifest.xml

中删除versionNameversionCode

由于您现在已经在build.gradle文件中设置versionNameversionCode,因此如果它们在那里,您也可以从AndroidManifest.xml文件中删除它们。

其它参考4


您需要两个部分:
安卓的versionCode
安卓的versionName


versionCode是一个数字,您提交给市场的应用程序的每个版本都需要比最后一个更高的数字。


VersionName是一个字符串,可以是您想要的任何字符串。您可以在此处将应用定义为1.0或2.5或2 Alpha EXTREME!管他呢。


例:



要在代码中访问它,请执行以下操作:


PackageManager manager = this.getPackageManager();
PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);
Toast.makeText(this,
     "PackageName = " + info.packageName + "\nVersionCode = "
       + info.versionCode + "\nVersionName = "
       + info.versionName + "\nPermissions = " + info.permissions, Toast.LENGTH_SHORT).show();

其它参考5


BuildConfig.VERSION_NAME //version name from your build file
BuildConfig.VERSION_CODE //version code from your build file


我不认为有必要从包管理器那里得到它

其它参考6


这是一个清除解决方案,基于scottyab的解决方案(由Xavi编辑)。它显示了如何首先获取上下文,如果它不是由您的方法提供的。此外,它使用多行而不是每行调用多个方法。这使您在调试应用程序时更容易。


Context context = getApplicationContext(); // or activity.getApplicationContext()
PackageManager packageManager = context.getPackageManager();
String packageName = context.getPackageName();

String myVersionName = "not available"; // initialize String

try {
    myVersionName = packageManager.getPackageInfo(packageName, 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}


现在您已在String myVersionName中收到版本名称,您可以将其设置为TextView或您喜欢的任何内容。


// set version name to a TextView
TextView tvVersionName = (TextView) findViewById(R.id.tv_versionName);
tvVersionName.setText(myVersionName);

其它参考7


如果你正在使用PhoneGap,那么创建一个自定义PhoneGap插件:


在app的包中创建一个新类:


package com.Demo; //replace with your package name

import org.json.JSONArray;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;

import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
import com.phonegap.api.PluginResult.Status;

public class PackageManagerPlugin extends Plugin {

    public final String ACTION_GET_VERSION_NAME = "GetVersionName";

    @Override
    public PluginResult execute(String action, JSONArray args, String callbackId) {
        PluginResult result = new PluginResult(Status.INVALID_ACTION);
        PackageManager packageManager = this.ctx.getPackageManager();

        if(action.equals(ACTION_GET_VERSION_NAME)) {
            try {
                PackageInfo packageInfo = packageManager.getPackageInfo(
                                              this.ctx.getPackageName(), 0);
                result = new PluginResult(Status.OK, packageInfo.versionName);
            }
            catch (NameNotFoundException nnfe) {
                result = new PluginResult(Status.ERROR, nnfe.getMessage());
            }
        }

        return result;
    }
}


在plugins.xml中,添加以下行:


<plugin name="PackageManagerPlugin" value="com.Demo.PackageManagerPlugin" />


在您的deviceready事件中,添加以下代码:[73]


var PackageManagerPlugin = function() {

};
PackageManagerPlugin.prototype.getVersionName = function(successCallback, failureCallback) {
    return PhoneGap.exec(successCallback, failureCallback, 'PackageManagerPlugin', 'GetVersionName', []);
};
PhoneGap.addConstructor(function() {
    PhoneGap.addPlugin('packageManager', new PackageManagerPlugin());
});


然后,您可以通过执行以下操作获取versionName属性:


window.plugins.packageManager.getVersionName(
    function(versionName) {
        //do something with versionName
    },
    function(errorMessage) {
        //do something with errorMessage
    }
);


来自这里和这里。[74] [75]

其它参考8


一个非常简单的方法是:


private String appVersion = BuildConfig.VERSION_NAME;

其它参考9


始终使用try catch块执行此操作:


String versionName = "Version not found";

try {
    versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
    Log.i(TAG, "Version Name: " + versionName);
} catch (NameNotFoundException e) {
    // TODO Auto-generated catch block
    Log.e(TAG, "Exception Version Name: " + e.getLocalizedMessage());
}

其它参考10


以下是获取版本代码的方法:


public String getAppVersion() {
    String versionCode = "1.0";
    try {
        versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
    } catch (PackageManager.NameNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return versionCode;
}

其它参考11


对于xamarin用户,请使用此代码获取版本名称和代码


1)版本名称:


public string getVersionName(){
      return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionName;
}


2)版本代码:


public string getVersionCode(){
      return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionCode;
}

其它参考12


我通过使用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);
        }
    }
}

其它参考13


如果要在xml上使用它,请在gradle文件中添加以下行:


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


然后在你的xml上使用它,如下所示:


<TextView
        android:gravity="center_horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/versionName" />

其它参考14


对于应用程序的UI,不需要BuildConfig信息的人想要使用这些信息来设置CI作业配置或其他人,比如我。


只要您成功构建项目,就会在项目目录下有一个自动生成的文件BuildConfig.java。


{WORKSPACE}/建立/生成/源极/buildConfig/{调试|释放}/{PACKAGE}/BuildConfig.java


/**
* Automatically generated file. DO NOT MODIFY
*/
package com.XXX.Project;

public final class BuildConfig {
    public static final boolean DEBUG = Boolean.parseBoolean("true");
    public static final String APPLICATION_ID = "com.XXX.Project";
    public static final String BUILD_TYPE = "debug";
    public static final String FLAVOR = "";
    public static final int VERSION_CODE = 1;
    public static final String VERSION_NAME = "1.0.0";
}


通过python脚本或其他工具拆分您需要的信息。这是一个例子:


import subprocess
#find your BuildConfig.java
_BuildConfig = subprocess.check_output('find {WORKSPACE} -name BuildConfig.java', shell=True).rstrip()
#get the version name
_Android_version = subprocess.check_output('grep -n "VERSION_NAME" '+_BuildConfig, shell=True).split('"')[1]
print('Android version :’+_Android_version)


请原谅我有限的英语能力,但希望这有帮助。

其它参考15


上面提到了这段代码,但是这里再次包括在内。你需要一个try/catch块,因为它可能抛出一个NameNotFoundException。


try {
   String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {e.printStackTrace();}


我希望这能为后来的人简化事情。 :)

其它参考16


有一些方法可以通过编程方式获得versionCodeversionName



  1. PackageManager获取版本。这是大多数情况下的最佳方式。





try {
    String versionName = packageManager.getPackageInfo(packageName, 0).versionName;
    int versionCode = packageManager.getPackageInfo(packageName, 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}



  1. 从生成BuildConfig.java中获取它。但请注意,如果您将在库中访问此值,它将返回库版本,而不是使用此库的应用程序。所以仅在非库项目中使用!





String versionName = BuildConfig.VERSION_NAME;
int versionCode = BuildConfig.VERSION_CODE;





除了在库项目中使用第二种方式外,还有一些细节。在新的Android gradle插件(3.0.0+)中删除了一些功能。所以,就目前而言,即设置不同版本的不同版本不正确。[76]


方式不正确:


applicationVariants.all { variant ->
    println('variantApp: ' + variant.getName())

    def versionCode = {SOME_GENERATED_VALUE_IE_TIMESTAMP}
    def versionName = {SOME_GENERATED_VALUE_IE_TIMESTAMP}

    variant.mergedFlavor.versionCode = versionCode
    variant.mergedFlavor.versionName = versionName
}


上面的代码将正确设置BuildConfig中的值,但是如果您没有在default配置中设置版本,则会从PackageManager接收0null。所以你的应用程序将在设备上有0版本代码。


有一个解决方法 - 手动设置输出apk文件的版本:


applicationVariants.all { variant ->
    println('variantApp: ' + variant.getName())

    def versionCode = {SOME_GENERATED_VALUE_IE_TIMESTAMP}
    def versionName = {SOME_GENERATED_VALUE_IE_TIMESTAMP}

    variant.outputs.all { output ->
        output.versionCodeOverride = versionCode
        output.versionNameOverride = versionName
    }
}

其它参考17


 package com.sqisland.android.versionview;

import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView textViewversionName = (TextView) findViewById(R.id.text);

    try {
        PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
        textViewversionName.setText(packageInfo.versionName);

    }
    catch (PackageManager.NameNotFoundException e) {

    }

  }
}

其它参考18


第一:


import android.content.pm.PackageManager.NameNotFoundException;


然后使用这个:


PackageInfo pInfo = null;
try {
     pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException e) {
     e.printStackTrace();
            }
String versionName = pInfo.versionName;

其它参考19


private String GetAppVersion(){
        try {
            PackageInfo _info = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
            return _info.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return "";
        }
    }

    private int GetVersionCode(){
        try {
            PackageInfo _info = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
            return _info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return -1;
        }
    }

其它参考20


试试这个:


try 
{
    device_version =  getPackageManager().getPackageInfo("com.google.android.gms", 0).versionName;
}
catch (PackageManager.NameNotFoundException e)
{
    e.printStackTrace();
}

其它参考21


Activity文件中


final TextView text_1 = (TextView) findViewById(R.id.text_1);

String version= BuildConfig.VERSION_NAME;
int code = BuildConfig.VERSION_CODE;
text_1.setText("version Name :   "+version+ "Version Code : "+code);


我希望它会帮助你......!

其它参考22


内部片段使用示例。


        import android.content.pm.PackageManager;
        .......

        private String VersionName;
        private String VersionCode;
        .......


        Context context = getActivity().getApplicationContext();

        /*Getting Application Version Name and Code*/
        try
        {

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

             /*I find usefull to convert vervion code into String, so it's ready for TextViev/server side checks*/ 

             VersionCode = Integer.toString(context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode);
        } catch (PackageManager.NameNotFoundException e)
        {
             e.printStackTrace();
        }

// DO SOMETHING USEFULL WITH THAT

其它参考23


  PackageInfo pinfo = null;
    try {
        pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    int versionNumber = pinfo.versionCode;
    String versionName = pinfo.versionName;

其它参考24


使用BuildConfig类


String versionName = BuildConfig.VERSION_NAME;
int versionCode = BuildConfig.VERSION_CODE;


build.gradle(APP)


 defaultConfig {
    applicationId "com.myapp"
    minSdkVersion 19
    targetSdkVersion 27
    versionCode 17
    versionName "1.0"
   }

其它参考25


try {
        PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
        String versionName = packageInfo.versionName;
        int versionCode = packageInfo.versionCode;
        //binding.tvVersionCode.setText("v" + packageInfo.versionName);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }