采用python进行Android的多渠道打包

背景

背景就是假如有一个.apk安装包,没有源码,不能改里面的代码,但是知道里面的渠道配置是采用的友盟的方式,在androidManifest里面配置的渠道号,问如何才能用脚本实现多渠道打包。

多渠道打包的两种实现方式

1.美团的方案

目前网上流行的都是美团的解决方案,读取配置文件然后在META-INF目录下新建一个空文件,文件名就是渠道号,然后改java代码去获取文件名字,并设置渠道号,这种方案随便一搜一大堆介绍文章,但是并不适合我司的需求,所以这里就不详细描述拉。

2.直接粗暴的方案

哈哈,到底有多粗暴多直接呢,就是反编译apk,然后修改androidManifest里面的

<meta-data android:name="UMENG_CHANNEL" android:value="suibian" /> 

再重新打包出来,是不是简单粗暴直接,就是貌似实现起来有点麻烦。
那就阿西吧,直接上代码吧,你们需要python环境,需要apktool.exe工具,然后就可以愉快的跑起来了。

#!/usr/bin/python
# coding=utf-8
import os
import shutil
import sys
from xml.etree import ElementTree as ET
from xml.etree.ElementTree import SubElement
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import ElementTree
import platform
import re

androidNS = 'http://schemas.android.com/apk/res/android'
curDir = os.getcwd()

def readChannelfile(filename):
    f = file(filename)
    while True:
        line = f.readline().strip('\n')
        if len(line) == 0:
            break
        else:
            channelList.append(line);
    f.close()

def backUpManifest():
    if os.path.exists('./AndroidManifest.xml'):
        os.remove('./AndroidManifest.xml')
    manifestPath = './temp/AndroidManifest.xml'
    shutil.copyfile(manifestPath, './AndroidManifest.xml')

def getCurrDir():
    global curDir
    retPath = curDir
    if platform.system() == 'Darwin':
        retPath = sys.path[0]
        lstPath = os.path.split(retPath)
        if lstPath[1]:
            retPath = lstPath[0]

    return retPath

def getFullPath(filename):
    if os.path.isabs(filename):
        return filename
    currdir = getCurrDir()
    filename = os.path.join(currdir, filename)
    filename = filename.replace('\\', '/')
    filename = re.sub('/+', '/', filename)
    return filename

def modifyChannel(value):
    manifestFile = "./temp/AndroidManifest.xml"
    manifestFile = getFullPath(manifestFile)
    ET.register_namespace('android', androidNS)
    tree = ET.parse(manifestFile)
    root = tree.getroot()

    key = '{' + androidNS + '}name'
    val = '{' + androidNS + '}value'

    appNode = root.find('application')
    if appNode is None:
        return

    metaDataList = appNode.findall('meta-data')

    if metaDataList != None:
        for metaDataNode in metaDataList:
            keyName = metaDataNode.attrib[key]
            if keyName == 'UMENG_CHANNEL' or keyName == 'DC_CHANNEL' or keyName == 'channel_value':
                metaDataNode.set(val, value)
    tree.write(manifestFile,'UTF-8')
    unsignApk = r'./bin/%s_%s_unsigned.apk'% (easyName, value)
    cmdPack = r'java -jar apktool.jar b temp -o %s'% (unsignApk)
    os.system(cmdPack)

    unsignedjar = r'./bin/%s_%s_unsigned.apk'% (easyName, value)
    signed_unalignedjar = r'./bin/%s_%s_signed_unaligned.apk'% (easyName, value)
    signed_alignedjar = r'./bin/%s_%s.apk'% (easyName, value)
    cmd_sign = r'jarsigner -verbose -keystore %s -storepass %s -signedjar %s %s %s'% (keystore, storepass, signed_unalignedjar, unsignedjar, alianame)
    cmd_align = r'zipalign -v 4 %s %s' % (signed_unalignedjar, signed_alignedjar)
    os.system(cmd_sign)
    os.remove(unsignedjar)
    os.system(cmd_align)
    os.remove(signed_unalignedjar)


channelList = []
apkName = 'bbbb.apk'#sys.argv[1]
easyName = apkName.split('.apk')[0]
keystore='./keystore/android_live.jks'
storepass='91yandroid'
alianame='91ylive'
output_apk_dir="./bin"

if os.path.exists(output_apk_dir):
    shutil.rmtree(output_apk_dir)

readChannelfile('./channel')
print '-------------------- your channel values --------------------'
print 'channel list: ', channelList

cmdExtract = r'java -jar apktool.jar d %s -o temp'% (apkName)
os.system(cmdExtract)

backUpManifest()
for channel in channelList:
    modifyChannel(channel)

if os.path.exists('./temp'):
    shutil.rmtree('./temp')
if os.path.exists('./AndroidManifest.xml'):
    os.remove('./AndroidManifest.xml')
print '-------------------- Done --------------------'

骚年们,不用谢,点个赞就好,请叫我雷锋。

作于杭州浮云网络科技有限公司,在给你们一点福利,捕鱼斗地主都能赢红包哟http://www.91y.com/,脑益结合才是王道。这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值