tus - Código de versión de incremento automático en la aplicación de Android
subir actualizacion google play (14)
¿Hay alguna forma de incrementar automáticamente el código de la versión cada vez que crea una aplicación de Android en Eclipse?
Según http://developer.android.com/guide/publishing/versioning.html , debe aumentar manualmente el código de su versión en AndroidManifest.xml
.
Entiendo que debe ejecutar un script antes de cada compilación, por ejemplo, analizar el archivo AndroidManifest.xml, buscar el número de versión, incrementarlo y guardar el archivo antes de que comience la compilación. Sin embargo, no pude averiguar cómo y si Eclipse admite secuencias de comandos antes / después de las compilaciones.
He encontrado este artículo sobre la configuración del generador de hormigas, pero esto no es exactamente sobre Android y me temo que esto arruinará demasiado los pasos de construcción predefinidos para Android.
Debe ser un problema común, ¿cómo lo resolvió?
Bueno, uno puede hacerlo manualmente, pero tan pronto como te olvides de hacer esta tarea, obtienes diferentes versiones con el mismo número y todo el versionado tiene poco sentido.
Aquí está la versión de Java por lo que vale. También maneja múltiples manifiestos.
String directory = "d://Android//workspace//";
String[] manifests = new String[]
{
"app-free//AndroidManifest.xml",
"app-donate//AndroidManifest.xml",
};
public static void main(String[] args)
{
new version_code().run();
}
public void run()
{
int I = manifests.length;
for(int i = 0; i < I; i++)
{
String path = directory + manifests[i];
String content = readFile(path);
Pattern versionPattern = Pattern.compile( "(.*android:versionCode=/")([0-9]+)(/".*)", Pattern.DOTALL );
Matcher m = versionPattern.matcher(content);
if (m.matches())
{
int code = Integer.parseInt( m.group(2) ) + 1;
System.out.println("Updating manifest " + path + " with versionCode=" + code);
String newContent = m.replaceFirst("$1" + code + "$3");
writeFile(path + ".original.txt", content);
writeFile(path, newContent);
}
else
{
System.out.println("No match to update manifest " + path);
}
}
}
Basándose en la respuesta de Charles , lo siguiente incrementa la versión de compilación existente:
#!/usr/bin/python
from xml.dom.minidom import parse
dom1 = parse("AndroidManifest.xml")
oldVersion = dom1.documentElement.getAttribute("android:versionName")
versionNumbers = oldVersion.split(''.'')
versionNumbers[-1] = unicode(int(versionNumbers[-1]) + 1)
dom1.documentElement.setAttribute("android:versionName", u''.''.join(versionNumbers))
with open("AndroidManifest.xml", ''wb'') as f:
for line in dom1.toxml("utf-8"):
f.write(line)
Entonces, lo veo así:
Dependiendo del artículo que presente, use hormiga para estas tareas (¿objetivos?).
- Parse Manifest (análisis XML)
- obtener el manifiesto de formulario de versión anterior y aumentarlo / obtener la versión del repositorio
- almacenar nueva versión en manifiesto
- construir la aplicación de Android.
Pero, en mi caso, suelo rellenar este campo por valor en función de la revisión de Tag cuando despliego o distribuyo la aplicación.
Este script de shell, adecuado para sistemas * nix, establece el código de versión y el último componente de versionName en la revisión de subversión actual. Estoy usando Netbeans con NBAndroid y llamo a este script desde el destino -pre-compile en custom_rules.xml.
Guarde este script en un archivo llamado incVersion en el mismo directorio que AndroidManifest.xml, chmod +x incVersion
ejecutable: chmod +x incVersion
manf=AndroidManifest.xml
newverfull=`svnversion`
newvers=`echo $newverfull | sed ''s/[^0-9].*$//''`
vers=`sed -n ''/versionCode=/s/.*"/([0-9][0-9]*/)".*//1/p'' $manf`
vername=`sed -n ''/versionName=/s/.*"/([^"]*/)".*//1/p'' $manf`
verbase=`echo $vername | sed ''s//(.*/./)/([0-9][0-9]*/).*$//1/''`
newvername=$verbase$newverfull
sed /versionCode=/s/''"''$vers''"''/''"''$newvers''"''/ $manf | sed /versionName=/s/''"''$vername''"''/''"''$newvername''"''/ >new$manf && cp new$manf $manf && rm -f new$manf
echo versionCode=$newvers versionName=$newvername
Crea o edita custom_rules.xml y agrega esto:
<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules">
<xmlproperty file="AndroidManifest.xml" prefix="mymanifest" collapseAttributes="true"/>
<target name="-pre-compile">
<exec executable="./incVersion" failonerror="true"/>
</target>
</project>
Entonces, si mi revisión svn actual es 82, termino con esto en AndroidManifest.xml:
android:versionCode="82"
android:versionName="2.1.82">
Cuando deseo lanzar una nueva versión, normalmente actualizaré las primeras partes de versionName, pero incluso si lo olvido, la última parte de versionName (que está expuesta en mi actividad Acerca de) siempre me dirá de qué revisión svn se creó. . Además, si no he registrado los cambios, el número de revisión será 82M y versionName será algo así como 2.1.82M.
La ventaja de simplemente incrementar el número de versión cada vez que se realiza una compilación es que el número permanece bajo control y puede relacionarse directamente con una revisión de svn específica. Muy útil cuando se investigan errores en la última versión.
FWIW, pude actualizar el valor de la versión de compilación en seis líneas de Python:
#!/bin/env python
import os
from xml.dom.minidom import parse
dom1 = parse("AndroidManifest.xml")
dom1.documentElement.setAttribute("android:versionName","%build.number%")
f = os.open("AndroidManifest.xml", os.O_RDWR)
os.write( f, dom1.toxml() )
Hice algo similar, pero lo escribí como una aplicación Desktop AIR en lugar de C # externa (no me sentí instalar otro sistema de compilación). Cree esta aplicación Flex / ActionScript y cambie la ruta a su archivo, contrátelo como una aplicación de escritorio independiente. Reescribe la parte 1.2.3 de tu archivo.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="371" height="255" applicationComplete="Init();">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
public function Init():void
{
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
var myFile:File = new File("D://Dropbox//Projects//My App//src//Main-app.xml");
var fileStream:FileStream = new FileStream();
fileStream.open(myFile, FileMode.READ);
var fileContents:String = fileStream.readUTFBytes(fileStream.bytesAvailable);
var startIndex:Number = fileContents.indexOf("<versionNumber>");
var numberIndex:Number = startIndex + 15;
var endIndex:Number = fileContents.indexOf("</versionNumber>");
if (startIndex == -1 || endIndex == -1)
return;
var versionNumber:String = fileContents.substr(numberIndex, endIndex - numberIndex);
var versionArr:Array = versionNumber.split(".");
var newSub:Number = Number(versionArr[2]);
newSub++;
versionArr[2] = newSub.toString();
versionNumber = versionArr.join(".");
var newContents:String = fileContents.substr(0, startIndex) + "<versionNumber>" + versionNumber + "</versionNumber>" +
fileContents.substr(endIndex + 16);
fileStream.close();
fileStream = new FileStream();
fileStream.open(myFile, FileMode.WRITE);
fileStream.writeUTFBytes(newContents);
fileStream.close();
close();
}
]]>
</fx:Script>
<s:Label x="10" y="116" width="351" height="20" fontSize="17"
text="Updating My App Version Number" textAlign="center"/>
</s:WindowedApplication>
Logré esto. Y así es como lo hice para el siguiente tipo (usando Eclipse):
1) Crea un ejecutable de consola externo que va a escribir un nuevo código de versión en AndroidManifest.xml: (el mío está en C #)
using System.IO;
using System.Text.RegularExpressions;
namespace AndroidAutoIncrementVersionCode
{
class Program
{
static void Main(string[] args)
{
try
{
string FILE = @"AndroidManifest.xml";
string text = File.ReadAllText(FILE);
Regex regex = new Regex(@"(?<A>android:versionCode="")(?<VER>/d+)(?<B>"")", RegexOptions.IgnoreCase);
Match match = regex.Match(text);
int verCode = int.Parse(match.Groups["VER"].Value) + 1;
string newText = regex.Replace(text, "${A}" + verCode + "${B}", 1);
File.WriteAllText(FILE, newText);
}
catch { }
}
}
}
a un lado: cualquier compilador c-sharp puede construir esta aplicación, no necesita Visual Studio o incluso Windows
- si aún no lo tiene, instale .NET runtime ( Mono funcionará, enlace ) ( enlace a .NET framework 2.0 de MS, 2.0 es la descarga más pequeña, cualquier versión> = 2.0 está bien )
- copie este código en un archivo
*.cs
(yo nombré el mío:AndroidAutoIncrementVersionCode.cs
) - abra un símbolo del sistema y navegue hasta donde hizo su archivo
*.cs
- construya el archivo usando este comando (en Windows, similar para Mono pero cambie la ruta al compilador):
c:/Windows/Microsoft.NET/Framework/v2.0.50727/csc AndroidAutoIncrementVersionCode.cs
(vea: .NET o Mono para más información) Felicidades, acabas de crear una aplicación C # sin ninguna herramienta, debería haber generado
AndroidAutoIncrementVersionCode.exe
en el mismo directorio automáticamente** el millaje puede variar, los caminos pueden ser diferentes, no se requiere compra, está vacío donde está prohibido, agregué esto porque C # es increíble, y la gente cree erróneamente que tiene bloqueo de MS, podrías traducirlo fácilmente a otro idioma (pero no voy a hacer eso por ti;). por cierto, cualquier versión de cualquier compilador .NET funcionará, adapté el código para el mínimo común denominador ... *
terminar a un lado
2) Ejecute el ejecutable durante el proceso de compilación: a) Vaya a las propiedades del proyecto
b) En las propiedades, vaya a "Constructores" -> "Nuevo ..."
c) Elija "Programa"
d) En la pestaña "Principal", seleccione la ubicación del programa (también configuro el directorio de trabajo para que sea seguro) y asígnele un nombre si lo desea.
e) En la pestaña "Actualizar", seleccione la opción "Actualizar recursos al finalizar" y "El recurso seleccionado"; esto actualizará el manifiesto después de que lo hayamos escrito.
f) En la pestaña "Opciones de compilación" puede desactivar "Asignar consola" ya que no tiene entrada y salida y luego seleccionar solo "Durante compilaciones manuales" y "Durante compilaciones automáticas" anule la selección de "Después de limpiar" si está marcada. Luego seleccione "Especificar un conjunto de recursos relevantes que funcione" y haga clic en el botón "Especificar recursos ...". En el cuadro de diálogo "Editar conjunto de trabajo", ubique su archivo "AndroidManifest.xml" en el cuadro de diálogo y verifíquelo, luego presione "Terminar"
f) Ahora presiona "OK" dentro del "cuadro de diálogo Editar configuración" y en las propiedades de tu aplicación, selecciona el creador recientemente creado y sigue haciendo clic en "Arriba" hasta que esté en la parte superior de la lista, de esta manera se ejecuta el incremento automático primero, y no desencadena estados o reconstrucciones accidentales fuera de sincronización. Una vez que el nuevo constructor que ha creado se encuentre en la parte superior de la lista, haga clic en "Aceptar" y habrá terminado.
Para aquellos que están en OSX y quieren usar Python, pero no pierden el formato XML que cuando el analizador XML de Python realiza el análisis, aquí hay un script de Python que hará el incremento basado en la expresión regular, que mantiene el formato:
#!/usr/bin/python
import re
f = open(''AndroidManifest.xml'', ''r+'')
text = f.read()
result = re.search(r''(?P<groupA>android:versionName=")(?P<version>.*)(?P<groupB>")'',text)
version = str(float(result.group("version")) + 0.01)
newVersionString = result.group("groupA") + version + result.group("groupB")
newText = re.sub(r''android:versionName=".*"'', newVersionString, text);
f.seek(0)
f.write(newText)
f.truncate()
f.close()
El código se basó en @ckozl answer, simplemente se realizó en python, por lo que no es necesario crear un ejecutable para esto. Simplemente llame el script autoincrement.py, colóquelo en la misma carpeta con el archivo manifest.xml y luego siga los pasos que ckozl describió arriba.
Pude resolver mi propia solución a partir de la información proporcionada. En caso de que sea útil para alguien, aquí está mi script bash para actualizar los atributos versionCode y versionName al usar el GIT VCS en Linux.
Mi script para editar el archivo AndroidManifest.xml se ve así:
#/bin/bash
CODE=`git tag | grep -c ^v`
NAME=`git describe --dirty`
COMMITS=`echo ${NAME} | sed -e ''s/v[0-9/.]*//''`
if [ "x${COMMITS}x" = "xx" ] ; then
VERSION="${NAME}"
else
BRANCH=" (`git branch | grep "^/*" | sed -e ''s/^..//''`)"
VERSION="${NAME}${BRANCH}"
fi
cat AndroidManifest.template.xml //
| sed -e "s/__CODE__/${CODE}/" //
-e "s/__VERSION__/${VERSION}/" > AndroidManifest.xml
exit 0
Analiza el archivo de plantilla (AndroidManifest.template.xml) y reemplaza las cadenas "__VERSION__" y "__CODE__" con valores más apropiados:
- "__CODE__" se reemplaza por un recuento de la cantidad de etiquetas en el repositorio de Git que comienza con una sola V minúscula y va seguida de una secuencia de dígitos y puntos. Esto se parece a la mayoría de las cadenas de versiones como: "v0.5", "v1.1.4" y así sucesivamente.
- "__VERSION__" se reemplaza con una combinación de la salida del comando "git describe" y, si no es una compilación "limpia", la rama en la que se creó.
Por una compilación "limpia" me refiero a una en la que todos los componentes están bajo control de versión y su última confirmación está etiquetada. "git describe --dirty" informará un número de versión basado en la última etiqueta anotada alcanzable en tu última confirmación en la rama actual. Si hay confirmaciones desde esa etiqueta, se informa un recuento de esas confirmaciones, así como el nombre de objeto abreviado de la última confirmación. La opción "- dirty" agregará "-dirty" a la información anterior si se modifican los archivos que están bajo control de versión.
Por lo tanto, AndroidManifest.xml ya no debe estar bajo control de versión, y solo debe editar el archivo AndroidManifest.template.xml. El inicio de su archivo AndroidManifest.template.xml se ve así:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.packagename"
android:versionCode="__CODE__"
android:versionName="__VERSION__" >
Espero que sea útil para alguien
Si desea actualizar AndroidManifest.xml para usar un número de versión específico, tal vez de un sistema de compilación, puede usar el proyecto que acabo de enviar a GitHub: https://github.com/bluebirdtech/AndroidManifestVersioner
Es una aplicación básica de línea de comando .NET, uso:
AndroidManifestVersioner <path> <versionCode> <versionName>.
Gracias a otros carteles por su código.
Si está usando gradle, entonces puede versionName
y versionCode
específicos muy fáciles en build.gradle
. Puede usar el conteo de compromiso de git como un número creciente para identificar la compilación.
También puede usar esta biblioteca: https://github.com/rockerhieu/Versionberg .
Sobre la base de la respuesta de Rocky, mejoré un poco ese script de python para aumentar también el versionCode, funciona para mí en Eclipse (integrado de acuerdo con el excelente tutorial de ckozl ) y Mac OSX.
#!/usr/bin/python
from xml.dom.minidom import parse
dom1 = parse("AndroidManifest.xml")
oldVersion = dom1.documentElement.getAttribute("android:versionName")
oldVersionCode = dom1.documentElement.getAttribute("android:versionCode")
versionNumbers = oldVersion.split(''.'')
versionNumbers[-1] = unicode(int(versionNumbers[-1]) + 1)
dom1.documentElement.setAttribute("android:versionName", u''.''.join(versionNumbers))
dom1.documentElement.setAttribute("android:versionCode", str(int(oldVersionCode)+1))
with open("AndroidManifest.xml", ''wb'') as f:
for line in dom1.toxml("utf-8"):
f.write(line)
también no olvides chmod +x autoincrement.py
y asegúrate de tener la ruta correcta a python en la primera línea (dependiendo de tu entorno) como señaló sulai
Todo el crédito va a ckoz, pero escribí mi propia implementación en c #. Creo que es un poco más rápido y no come errores, porque si algo sale mal probablemente algo esté configurado incorrectamente y debería saberlo.
namespace AndroidVersionCodeAutoIncrement
{
using System.IO;
using System.Text.RegularExpressions;
public class Program
{
private static readonly Regex VersionCodeRegex = new Regex("android:versionCode=/"(?<version>.*)/"", RegexOptions.Compiled);
public static void Main()
{
using (var manifestFileStream = File.Open("AndroidManifest.xml", FileMode.Open, FileAccess.ReadWrite))
using (var streamReader = new StreamReader(manifestFileStream))
{
var manifestFileText = streamReader.ReadToEnd();
var firstMatch = VersionCodeRegex.Match(manifestFileText);
if (firstMatch.Success)
{
int versionCode;
var versionCodeValue = firstMatch.Groups["version"].Value;
if (int.TryParse(versionCodeValue, out versionCode))
{
manifestFileText = VersionCodeRegex.Replace(manifestFileText, "android:versionCode=/"" + (versionCode + 1) + "/"", 1);
using (var streamWriter = new StreamWriter(manifestFileStream))
{
manifestFileStream.Seek(0, SeekOrigin.Begin);
streamWriter.Write(manifestFileText);
manifestFileStream.SetLength(manifestFileText.Length);
}
}
}
}
}
}
}
Receta:
Para tener automáticamente el atributo android: versionCode del elemento manifesto en AndroidManifest.xml establecido en la hora actual (de epoch en segundos, obtenida del shell de Unix) cada vez que ejecuta una compilación, agréguela a su objetivo de pre-compilación en custom_rules.xml Archivo de Android.
<target name="-pre-build">
<exec executable="date" outputproperty="CURRENT_TIMESTAMP">
<arg value="+%s"/>
</exec>
<replaceregex file="AndroidMainfest.xml" match="android:versionCode=.*"
replace=''android:versionCode="${CURRENT_TIMESTAMP}"'' />
</target>
Prueba de confirmación :
Obtenga el atributo versionCode del archivo apk generado, usando el siguiente comando de shell desde su directorio de proyecto Android:
$ANDROID_SDK/build-tools/20.0.0/aapt dump badging bin/<YourProjectName>.apk | grep versionCode
y compararlo con la fecha actual devuelta desde el comando de shell: date +%s
La diferencia debe ser igual al período de tiempo en segundos entre los dos pasos de confirmación anteriores.
Ventajas de este enfoque:
- Independientemente de si la compilación se inicia desde la línea de comandos o Eclipse, actualizará el código de versión.
- Se garantiza que el versionCode es único y creciente para cada compilación
- El versionCode puede ser de ingeniería inversa en un tiempo de construcción aproximado si lo necesita
- La secuencia de comandos anterior reemplaza cualquier valor presente de versionCode, incluso 0 y no requiere un marcador de posición de macro (como -build_id-).
- Como el valor se actualiza en el archivo AndroidManifest.xml, puede verificarlo en el control de la versión y retendrá el valor real, no alguna macro (como -build_id-).