태그 보관물: 안드로이드 빌드

Android에서 Ant(build.xml)로 마켓 별 바이너리 빌드하기..

안드로이드 마켓은 애플 앱스토어와 다르게, 통신사나 회사에서 마켓을 만들어서 서비스 할 수 있다. 그래서 여러 안드로이드 마켓을 확인할 수 있다. 안드로이드 앱을
개발하면, Play 마켓 과 더불어 아마존 이나 티스토어 등의 여러 마켓에 런칭하는 경우가 있다. 개별 앱 마켓에 앱을 런칭하는 경우, 개별 마켓은 고유한 정책을 가지고 있고, 정책에 위배되면, 위배되는 내용을 수정해서 다시 요청(Play 마켓을 제외한 다른 마켓들은 거의 리뷰를 한다)해야 한다.

개별 마켓이 가지고 있는 정책중에 하나가, 앱에 대한 설명이나 앱의 주소가 적인 URL(http://play.google.com과 같은 주소는 다른 마켓에서 반려 사유가 된다)이 문제가 되는 경우가 있다. 그리고 개별 마켓에서 설치한 앱은 마켓 별로 다른 메세지를 보여줄 필요도 있다.

그래서, 앤트(Ant, build.xml)를 사용해서 마켓별로 앱을 패키징 하는 방법을 살펴보자.

1. 기본적인 구조

기본적인 패키지의 구조는 좌측과 같습니다..

2.3 버전부터 지원할 수 있는 형태로 프로젝트를 생성했습니다.

좌측의 패키지 구조를 살펴보면…

\libs-ext : 마켓의 분리를 위해서 필요한 Market.java를 폴더별로 가지고 있습니다.

build.properties : 릴리즈를 하기 위한 인증서의 위치와 정보를 저장하는 파일..

build.xml : 빌드 스크립트 파일..

local.properties : 로컬의 SDK 위치를 가리치는 파일..

project.properties : target project의 버전정보를 가지고 있는 파일..

 

참고로, 검은색으로 칠해버린 넘은 인증서 파일입니다..

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2. 코드 보기..

 

 

 

 

 

 

 

2.1 MainActivity.java

– 화면에 마켓의 정보를 보여주는 클래스..

package net.sjava.buildtest;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;

import net.sjava.buildtest.util.Constants;

public class MainActivity extends Activity {
	private TextView tv;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tv = (TextView)findViewById(R.id.main_textview);
        tv.setText(Constants.getMarketString(MainActivity.this));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

2.2 Constants.java

– 마켓에 대한 정보를 넘겨주는 클래스..

package net.sjava.buildtest.util;

import android.content.Context;
import net.sjava.buildtest.R;
import net.sjava.buildtest.util.config.Debug;
import net.sjava.buildtest.util.config.Market;

public class Constants {
	public static final boolean DEBUG = Debug.DEBUG;
	public static final int MARKET = Market.MARKET;
	
	public static String getMarketString(Context c) {
		if(c == null)
			return "";
		
		if(MARKET == 0)
			return c.getString(R.string.mk_play);
					
		if(MARKET == 1)
			return c.getString(R.string.mk_amazon);
		
		if(MARKET == 2)
			return c.getString(R.string.mk_tstore);
		
		return "";
	}
}

 

2. 마켓의 정보를 구분하기..

마켓의 정보는 위의 폴더에서 자신의 상수값을 가지고 있게 된다..

따라서, 첨부한 소스를 확인해 보면, mk-play 폴더의 Market.java는 상수값으로 1을 가지고 있다..

 

3. 빌드 스크립트..

– 빌드 스크립트인 build.xml은 구글의 프레임웍이 빌드를 하기 위한 스크립트를 제공하기 때문에 매우 간단하게 작성을 할 수 있다.. 떙큐.. ^^, 아래의 스크립트는 dev/rc/live 같은 개발/라이브의 테스트/라이브 별도 바이너리를 릴리즈 하는 스크립트는 포함하지 않지만, 이것도 쉽게 추가할 수 있다.. 또한, 포함되어 있지 않지만, obfuscate를 위해서  proguard가 포함되어 있어, obfucate를 쉽게 지원한다.

 

3.1 build.properties

#
# Set the keystore properties for signing the application.
# 맞게 수정하시면 됩니다.. ^^
key.store=./libs-ext/xxxx
key.alias=xxxx

key.store.password=xxxx
key.alias.password=xxxx

3.2 local.properties

# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=C:\\Program Files\\android\\android-sdk

 

3.3 project.properties

# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-16

 

3.4 build.xml

– 아래의 빌드 스크립트의 buildtest-release-all 타켓을 실행해서, 마켓별 바이너리를 뽑아낼 수 있다.

 

<?xml version=”1.0″ encoding=”UTF-8″?>
<project name=”BuildTest” default=”help”>
<property file=”local.properties”/>
<property file=”build.properties” />
<property file=”project.properties” />

<!–property name=”config-target-dir-path” value=”net/sjava/buildtest/util/config” /–>
<property name=”market-target-dir-path” value=”net/sjava/buildtest/util/config” />

<property name=”project.name” value=”BuildTest”/>
<property name=”dist.dir” value=”./dist/” />
<property name=”release.file” value=”./bin/BuildTest-release.apk” />
<property name=”dist.backup” value=”c:/dev/dist” />

<path id=”android.antlibs”>
<fileset dir=”${sdk.dir}/tools/lib/” includes=”*.jar” />
</path>

    <!– 안드로이드 SDK가 제공하는 build.xml을 사용하기 위해서 import 한다.. –>
    <import file=”${sdk.dir}/tools/ant/build.xml”/>

    <!–AndroidManifest에서 xpath를 이용해서 선언된 versionName 값을 가져온다. –>
    <xpath input=”AndroidManifest.xml” expression=”/manifest/@android:versionName” output=”versionName” default=”1.0.0″/>

<tstamp>
<format property=”touch.time” pattern=”yyyyMMdd_HHmm” />
</tstamp>

<target name=”switch-market”>
<echo>Market Configuration file: ${market.filename}</echo>
<property name=”market-target-path” value=”${source.dir}/${market-target-dir-path}” />
<copy file=”${market.filename}” todir=”${market-target-path}” overwrite=”true” encoding=”utf-8″ />
</target>

<target name=”buildtest-backup”>
<copy todir=”${dist.backup}/${project.name}/${versionName}_${touch.time}”>
<fileset dir=”./dist”/>
</copy>
</target>

<target name=”buildtest-release-mk-play”>
<echo>Selected release configuration</echo>
<antcall target=”clean” />

<antcall target=”switch-market”>
<param name=”market.filename” value=”libs-ext/mk-play/Market.java” />
</antcall>

<property name=”proguard.enabled” value=”false”/>
<antcall target=”release” />
<copy file=”${release.file}” tofile=”${dist.dir}/${project.name}_live_play_${versionName}_${touch.time}.apk”/>
</target>

<target name=”buildtest-release-mk-amazon”>
<echo>Selected release configuration</echo>
<antcall target=”clean” />

<antcall target=”switch-market”>
<param name=”market.filename” value=”libs-ext/mk-amazon/Market.java” />
</antcall>

<property name=”proguard.enabled” value=”false”/>
<antcall target=”release” />
<copy file=”${release.file}” tofile=”${dist.dir}/${project.name}_live_amazon_${versionName}_${touch.time}.apk”/>
</target>

<target name=”buildtest-release-mk-tstore”>
<echo>Selected release configuration</echo>
<antcall target=”clean” />

<antcall target=”switch-market”>
<param name=”market.filename” value=”libs-ext/mk-tstore/Market.java” />
</antcall>

<property name=”proguard.enabled” value=”false”/>
<antcall target=”release” />
<copy file=”${release.file}” tofile=”${dist.dir}/${project.name}_live_tstore_${versionName}_${touch.time}.apk”/>
</target>

<target name=”buildtest-release-all”>
<echo>Start distribute binaries all of the market</echo>
<antcall target=”buildtest-release-mk-play” />
<antcall target=”buildtest-release-mk-amazon” />
<antcall target=”buildtest-release-mk-tstore” />
</target>

</project>

 

4. 결과

– 위의 코드를 통해서 마켓별로 필요한 URL이나, 리소스를 구분해서 보여줄 수 가 있겠습니다.. 아래의 화면은 만들어진 바이너리가 마켓별로 구분된 메세지를 보여주는지 테스트한 화면입니다..

 

아래의 명령을 통해서 각 바이너리를 에뮬레이터에 설치해서 테스트 하시면 됩니다.

> adb install BuildTest_live_amazon_1.0_20120918_2132.apk

> adb install BuildTest_live_tstore_1.0_20120918_2132.apk

 

 

5. 소스

cfile27.uf.1534F3375059F12A030C14.zip