una - Obtener Android.apk archivo VersionName o VersionCode SIN instalar apk
play store (6)
¿Cómo puedo obtener el código de la versión programáticamente o el nombre de la versión de apk del archivo AndroidManifest.xml después de la descarga y sin instalarlo?
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxx.xx.xxx"
android:versionCode="1"
android:versionName="1.1" >
Por ejemplo, quiero verificar si una nueva versión se carga en mi servicio IIS después de esa instalación en el dispositivo, si no es una nueva versión, no quiero instalarlo.
Ahora puedo recuperar con éxito la versión de un archivo APK a partir de sus datos XML binarios.
En este tema obtuve la clave de mi respuesta (también agregué mi versión del código de Ribo): cómo analizar el archivo AndroidManifest.xml dentro de un paquete .apk
Además, aquí está el código de análisis XML que escribí, específicamente para buscar la versión:
Análisis XML
/**
* Verifies at Conductor APK path if package version if newer
*
* @return True if package found is newer, false otherwise
*/
public static boolean checkIsNewVersion(String conductorApkPath) {
boolean newVersionExists = false;
// Decompress found APK''s Manifest XML
// Source: https://.com/questions/2097813/how-to-parse-the-androidmanifest-xml-file-inside-an-apk-package/4761689#4761689
try {
if ((new File(conductorApkPath).exists())) {
JarFile jf = new JarFile(conductorApkPath);
InputStream is = jf.getInputStream(jf.getEntry("AndroidManifest.xml"));
byte[] xml = new byte[is.available()];
int br = is.read(xml);
//Tree tr = TrunkFactory.newTree();
String xmlResult = SystemPackageTools.decompressXML(xml);
//prt("XML/n"+tr.list());
if (!xmlResult.isEmpty()) {
InputStream in = new ByteArrayInputStream(xmlResult.getBytes());
// Source: http://developer.android.com/training/basics/network-ops/xml.html
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(in, null);
parser.nextTag();
String name = parser.getName();
if (name.equalsIgnoreCase("Manifest")) {
String pakVersion = parser.getAttributeValue(null, "versionName");
//NOTE: This is specific to my project. Replace with whatever is relevant on your side to fetch your project''s version
String curVersion = SharedData.getPlayerVersion();
int isNewer = SystemPackageTools.compareVersions(pakVersion, curVersion);
newVersionExists = (isNewer == 1);
}
}
}
} catch (Exception ex) {
android.util.Log.e(TAG, "getIntents, ex: "+ex);
ex.printStackTrace();
}
return newVersionExists;
}
Comparación de versiones (visto como SystemPackageTools.compareVersions en el fragmento anterior) NOTA: Este código está inspirado en el siguiente tema: forma eficiente de comparar cadenas de versiones en Java
/**
* Compare 2 version strings and tell if the first is higher, equal or lower
* Source: https://.com/questions/6701948/efficient-way-to-compare-version-strings-in-java
*
* @param ver1 Reference version
* @param ver2 Comparison version
*
* @return 1 if ver1 is higher, 0 if equal, -1 if ver1 is lower
*/
public static final int compareVersions(String ver1, String ver2) {
String[] vals1 = ver1.split("//.");
String[] vals2 = ver2.split("//.");
int i=0;
while(i<vals1.length&&i<vals2.length&&vals1[i].equals(vals2[i])) {
i++;
}
if (i<vals1.length&&i<vals2.length) {
int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
return diff<0?-1:diff==0?0:1;
}
return vals1.length<vals2.length?-1:vals1.length==vals2.length?0:1;
}
Espero que esto ayude.
Lo siguiente funcionó para mí desde la línea de comando:
aapt dump badging myapp.apk
NOTA: aapt.exe se encuentra en una subcarpeta de build-tools
de desarrollo de SDK. Por ejemplo:
<sdk_path>/build-tools/23.0.2/aapt.exe
Para el escenario de actualización, específicamente un enfoque alternativo podría ser tener un servicio web que entregue el número de versión actual y verificar que en lugar de descargar todo el apk solo verifique su versión. Ahorraría algo de ancho de banda, sería un poco más eficiente (mucho más rápido de descargar que un apk si no se necesita la apk completa la mayor parte del tiempo) y sería mucho más fácil de implementar.
En la forma más simple, podría tener un archivo de texto simple en su servidor ... http://some-place.com/current-app-version.txt
Dentro de ese archivo de texto tiene algo así como
3.1.4
y luego descargue ese archivo y verifique contra la versión instalada actualmente.
Crear una solución más avanzada para eso sería implementar un servicio web adecuado y tener una llamada de API en el lanzamiento que podría devolver algo de json, es decir, http://api.some-place.com/versionCheck
:
{
"current_version": "3.1.4"
}
Si está utilizando la versión 2.2 y superior de Android Studio, entonces en Android Studio use Build → Analyze APK y luego seleccione AndroidManifest.xml.
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();
}
final PackageManager pm = getPackageManager();
String apkName = "example.apk";
String fullPath = Environment.getExternalStorageDirectory() + "/" + apkName;
PackageInfo info = pm.getPackageArchiveInfo(fullPath, 0);
Toast.makeText(this, "VersionCode : " + info.versionCode + ", VersionName : " + info.versionName , Toast.LENGTH_LONG).show();