友盟封装工具(Java+shell)

友盟打包工具(Java+shell)
一共4个文件


my.keystore.properties 打签名的配置,合并到ant里也可以
SetUMengChannel.java 编译成SetUMengChannel.jar
build_channel.xml ant配置
build_channel.sh 打签名的批处理


-1. 基于android-sdk_r18-macosx,其他环境我没测过
0. 用java而不用python和perl,是因为,不管在哪个平台开发Android,你一定有java用。(笑
1. 先设置环境变量,放脚本里面或者放配置文件都可以
export ANDROID_SDK=...
2. 编译SetUMengChannel.jar,放到合适的位置
3. sh build_channel.sh <渠道字符串>

文件名: my.keystore.properties
签名文件的配置
key.store=...
key.alias=...
key.store.password=...
key.alias.password=...


文件名: build_channel.xml
ant配置文件
从Android SDK 的tools/build.xml 借鉴了一些代码
主要目的:
1. 指定签名文件的参数 my.keystore.properties
2. 定制安装包apk的文件名,这里会输出的文件名形如
     HelloWorld_0.8.6_build75_google.apk

<?xml version="1.0" encoding="UTF-8"?>
<project
    name="HelloWorld"
    default="help" >

    <loadproperties srcFile="my.keystore.properties" />

    <property environment="env" />

    <condition
        property="umeng.channel"
        value="${env.UMENG_CHANNEL}" >
        <and>
            <not><isset property="${env.UMENG_CHANNEL}" /></not>
            <not><isset property="umeng.channel" /></not>
        </and>
    </condition>

    <condition
        property="sdk.dir"
        value="${env.ANDROID_SDK}" >
        <and>
            <not><isset property="${env.ANDROID_SDK}" /></not>
            <not><isset property="sdk.dir" /></not>
        </and>
    </condition>

    <import file="build.xml" />

    <!-- Custom tasks -->
    <taskdef name="xpath"
             classname="com.android.ant.XPathTask"
             classpathref="android.antlibs" />

    <target name="release-channel"
        depends="-set-release-mode, -release-obfuscation-check, -package, -post-package, -release-prompt-for-password, -release-channel-sign, -post-build"
        description="Builds the application in release-channel mode.">
    </target>

    <!-- custom output file name -->
    <target name="-release-channel-sign" if="has.keystore" >
        <!-- only create apk if *not* a library project -->
        <do-only-if-not-library elseText="Library project: do not create apk..." >
            <sequential>
                <property name="out.unaligned.file" location="${out.absolute.dir}/${ant.project.name}-release-unaligned.apk" />

                <echo>umeng.channel=${umeng.channel}</echo>

                <xpath input="AndroidManifest.xml" expression="/manifest/@android:versionName"
                    output="version.name" default="0.0.0.0"/>
                <echo>version.name=${version.name}</echo>

                <xpath input="AndroidManifest.xml" expression="/manifest/@android:versionCode"
                    output="version.code" default="0"/>
                <echo>version.code=${version.code}</echo>

                <echo>Signing final apk...</echo>
                <property name="version.name" value="${version.name}" />
                <property name="version.code" value="${version.code}" />

                <!-- 在这里定义安装包的文件名规则 -->
                <property name="out.channel.file" location="${out.absolute.dir}/${ant.project.name}_${version.name}_build${version.code}_${umeng.channel}.apk" />

                <!-- Signs the APK -->
                <echo>Signing final apk...</echo>
                <signjar
                        jar="${out.packaged.file}"
                        signedjar="${out.unaligned.file}"
                        keystore="${key.store}"
                        storepass="${key.store.password}"
                        alias="${key.alias}"
                        keypass="${key.alias.password}"
                        verbose="${verbose}" />

                <!-- Zip aligns the APK -->
                <zipalign-helper
                        in.package="${out.unaligned.file}"
                        out.package="${out.channel.file}" />
                <echo>Release Package: ${out.channel.file}</echo>
            </sequential>
        </do-only-if-not-library>
        <record-build-info />
    </target>

</project>




文件名: SetUMengChannel.java
编译成 SetUMengChannel.jar 使用
使用java是因为,如果你能build apk,就一定能用java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 通过正则表达式修改AndroidManifest.xml中的渠道号
 * @param args
 */
public class SetUMengChannel {

	/**
         * 懒得检查参数了,有需要的请自己加
	 * args[0] AndroidManifest.xml 的文件位置
         * args[1] 渠道号的字符串
	 */
	public static void main(String[] args) {
		String channel = args[1];

		StringBuilder sb = new StringBuilder();
		try {
			File file = new File(args[0]);
			file = new File(file.getAbsolutePath());
			BufferedReader bufReader = new BufferedReader(
					new InputStreamReader(new FileInputStream(file)));
			String str = bufReader.readLine();
			if (str != null) {
				sb.append(str);
			}

			while ((str = bufReader.readLine()) != null) {
				sb.append('\n');
				sb.append(str);
			}

			bufReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		String metaChannel = String
				.format("<meta-data android:name=\"UMENG_CHANNEL\" android:value=\"%s\"/>",
						channel);

		String replaced = sb
				.toString()
				.replaceAll(
						"<meta-data\\s+android:name=\"UMENG_CHANNEL\"\\s+android:value=\".*?\"\\s*/>",
						metaChannel);

		System.out.println(replaced);
	}
}



文件名: build_channel.sh
shell 脚本,要改成bat神马的也很容易

#! /bin/sh

# 从命令行获取渠道号
export UMENG_CHANNEL=$1

# 先重置 AndroidManifset.xml
# 你也可以使用 svn, copy 神马的
git checkout -f AndroidManifest.xml

# 修改AndroidManifset.xml
sh set_channel.sh ${UMENG_CHANNEL} > AndroidManifest.channel.xml
mv AndroidManifest.channel.xml AndroidManifest.xml

# 编译并加上签名
ant -f build_channel.xml release-channel

# 重置 AndroidManifset.xml
git checkout -f AndroidManifest.xml