Android 앱의 자동 증가 버전 코드
Eclipse에서 Android 애플리케이션을 빌드 할 때마다 버전 코드를 자동으로 증가시키는 방법이 있습니까?
http://developer.android.com/guide/publishing/versioning.html 에 따르면에서 버전 코드를 수동으로 증가시켜야합니다 AndroidManifest.xml
.
예를 들어 AndroidManifest.xml 파일을 구문 분석하고 버전 번호를 찾고 증분하고 빌드 자체가 시작되기 전에 파일을 저장하는 등 각 빌드 전에 스크립트를 실행해야합니다. 그러나 Eclipse가 빌드 전후 스크립트 실행을 지원하는 방법과 여부를 알 수 없습니다.
ant Builder 구성에 대한 이 기사 를 찾았 지만 이것은 정확히 Android에 관한 것이 아니며 이것이 Android에 대해 미리 정의 된 빌드 단계를 너무 많이 엉망으로 만들까 두렵습니까?
일반적인 문제 여야하는데 어떻게 해결 했습니까?
글쎄요,이 작업을 수동으로 할 수는 있지만,이 일을하는 것을 잊 자마자 같은 번호의 다른 버전을 얻게되며 전체 버전 관리는 의미가 없습니다.
그래서 다음과 같이 보입니다.
발표하는 기사에 따라이 작업에 ant 를 사용 하십시오 (targets?).
- 매니페스트 구문 분석 (XML 구문 분석)
- 이전 버전 양식 매니페스트를 가져 와서 늘리거나 저장소에서 버전 가져 오기
- 매니페스트에 새 버전 저장
- Android 앱을 빌드하십시오.
하지만 제 경우에는 일반적으로 응용 프로그램을 배포하거나 배포 할 때 Tag 의 개정판 에 따라이 필드를 값으로 채 웁니다 .
나는 이것을 성취했다. 그리고 다음 사람 (Eclipse 사용)을 위해 내가 한 방법은 다음과 같습니다.
1) AndroidManifest.xml에 새 버전 코드를 작성할 외부 콘솔 실행 파일을 만듭니다. (내는 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 { }
}
}
}
곁에 : 모든 c-sharp 컴파일러가이 앱을 빌드 할 수 있으며 Visual Studio 또는 Windows가 필요하지 않습니다.
- 아직 설치하지 않은 경우 .NET 런타임을 설치하십시오 ( Mono가 작동합니다. 링크 ) ( MS의 .NET Framework 2.0에 대한 링크, 2.0은 가장 작은 다운로드이며 모든 버전> = 2.0은 괜찮습니다 )
- A를이 코드를 복사
*.cs
파일 (난 내 이름 :AndroidAutoIncrementVersionCode.cs
) - 명령 프롬프트를 열고
*.cs
파일 을 만든 위치로 이동 합니다. - 다음 명령을 사용하여 파일을 빌드합니다 (Windows에서는 Mono와 비슷하지만 컴파일러에 대한 경로 변경) :
c:\Windows\Microsoft.NET\Framework\v2.0.50727\csc AndroidAutoIncrementVersionCode.cs
(자세한 내용은 .NET 또는 Mono 참조 ) 축하합니다. 도구없이 C # 앱을 빌드
AndroidAutoIncrementVersionCode.exe
했습니다. 동일한 디렉토리에 자동으로 생성되었을 것 입니다.** 마일리지는 다를 수 있으며 경로가 다를 수 있으며 구매가 필요하지 않으며 금지 된 곳에서는 무효입니다. C #이 굉장하고 사람들이 MS 락인이 있다고 잘못 생각하기 때문에 이것을 추가했습니다.이를 다른 언어로 쉽게 번역 할 수 있습니다. 나는 당신을 위해 그렇게하지 않을 것입니다.). 우연히 모든 버전의 .NET 컴파일러가 작동합니다. 최소 공통 분모에 맞게 코드를 수정했습니다 ... *
옆으로 끝내다
2) 빌드 프로세스 중에 실행 파일을 실행합니다. a) 프로젝트 속성으로 이동합니다.
b) 속성에서 "Builders"-> "New ..."로 이동합니다.
c) "프로그램"선택
d) "기본"탭에서 프로그램 위치를 선택하고 (작업 디렉토리도 안전하도록 설정합니다) 원하는 경우 이름을 지정합니다.
e) "새로 고침"탭에서 "완료시 리소스 새로 고침"및 "선택된 리소스"옵션을 선택합니다. 그러면 매니페스트를 작성한 후 매니페스트를 새로 고칩니다.
f) "Build Options"탭에서 입력과 출력이 없기 때문에 "Allocate Console"을 끄고 "During manual builds"와 "During auto builds"만 선택하면 "After a Clean"을 선택 해제 할 수 있습니다. 그런 다음 "관련 자원의 작업 세트 지정"을 선택하고 "자원 지정 ..."단추를 클릭하십시오. "Edit Working Set"대화 상자에서 대화 상자에서 "AndroidManifest.xml"파일을 찾아 확인한 다음 "Finish"를 누릅니다.
f) 이제 "구성 편집 대화 상자"에서 "확인"을 누르고 앱의 속성에서 새로 만든 빌더를 선택하고 목록 맨 위에 올 때까지 "위로"를 계속 클릭합니다. 이렇게하면 자동 증가가 실행됩니다. 첫째, 실수로 동기화되지 않은 상태 또는 재 구축을 트리거하지 않습니다. 만든 새 빌더가 목록 맨 위에 있으면 "확인"을 클릭하면 완료됩니다.
* nix 시스템에 적합한이 쉘 스크립트는 versionCode 및 versionName의 마지막 구성 요소를 현재 하위 버전 개정으로 설정합니다. NBAndroid와 함께 Netbeans를 사용하고 있으며 custom_rules.xml의 사전 컴파일 대상에서이 스크립트를 호출합니다.
이 스크립트를 AndroidManifest.xml과 동일한 디렉토리에있는 incVersion이라는 파일에 저장하고 실행 가능하게 만듭니다. 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
custom_rules.xml을 생성 또는 편집하고 다음을 추가합니다.
<?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>
따라서 현재 svn 개정판이 82이면 AndroidManifest.xml에서 다음과 같이 끝납니다.
android:versionCode="82"
android:versionName="2.1.82">
새 버전을 릴리스하고 싶을 때 일반적으로 versionName의 첫 번째 부분을 업데이트하지만 잊어 버려도 버전 이름의 마지막 부분 (내 정보 활동에 노출됨)은 항상 어떤 svn 개정에서 빌드되었는지 알려줍니다. . 또한 변경 사항을 체크인하지 않은 경우 개정 번호는 82M이고 versionName은 2.1.82M입니다.
빌드가 완료 될 때마다 단순히 버전 번호를 늘리는 것보다 장점은 번호가 제어되고 특정 svn 개정판과 직접 관련 될 수 있다는 것입니다. 최신 릴리스 이외의 버그를 조사 할 때 매우 유용합니다.
FWIW, 6 줄의 파이썬에서 빌드 버전 값을 업데이트 할 수있었습니다.
#!/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() )
바탕 찰스 대답 기존의 빌드 버전은 다음과 같은 단위를 :
#!/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)
영수증 :
빌드를 실행할 때마다 AndroidManifest.xml에있는 manifest 요소의 android : versionCode 속성을 현재 시간 (초 단위의 epoch, unix 셸에서 가져옴)으로 자동 설정하려면 custom_rules.xml의 -pre-build 대상에 추가합니다. 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>
확인 테스트 :
Android 프로젝트 디렉토리에서 다음 셸 명령을 사용하여 생성 된 apk 파일의 versionCode 속성을 가져옵니다.
$ANDROID_SDK/build-tools/20.0.0/aapt dump badging bin/<YourProjectName>.apk | grep versionCode
쉘 명령에서 반환 된 현재 날짜와 비교합니다 date +%s
. 차이는 위의 두 확인 단계 사이의 시간 (초)과 같아야합니다.
이 접근 방식의 장점 :
- 빌드가 명령 줄에서 시작되었는지 Eclipse에서 시작되었는지에 관계없이 versionCode를 업데이트합니다.
- versionCode는 각 빌드마다 고유하고 증가합니다.
- 필요한 경우 versionCode를 대략적인 빌드 시간으로 리버스 엔지니어링 할 수 있습니다.
- 위의 스크립트는 versionCode의 현재 값 (0도)을 대체하고 매크로 자리 표시 자 (예 : -build_id-)가 필요하지 않습니다.
- 값이 AndroidManifest.xml 파일에서 업데이트되기 때문에 버전 제어에 체크인 할 수 있으며 일부 매크로 (예 : -build_id-)가 아닌 실제 값을 유지합니다.
Rocky의 답변을 바탕으로 python 스크립트를 약간 향상하여 versionCode도 높이고 Eclipse ( ckozl 훌륭한 튜토리얼에 따라 통합 ) 및 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)
또한 sulai가 지적한 chmod +x autoincrement.py
것처럼 첫 번째 줄 (환경에 따라 다름)에 파이썬에 대한 올바른 경로가 있는지 잊지 말고 확인하십시오.
비슷한 작업을 수행했지만 외부 C # 대신 데스크톱 AIR 앱으로 작성했습니다 (다른 빌드 시스템을 설치하는 느낌이 들지 않음). 이 Flex / ActionScript 앱을 빌드하고 파일 경로를 변경하여 독립 실행 형 데스크탑 앱으로 빌드하십시오. 파일의 1.2.3 부분을 다시 작성합니다.
<?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>
나는 주어진 정보로부터 내 자신의 해결책을 찾을 수 있었다. 누군가에게 유용한 경우 Linux에서 GIT VCS를 사용할 때 versionCode 및 versionName 속성을 업데이트하는 bash 스크립트가 있습니다.
AndroidManifest.xml 파일을 편집하는 스크립트는 다음과 같습니다.
#/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
템플릿 파일 (AndroidManifest.template.xml)을 파싱하고 문자열 "__VERSION__"및 "__CODE__"를 더 적절한 값으로 바꿉니다.
- "__CODE__"는 단일 소문자 V로 시작하고 그 뒤에 일련의 숫자와 점이 오는 Git 리포지토리의 태그 수로 대체됩니다. 이것은 "v0.5", "v1.1.4"등과 같은 대부분의 버전 문자열처럼 보입니다.
- "__VERSION__"은 "git describe"명령의 출력과 "clean"빌드가 아닌 경우 빌드 된 분기의 조합으로 대체됩니다.
"깨끗한"빌드 란 모든 구성 요소가 버전 제어하에 있고 최신 커밋에 태그가 지정된 것을 의미합니다. "git describe --dirty"는 현재 브랜치의 최근 커밋에서 마지막으로 도달 할 수있는 주석이 달린 태그를 기반으로 버전 번호를보고합니다. 해당 태그 이후에 커밋이있는 경우 해당 커밋 수는 마지막 커밋의 축약 된 개체 이름으로보고됩니다. "--dirty"옵션은 버전 제어하에 수정 된 파일이 수정 된 경우 위 정보에 "-dirty"를 추가합니다.
따라서 AndroidManifest.xml은 더 이상 버전 제어를받지 않아야하며 AndroidManifest.template.xml 파일 만 편집해야합니다. AndroidManifest.template.xml 파일의 시작은 다음과 같습니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.packagename"
android:versionCode="__CODE__"
android:versionName="__VERSION__" >
이것이 누군가에게 유용하기를 바랍니다.
모든 크레딧은 ckoz에게 전달되지만 C #으로 자체 구현을 작성했습니다. 조금 더 빠르고 오류를 먹지 않는다고 생각합니다. 뭔가 잘못되면 아마도 뭔가 잘못 구성되어 있고 그것에 대해 알아야하기 때문입니다.
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);
}
}
}
}
}
}
}
OSX에 있고 Python을 사용하고 싶지만 python XML 파서에 의해 구문 분석이 수행 될 때 XML 형식을 잃지 않는 사람들을 위해 다음은 형식을 유지하는 정규 표현식을 기반으로 증분을 수행하는 Python 스크립트입니다.
#!/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()
코드는 @ckozl 답변을 기반으로했으며 Python으로 수행되었으므로 실행 파일을 만들 필요가 없습니다. 스크립트 이름을 autoincrement.py로 지정하고 manifest.xml 파일과 같은 폴더에 넣은 다음 ckozl이 위에서 설명한 단계를 수행하십시오!
If you want to update the AndroidManifest.xml to use a specific version number, perhaps from a build system, then you can use the project I just pushed to GitHub: https://github.com/bluebirdtech/AndroidManifestVersioner
It's a basic .NET command line app, usage:
AndroidManifestVersioner <path> <versionCode> <versionName>.
Thanks to other posters for their code.
Here is the Java version for what it's worth. Also handling multiple manifests.
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);
}
}
}
If you're using gradle then you can specific versionName
and versionCode
very easy in build.gradle
. You can use git commit count as an increasing number to identify the build.
You can also use this library: https://github.com/rockerhieu/Versionberg.
참고URL : https://stackoverflow.com/questions/6758685/auto-increment-version-code-in-android-app
'IT Share you' 카테고리의 다른 글
캔버스 내에서 애니메이션 프레임 워크를 어떻게 사용할 수 있습니까? (0) | 2020.11.26 |
---|---|
SELECT 쿼리에서 계산 된 필드를 재사용 할 수 있습니까? (0) | 2020.11.26 |
sw600dp와 w600dp의 차이점은 무엇입니까? (0) | 2020.11.26 |
WatchService (전체 디렉토리가 아님)를 사용하여 단일 파일 변경을 볼 수 있습니까? (0) | 2020.11.26 |
Enum 멤버를 JSON으로 직렬화 (0) | 2020.11.26 |