import zipfile #导入文件解压模块
import os,sys #导入os模块
import xml.dom.minidom #导入XML相关模块
from xml.dom.minidom import parse #导入XML相关模块
import shutil #导入文件处理模块
iconAttrName = "android:icon"#android的icon
roundIconAttrName = "android:roundIcon"#高版本上会有一个圆形的icon
outPath = sys.path[0]"/packUtil/"#解压目录
zipFileName = "yuanyuan.zip"#源文件的压缩文件
fileName = "yuanyuan"#解压后的文件目录
manifestPath = "/app/src/main/AndroidManifest.xml"#android配置文件目录
resPath = "/app/src/main/res/"#资源文件的目录
replaceLogoName = "ic_launcher.png"#替换的logo名称
replaceRoundLogoName = "ic_launcher_round.png"#替换的圆形logo名称
androidManifestTag = "application"#Android配置清单文件
cmd_gen_apk = "gradlew assembleRelease"#生成android包的命令,生成目录/app/build/outputs/apk/release/app-release.apk,
#找到application里面的根节点,获取到icon和roundicon的对应的图片名称
def parseXmlAndReplaceLogo(xmlPath):
domTree = parse(xmlPath)
rootNode = domTree.documentElement
applicationInfo = rootNode.getElementsByTagName(androidManifestTag)
app = applicationInfo[0]
if app.hasAttribute(iconAttrName):
print(app.getAttribute(iconAttrName))
replaceIcon(app.getAttribute(iconAttrName),1)
if app.hasAttribute(roundIconAttrName):
print(app.getAttribute(roundIconAttrName))
replaceIcon(app.getAttribute(roundIconAttrName),2)
#判断图片的位置,一般是在mipmap中,但是不排除部分开发者的不规范,放在drawable下面
#获取到路径和图片名称
def replaceIcon(dirAndName,type):
if "drawable" in dirAndName:
replaceMipMap(dirAndName.split("/")[1],type,"drawable")
elif "mipmap" in dirAndName:
replaceMipMap(dirAndName.split("/")[1],type,"mipmap")
else:
print("未找到相对应的图片")
#开始替换图片,logo文件只支持png
def replaceMipMap(logoFileName,type,dirstart):
print("开始替换文件..."+logoFileName)
resAllPath = outPath+fileName+resPath
resDirs = os.listdir(resAllPath)
newFileName = replaceLogoName
if type==2:
newFileName = replaceRoundLogoName
for f in resDirs:
if(f.startswith(dirstart)):
print("获取到文件目录:"+f)
print("移除文件:"+resAllPath+f+"/"+logoFileName+".png")
logoFilePath = resAllPath+f+"/"+logoFileName+".png"
if(os.path.exists(logoFilePath)):
os.remove(logoFilePath)
else:
continue
root = os.getcwd()
if(f.endswith("hdpi")):
shutil.copy(root+"/icon/icon-hdpi/"+newFileName,resAllPath+f+"/"+logoFileName+".png")
elif(f.endswith("ldpi")):
shutil.copy(root+"/icon/icon-ldpi/"+newFileName,resAllPath+f+"/"+logoFileName+".png")
elif(f.endswith("mdpi")):
shutil.copy(root+"/icon/icon-mdpi/"+newFileName,resAllPath+f+"/"+logoFileName+".png")
elif(f.endswith("xhdpi")):
shutil.copy(root+"/icon/icon-xhdpi/"+newFileName,resAllPath+f+"/"+logoFileName+".png")
elif(f.endswith("xxhdpi")):
shutil.copy(root+"/icon/icon-xxhdpi/"+newFileName,resAllPath+f+"/"+logoFileName+".png")
elif(f.endswith("xxxhdpi")):
shutil.copy(root+"/icon/icon-xxxhdpi/"+newFileName,resAllPath+f+"/"+logoFileName+".png")
else:
print("未找到对应尺寸的图片替换")
print("替换完成。。。")
#检查java环境配置
def configJavaEnv():
print("检查java环境")
conDomTree = parse("config.xml")
rootNode = conDomTree.documentElement
javaPath = rootNode.getElementsByTagName("javaPath")[0].childNodes[0].data
print("找到java环境位置:"+javaPath)
return javaPath
#写入环境配置
def writeJavaEnvToProperties(value):
file = open("gradle.properties",mode="r+")
testline = "org.gradle.java.home="+value
isConfig = False
for line in file:
if(testline==line.strip()):
isConfig = True
break;
if(not isConfig):
file.writelines("\n"+testline)
file.flush()
file.close()
print("已写入配置文件")
#改变工作目录到android Project目录
def changeDir(workPath):
os.chdir(workPath)
#生成安装包
def genReleaseApk():
os.system(cmd_gen_apk)
print("开始解压压缩包文件...")
file = zipfile.ZipFile(zipFileName,"r")
file.extractall(path=outPath)
file.close()
print("文件解压完毕,查找配置文件AndroidManifest文件...")
xmlFilePath = outPath+fileName+manifestPath
parseXmlAndReplaceLogo(xmlFilePath)#解析xml并替换图标
#配置javahome
gradleJdkPath = configJavaEnv()
print("切换工作目录...")
workPath = sys.path[0]+"/"+fileName
changeDir(workPath)
print("准备写入配置文件...")
writeJavaEnvToProperties(gradleJdkPath)
#生成安装包
genReleaseApk()