python调用aapt工具直接获取包名和tagertSdkversion
背景:
每次海外游戏上架都需要符合google的上架规则,其中适配方面tagetSdkversion有硬性要求,比如需要适配安卓q就需要tagetSdkversion达到28,水平太渣的我每次调用aapt工具都需要在cmd中输入大量指令,且aapt dump baging指令会返回大量相关以及无关信息,为了方便过滤相应信息,编写代码直接获取相关信息,排除无关信息
以剑网3指尖江湖的安装包为例
若直接使用aapt工具,返回信息如下图所示
思路:
re模块使用正则表达式过滤无关信息,os模块调用环境变量中的ANDROID_HOME,subprocess创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入、标准输出、标准错误以及返回码等。
我们实际需要的相关信息红框部分,其余都是无关信息,所以需要re模块去过滤出相关信息
代码:
# -*- coding: utf-8 -*- import re import subprocess import os
class ApkInfo: def __init__(self, apk_path): self.apkPath = apk_path self.aapt_path = self.get_aapt() @staticmethod def get_aapt(): if "ANDROID_HOME" in os.environ: root_dir = os.path.join(os.environ["ANDROID_HOME"], "build-tools") for path, subdir, files in os.walk(root_dir): if "aapt.exe" in files: return os.path.join(path, "aapt.exe") else: return "ANDROID_HOME not exist" def get_apk_base_info(self): p = subprocess.Popen(self.aapt_path + " dump badging %s" % self.apkPath, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) (output, err) = p.communicate() match = re.compile("package: name='(\S+)'").match(output.decode()) if not match: raise Exception("can't get packageinfo") package_name = match.group(1) return package_name def get_apk_activity(self): p = subprocess.Popen(self.aapt_path + " dump badging %s" % self.apkPath, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) (output, err) = p.communicate() match = re.compile("launchable-activity: name='(\S+)'").search(output.decode()) if match is not None: return match.group(1) def get_apk_sdkVersion(self): p = subprocess.Popen(self.aapt_path + " dump badging %s" % self.apkPath, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) (output, err) = p.communicate() match = re.compile("sdkVersion:'(\S+)'").search(output.decode()) return match.group(1) def get_apk_targetSdkVersion(self): p = subprocess.Popen(self.aapt_path + " dump badging %s" % self.apkPath, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) (output, err) = p.communicate() match = re.compile("targetSdkVersion:'(\S+)'").search(output.decode()) return match.group(1) if __name__ == '__main__': apk_info = ApkInfo(r"apk文件路径") print("Activity:%s"%apk_info.get_apk_activity()) print("apkName:%s"%apk_info.get_apk_base_info()) print("sdkVersion:%s"%apk_info.get_apk_sdkVersion()) print("targetSdkVersion:%s"%apk_info.get_apk_targetSdkVersion())
在pycharm中直接运行,结果如下图所示