在国内Android常用渠道可能多达几十个,如: 
谷歌市场、腾讯应用宝、百度手机助手、91手机商城、360应用平台、豌豆荚、安卓市场、小米、魅族商店、oppo手机、联想乐商、中兴汇天地、华为、安智、应用汇、木蚂蚁、3G安卓市场(久邦开发者发布系统) 
uc应用商店、苏宁应用、淘宝手机助手、蘑菇市场、搜狗市场、搜狗助手、机锋、易用汇(金立手机)、中国联通沃商、中国移动MM、中国电信天翼、亿优市场、历趣世界、冒泡堂、网讯安卓开发者平台、桌乐、网易、泡椒网、十字猫、酷传、安粉、安卓园、安卓之家 
所以在工作中,当项目开发、测试完毕后就需要针对不同的渠道打出对应的apk安装包。为了统计每个渠道效果,我们可以使用Umeng sdk或者百度的sdk。这些sdk的使用我就不再这里赘述了,请看相应的开发文档即可。本文以友盟统计为例。

批量打包方式一:Gradle方式

我相信现在应该很多开发环境都是AndroidStudio了,对Gradle相对还是熟悉的。如果您使用的是Eclipse也没有关系,用AndroidStudio导入Eclipse工程,或者把gradle配置放在Eclipse工程下(因为AndroidStudio和Eclipse的工程目录有些差别,把对应的目录配置对即可) 
首先我们使用AndroidStudio新建一个工程,名叫AndroidBatchApk,工程结构如下: 
打开AndroidManifest.xml文件 添加友盟的渠道配置如下:

在MainActivity 显示渠道名代码:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MainActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppCompatActivity</span> {</span><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState);setContentView(R.layout.activity_main);String channel = ManifestUtil.getMetaDataFromAppication(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"UMENG_CHANNEL"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//String channel = ManifestUtil.getUmengChannel(this);</span>((TextView) findViewById(R.id.tv_channel)).setText(channel);}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>
<code class="hljs haskell has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><meta-<span class="hljs-typedef" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">data</span></span>android:name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"UMENG_APPKEY"</span>android:value=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Your UMENG_APPKEY"</span> /><meta-<span class="hljs-typedef" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">data</span></span>android:name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"UMENG_CHANNEL"</span>android:value=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"${UMENG_CHANNEL_VALUE}"</span> /> //${<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">UMENG_CHANNEL_VALUE</span>}是个占位符</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
 打开app目录下的build.gradle文件,修改成如下形式:
<code class="hljs livecodeserver has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">apply plugin: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'com.android.application'</span>android {compileSdkVersion <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">22</span>buildToolsVersion <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"22.0.1"</span>packagingOptions {exclude <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'META-INF/NOTICE.txt'</span>exclude <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'META-INF/LICENSE.txt'</span>}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //签名</span>signingConfigs {release {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //storeFile file("../yourapp.keystore")</span>storeFile <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">file</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"keystore_apk.jks"</span>)storePassword <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123456"</span>keyAlias <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"apk"</span>keyPassword <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123456"</span>}}buildTypes {release {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> // 不显示Log</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //buildConfigField "boolean", "LOG_DEBUG", "false"</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //minifyEnabled true //混淆</span>zipAlignEnabled <span class="hljs-constant" style="box-sizing: border-box;">true</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //内存对齐</span>shrinkResources <span class="hljs-constant" style="box-sizing: border-box;">true</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //移除无用的resource文件</span>proguardFiles getDefaultProguardFile(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'proguard-android.txt'</span>), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'proguard-rules.pro'</span>signingConfig signingConfigs.releaseandroid.applicationVariants.all { variant ->def stringsFile = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">new</span> File(variant.outputs[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].processResources.assetsDir, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abc.txt"</span>)stringsFile.mkdir()}applicationVariants.all { variant ->variant.outputs.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">each</span> { output ->def outputFile = output.outputFile<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (outputFile != <span class="hljs-constant" style="box-sizing: border-box;">null</span> && outputFile.name.endsWith(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'.apk'</span>)) {def fileName = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"APK_${releaseTime()}_${variant.productFlavors[0].name}.apk"</span>output.outputFile = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">new</span> File(outputFile.parent, fileName)}}}}}lintOptions {checkReleaseBuilds <span class="hljs-constant" style="box-sizing: border-box;">false</span>abortOnError <span class="hljs-constant" style="box-sizing: border-box;">false</span>ignoreWarnings <span class="hljs-constant" style="box-sizing: border-box;">true</span>}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> // 渠道列表</span>productFlavors {<span class="hljs-title" style="box-sizing: border-box;">_360</span> {}<span class="hljs-title" style="box-sizing: border-box;">_91</span> {}QQ {}appChina {}baidu {}google {}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //.....</span>}productFlavors.all { flavor ->flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]}}def releaseTime() {<span class="hljs-constant" style="box-sizing: border-box;">return</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">new</span> Date().<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">format</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"yyyy-MM-dd HH-mm-ss"</span>, TimeZone.getTimeZone(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"GMT+8"</span>))}dependencies {compile fileTree(dir: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'libs'</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">include</span>: [<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'*.jar'</span>])compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'com.android.support:appcompat-v7:22.2.1'</span>}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li></ul>

上面的配置,我们测试打6个包,分别是google 、_360、 _91、 appChina、 QQ、 baidu

打开cmd命令行 进入工程所在的目录,输入命令:gradle build 不出意外将看到如下成功界面: 

并且在output目录下生成了我们要的apk包(AndroidBatchApk\app\build\outputs\apk) 

现在用的安装我们的生成apk文件,安装google渠道的apk。 

到这里我们就通过gradle方式成功的批量打包了,

时间我们只花费了25秒,但是这是最简单的工程,如果是实际的开发中,我们的项目会很大,打包的时间也会花费很长时间,我现在公司的项目,通过这种方式打包,需要30、40分钟左右,这也是挺长的。时间上并不占优势。但是比我们用工具一个个的打apk强太多了。下面为大家界面一种更高效的打包方式。

批量打包方式二:Python批量打包

首先配置好Python,我用的是Python2.7版本。使用该方式,不把渠道名称放在AndroidManifest.xml 里,而是新建一个空文件,文件名就是渠道名称。该文件放在apk目录的META-INF里。META-INF目录下默认文件列表如下: 

现在我们要解决两个问题:

如果在META-INF目录下新建文件?

我们解决第一个问题。首先我们通过AndroidStudio或者Eclipse打一个正式环境的apk安装包,不需要有渠道。 
然后按照渠道列表 复制出各个渠道的,然后往apk文件里写入文件为渠道名的空文件。我们使用Python代码来实现该功能,代码如下:

<code class="hljs python has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> sys,os,shutil,zipfile,time
apkVersion=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"1.0"</span>
srcFileName=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"source.apk"</span>
destDir=os.path.abspath(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'.'</span>)
file=open(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"channel.txt"</span>)<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">writeChannelToApk</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(filename,channel)</span>:</span>z=zipfile.ZipFile(filename,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'a'</span>,zipfile.ZIP_DEFLATED)empty_channel_file=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"META-INF/channel_{channe}"</span>.format(channe=channel)target_file=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"channel.apk"</span>z.write(target_file,empty_channel_file)z.close()<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"writeChannelToApkchannel"</span>+channel+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">","</span>+filename+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">cpFile</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(srcPath,fileName)</span>:</span>destPath = destDir + os.path.sep + fileName<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> os.path.exists(srcPath) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> os.path.exists(destPath):shutil.copy(srcPath,destPath)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> os.path.exists(srcFileName):<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"sourcefile"</span>+srcFileName+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"notexists"</span>sys.exit(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)start = time.clock()<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> line <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> file:channel=line.strip(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\n'</span>).strip()targetFileName=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"apk_"</span>+channel+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"-"</span>+apkVersion+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">".apk"</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"copyfile:"</span>+targetFileNamecpFile(srcFileName,targetFileName)writeChannelToApk(targetFileName,channel)
end = time.clock()print(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"The function run time is : %.03f seconds"</span> %(end-start))</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul>

上面是我编写的Python代码,根据代码我们需要三个文件,一个我们打出的apk文件(source.apk 当然名字可以改)、一个空apk文件(channel.apk)和渠道列表文件(channel.txt) 目录如下: 

渠道文件内容如下: 
360 
appChina 
wandoujia 
91 
baidu 
QQ 
3G 
eoe 
anzhi 
163 
hiapk 
jifeng 
xiaomi 
meizu 
oppo 
lenovo

在命令行输入:python batch_apk.py 回车

瞬间完成: 

解压文件oppo渠道的apk,看看是不是META-INF下是不是有渠道文件: 

如果读取META-INF下的渠道文件?

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ManifestUtil</span> {</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> String channel;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> String <span class="hljs-title" style="box-sizing: border-box;">getUmengChannel</span>(Context context) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//return getMetaDataFromAppication(context, "UMENG_CHANNEL");</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> getChannel(context);}<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*** 获取META-INFO下面的渠道*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> context*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @return</span>*/</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> String <span class="hljs-title" style="box-sizing: border-box;">getChannel</span>(Context context) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!TextUtils.isEmpty(channel)) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> channel;}ApplicationInfo appinfo = context.getApplicationInfo();String sourceDir = appinfo.sourceDir;ZipFile zipfile = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String start_flag = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"META-INF/channel_"</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {zipfile = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ZipFile(sourceDir);Enumeration<?> entries = zipfile.entries();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (entries.hasMoreElements()) {ZipEntry entry = ((ZipEntry) entries.nextElement());String entryName = entry.getName();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (entryName.contains(start_flag)) {channel = entryName.replaceAll(start_flag, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> channel;}}} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IOException e) {e.printStackTrace();} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (zipfile != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {zipfile.close();} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IOException e) {e.printStackTrace();}}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>;}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li></ul>

我们安装oppo渠道的apk看看能否读取到渠道名: 

通过上面的对比,使用Pyhon往META-INF写入渠道的方式,比gradle方式极大的提高了效率。

资源下载 
Have Fun !

转自:http://blog.csdn.net/johnny901114/article/details/48714849

Android批量打包相关推荐

  1. Android 批量打包 基于Walle的多渠道快速打包自动脚本

    Android 批量打包 基于Walle的多渠道快速打包自动脚本 Android Signature V2 Scheme签名下的新一代渠道包打包神器 github主页:https://github.c ...

  2. Android批量打包 如何一秒内打完几百个apk渠道包

    在国内Android常用渠道可能多达几十个,如:  谷歌市场.腾讯应用宝.百度手机助手.91手机商城.360应用平台.豌豆荚.安卓市场.小米.魅族商店.oppo手机.联想乐商.中兴汇天地.华为.安智. ...

  3. ant 实现批量打包android应用

    很多的应用中需要加上应用推广的统计,如果一个一个的去生成不同渠道包的应用,效率低不说,还有可能不小心弄错了分发渠道,使用ant可以批量生成应用. 一.添加渠道包信息 为了统计渠道信息,就不得不在程序的 ...

  4. android打包工具多渠道批量打包,Android 快速渠道批量打包详解教程-美团多渠道打包方案...

    今天写一篇文章来总结下android批量打渠道包美团版本.之前项目上一直用的是gradle 批量打包方式,那个速度啊真是令人发指,15个渠道得跑上半个小时,出去吃顿饭回来,还在跑.特别是赶上项目上线的 ...

  5. 使用Ant 实现批量打包Android应用

    2019独角兽企业重金招聘Python工程师标准>>> 由于公司运维需要以及应用中需要加上应用推广的统计,往往要对应二三十个渠道,按照正常方法一个一个的去生成不同渠道包的应用,不仅浪 ...

  6. android ant批量打包

    当我们对安卓项目需要分很多渠道打包的时候,批量打包工具无疑是个不二选择,批量打包的方式大概可以分为两种,第一是通过第三方的打包平台,比如360加固宝,这确实是个很好的工具,既提高了源代码的安全性能,又 ...

  7. Android 使用 Ant 批量打包

    1.先下载安装 Ant,下载地址:http://ant.apache.org/ 点击打开链接: 下载完成后,安装: 1)解压Ant,比如解压到D:\download\Ant 2) 我的电脑 -> ...

  8. 简单的android ant 批量打包

    友盟android统计是这样搞的,添加友盟sdk后每打一个平台的包都要修改AndroidManifest.xml里<meta-data android:name="UMENG_CHAN ...

  9. android 美团批量打包,Android 快速渠道批量打包详解教程-美团多渠道打包方案

    今天写一篇文章来总结下android批量打渠道包美团版本.之前项目上一直用的是gradle 批量打包方式,那个速度啊真是令人发指,15个渠道得跑上半个小时,出去吃顿饭回来,还在跑.特别是赶上项目上线的 ...

  10. android 自动批量打包,AutopackingAndroid

    项目说明: 该项目是完成android apk的批量打包工具 支持渠道号替换,资源替换,指定文件修改.修改包名,修改内部包名等等.功能强大程度完全超过友盟等市面主流批量打包工具 作者:冰剑 QQ:21 ...

最新文章

  1. 美团真的让人无语!背调了一个多星期,跟我说背调不通过!问原因,HR说没办法透露,但可以看其它美团机会...
  2. TensorFlow学习笔记之二(使用TensorFlow实现神经网络)
  3. Android Studio使用Google Flutter完整教程
  4. 深度学习浪潮过后,计算机视觉将走向何方
  5. 自动化集成:Jenkins管理工具详解
  6. SLAM GMapping(8)重采样
  7. 截取年月日在hana中怎么写_获取Sting类型格式-日期中的年月日
  8. JavaScript的new关键字执行过程(1)
  9. AnnotationConfigBeanDefinitionParser are only available on JDK 1.5 and higher
  10. zabbix3.2学习笔记(四):设置sendEmail告警动作
  11. 【功能强大的国产Mac办公软件】WPS Office for Mac 1.1.0(1454)
  12. Spring----pom.xml报错Missing artifact org.aspectj:aspectjweaver:jar:1.8.0.M1
  13. 奈奎斯特与香农定理_奈奎斯特定律和香农定理
  14. 中国奶茶成海外消费者“囤货标配”;SK海力士将推进对英特尔大连芯片厂收购 | 美通企业日报...
  15. Alice and the List of Presents CodeForces - 1236B 数学推导
  16. Spring Security 小记 - @Secured(), @PreAuthorize() 及 @RolesAllowed()
  17. springmvc防xss脚本注入攻击,springmvc过滤html和js标签,html和js标签转义
  18. 子线程循环10次,接着主线程循环5次,接着又回到子线程循环10次,接着再回到主线程又循环5次,如此循环50次,请写出程序。
  19. 星际争霸2-数据编辑器-菜鸟入门
  20. Day739.GEO经纬度数据结构自定义数据结构 -Redis 核心技术与实战

热门文章

  1. 前端:一篇彻底搞懂vuex中dispatch与commit的使用及差异
  2. matlab 数组 冒号,matlab中冒号的用法
  3. 【MySQL】MySQL入门笔记
  4. python数据分析实例-python数据分析-11数据分析实战案例
  5. 双料大奖 | 奇点云获评「年度数字化创新最佳实践奖」「年度数字化服务最值得信赖品牌奖」
  6. 题解 2020级HAUT新生周赛(二)
  7. FileZilla查看站点隐藏文件
  8. 思维导图如何转换成图片
  9. 计算机夏令营英语面试,保研经验 | 夏令营面试那些事儿(内含视频)
  10. GHO文件安装全教程