我如何从AndroidManifest.xml文件下载后,不安装它,以编程方式获得我的apk的版本代码或版本名。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="xxx.xx.xxx"
    android:versionCode="1"
    android:versionName="1.1" >

例如,我想检查我的IIS服务上是否上传了新版本,在设备上安装后,如果不是新版本,我就不想安装它。


当前回答

对于升级场景,另一种方法可能是使用web服务来交付当前版本号并进行检查,而不是下载整个apk来检查其版本。它可以节省一些带宽,性能更好(如果大多数时候不需要整个apk,那么下载速度比apk快得多),实现起来也更简单。

以最简单的形式,你可以在你的服务器上有一个简单的文本文件…http://some-place.com/current-app-version.txt

在那个文本文件里面有

3.1.4

然后下载该文件并检查当前安装的版本。

构建一个更高级的解决方案是实现一个适当的web服务,并在启动时调用api,该api可以返回一些json,即http://api.some-place.com/versionCheck:

{
    "current_version": "3.1.4"
}

其他回答

    EditText ET1 = (EditText) findViewById(R.id.editText1);

    PackageInfo pinfo;
    try {
        pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
        String versionName = pinfo.versionName;
        ET1.setText(versionName);
        //ET2.setText(versionNumber);
    } catch (NameNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
aapt dump badging test.apk | grep "versionName" | sed -e "s/.*versionName='//" -e "s/' .*//"

这将通过只返回版本号作为结果来回答问题。 然而……

如前所述,目标应该是在尝试下载或安装它之前,找出服务器上的apk是否比安装的apk更新。最简单的方法是在服务器上托管的apk的文件名中包含版本号,例如myapp_1.01.apk

为了进行比较,你需要建立已经安装的应用程序的名称和版本号(如果已经安装)。如果apapt二进制文件和busybox还没有包含在rom中,您将需要一个根设备或安装它们的方法。

这个脚本将从服务器获取应用程序列表,并与任何已安装的应用程序进行比较。结果是一个标记为升级/安装的列表。

#/system/bin/sh
SERVER_LIST=$(wget -qO- "http://demo.server.com/apk/" | grep 'href' | grep '\.apk' | sed 's/.*href="//' | \
              sed 's/".*//' | grep -v '\/' | sed -E "s/%/\\\\x/g" | sed -e "s/x20/ /g" -e "s/\\\\//g")
LOCAL_LIST=$(for APP in $(pm list packages -f | sed -e 's/package://' -e 's/=.*//' | sort -u); do \
              INFO=$(echo -n $(aapt dump badging $APP | grep -e 'package: name=' -e 'application: label=')) 2>/dev/null; \
              PACKAGE=$(echo $INFO | sed "s/.*package: name='//" | sed "s/'.*$//"); \
              LABEL=$(echo $INFO | sed "s/.*application: label='//" | sed "s/'.*$//"); if [ -z "$LABEL" ]; then LABEL="$PACKAGE"; fi; \
              VERSION=$(echo $INFO | sed -e "s/.*versionName='//" -e "s/' .*//"); \
              NAME=$LABEL"_"$VERSION".apk"; echo "$NAME"; \
              done;)
OFS=$IFS; IFS=$'\t\n'
for REMOTE in $SERVER_LIST; do
    INSTALLED=0
    REMOTE_NAME=$(echo $REMOTE | sed 's/_.*//'); REMOTE_VER=$(echo $REMOTE | sed 's/^[^_]*_//g' | sed 's/[^0-9]*//g')
    for LOCAL in $LOCAL_LIST; do
        LOCAL_NAME=$(echo $LOCAL | sed 's/_.*//'); LOCAL_VER=$(echo $LOCAL | sed 's/^[^_]*_//g' | sed 's/[^0-9]*//g')
        if [ "$REMOTE_NAME" == "$LOCAL_NAME" ]; then INSTALLED=1; fi
        if [ "$REMOTE_NAME" == "$LOCAL_NAME" ] && [ ! "$REMOTE_VER" == "$LOCAL_VER" ]; then echo remote=$REMOTE ver=$REMOTE_VER local=$LOCAL ver=$LOCAL_VER; fi
    done
    if [ "$INSTALLED" == "0" ]; then echo "$REMOTE"; fi
done
IFS=$OFS

有人问我怎么不用apapt就能做到。 也可以用apktool和一些脚本来提取apk信息。这种方法在android上较慢且不简单,但只要你有apktool设置,就可以在windows/mac或linux上工作。

#!/bin/sh
APK=/path/to/your.apk
TMPDIR=/tmp/apktool
rm -f -R $TMPDIR
apktool d -q -f -s --force-manifest -o $TMPDIR $APK
APK=$(basename $APK)
VERSION=$(cat $TMPDIR/apktool.yml | grep "versionName" | sed -e "s/versionName: //")
LABEL=$(cat $TMPDIR/res/values/strings.xml | grep 'string name="title"' | sed -e 's/.*">//' -e 's/<.*//')
rm -f -R $TMPDIR
echo ${LABEL}_$(echo $V).apk

还可以考虑在服务器上设置一个删除文件夹。上传apks到它和一个cron任务重命名和移动他们到你的更新文件夹。

#!/bin/sh
# Drop Folder script for renaming APKs
# Read apk file from SRC folder and move it to TGT folder while changing filename to APKLABEL_APKVERSION.apk
# If an existing version of the APK exists in the target folder then script will remove it
# Define METHOD as "aapt" or "apktool" depending upon what is available on server 

# Variables
METHOD="aapt"
SRC="/home/user/public_html/dropfolders/apk"
TGT="/home/user/public_html/apk"
if [ -d "$SRC" ];then mkdir -p $SRC
if [ -d "$TGT" ]then mkdir -p $TGT

# Functions
get_apk_filename () {
    if [ "$1" = "" ]; then return 1; fi
    local A="$1"
    case $METHOD in
        "apktool")
            local D=/tmp/apktool
            rm -f -R $D
            apktool d -q -f -s --force-manifest -o $D $A
            local A=$(basename $A)
            local V=$(cat $D/apktool.yml | grep "versionName" | sed -e "s/versionName: //")
            local T=$(cat $D/res/values/strings.xml | grep 'string name="title"' | sed -e 's/.*">//' -e 's/<.*//')
            rm -f -R $D<commands>
            ;;
        "aapt")
            local A=$(aapt dump badging $A | grep -e "application-label:" -e "VersionName")
            local V=$(echo $A | sed -e "s/.*versionName='//" -e "s/' .*//")
            local T=$(echo $A | sed -e "s/.*application-label:'//" -e "s/'.*//")
            ;;
        esac
    echo ${T}_$(echo $V).apk
}

# Begin script
for APK in $(ls "$SRC"/*.apk); do
    APKNAME=$(get_apk_filename "$APK")
    rm -f $TGT/$(echo APKNAME | sed "s/_.*//")_*.apk
    mv "$APK" "$TGT"/$APKNAME
done

对于升级场景,另一种方法可能是使用web服务来交付当前版本号并进行检查,而不是下载整个apk来检查其版本。它可以节省一些带宽,性能更好(如果大多数时候不需要整个apk,那么下载速度比apk快得多),实现起来也更简单。

以最简单的形式,你可以在你的服务器上有一个简单的文本文件…http://some-place.com/current-app-version.txt

在那个文本文件里面有

3.1.4

然后下载该文件并检查当前安装的版本。

构建一个更高级的解决方案是实现一个适当的web服务,并在启动时调用api,该api可以返回一些json,即http://api.some-place.com/versionCheck:

{
    "current_version": "3.1.4"
}

科特林:

var ver: String = packageManager.getPackageInfo(packageName, 0).versionName

有更简单的方法来识别版本代码和版本名。 请将最新的apk拖拽到Android studio进行apk分析器,在这里您可以交叉验证版本代码和版本名称,如下所示: