为Android应用增加渠道信息 自动化不同渠道的打包过程的使用详解
为什么需要在应用程序中增加渠道信息?
android应用的发布需要面对各种各样的市场,我们称之为渠道。有的时候,我们需要知道应用是从哪个渠道下载的。比如,我们可能需要统计哪些市场带来的用户量比较大。再比如,我们可能有一些盈利需要和具体的渠道进行分成。这些都是统计渠道的信息。
一般如何在应用中加入渠道信息?
为了统计渠道信息,就不得不在程序的某个地方加入渠道的信息,然后针对不同的渠道打不同的包。一般可以在manifest文件中加入渠道编号,而不直接写在代码中。这样做的好处是,可以针对不同渠道,自动化去修改manifest文件中的渠道编号,然后自动为该渠道打包。
manifest文件支持meta data标签,建议使用这种自定义标签。例如下面的文件片段。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versioncode="x"
android:versionname="x.x.x"
package="com.xxx">
……
<application android:icon="@drawable/icon"
android:label="@string/app_name">
……
<meta-data android:name="channel" android:value="c_001" />
</application>
</manifest>
在这段代码示例中,我们在application节点下增加了一个meta-data标签,名称是channel,值是c_001,是我们规定的一个渠道的编号。
为不同的渠道打包,就要手工或者自动化修改c_001成为c_002、c_003等等其它我们定义的渠道编号,然后再打不同的包。
程序如何读取打包的渠道编号?
在程序代码中,可以读取manifest文件中定义的meta-data。以下为代码实例。
public static string getchannelcode(context context) {
string code = getmetadata(context, "channel");
if (code != null) {
return code;
}
return "c_000";
}
private static string getmetadata(context context, string key) {
try {
applicationinfo ai = context.getpackagemanager().getapplicationinfo(
context.getpackagename(), packagemanager.get_meta_data);
object value = ai.metadata.get(key);
if (value != null) {
return value.tostring();
}
} catch (exception e) {
//
}
return null;
}
如何自动化打包过程?
我们想要自动化针对不同渠道打不同包的过程,有两种情况。一种是有源代码的情况,一种是没有源代码只有apk文件的情况。
有源代码的情况。
有源代码的情况比较简单。我们可以使用自动化脚本工具进行打包,比如使用ant。
使用ant打包,有两个关键问题:一个是要在ant中支持for循环,以自动做多次打包动作;一个是如何能够在ant中修改manifest文件,以支持不同的市场。只要解决了这两个关键问题,配合ant的基本功能,就能实现我们的要求了。
在ant中支持循环
在ant的核心包里没有相关的for循环的task,要下载相应的扩展包。可以使用开源的ant-contrib包。
下载地址:http://ant-contrib.sourceforge.net/
下载完成后,把ant-contrib里的lib包复制到安装好的ant库apache-ant-xxx\lib下面,就可以使用了。
具体如何使用,可以参考ant-contrib的官方网站。
在ant中修改manifest文件
利用 ant 扩展任务所提供的 <replaceregexp> 任务,还可以实现基于正则表达式的替换。
例如,要将androidmanifest.xml文件中的行首“c_001”字符串替换为“c_002”,可以使用如下ant脚本:
<replaceregexp
file="androidmanifest.xml"
byline="true"
match="c_001 "
replace="c_002"
/>
<replaceregexp> 任务很强大,这只是一个简单的例子。
只有apk文件的情况。
如果没有源代码,只有apk文件,事情相对就稍微复杂一些了。我们知道有一个开源的apktool,可以对apk文件进行反编译,或者重新打包。具体的请参考apktool的官方文件。
有了apktool的帮助,就可以有一个基本思路。
先使用apktool对apk文件进行反编译,反编译出来资源文件和androidmanifest.xml文件。
使用脚本代码修改androidmanifest.xml文件中的渠道id文本。
使用apktool重新打包成apk文件。
使用jarsigner工具为apk文件签名。
只要反复重复2-4步骤,即可对不同的渠道打出不同的apk安装包。
根据这个思路,具体的实现就相对简单了。可以写成一个bat脚本文件,也可以写成java应用程序。