通过上传的APK文件,解析APK文件内容,获取应用权限包名等
1工具导入:
下载aapt.exe反编译执行程序,放入Java工程资源文件夹下(具体路径自己可定义)
2编写ApkUtil类,获取apk文件信息
public class ApkUtil {
public static final String VERSION_CODE = "versionCode";
public static final String VERSION_NAME = "versionName";
public static final String SDK_VERSION = "sdkVersion";
public static final String TARGET_SDK_VERSION ="targetSdkVersion";
public static final String USES_PERMISSION ="uses-permission";
public static final String APPLICATION_LABEL ="application-label";
public static final String APPLICATION_ICON = "application-icon";
public static final String USES_FEATURE = "uses-feature";
public static final String USES_IMPLIED_FEATURE ="uses-implied-feature";
public static final String SUPPORTS_SCREENS ="supports-screens";
public static final String SUPPORTS_ANY_DENSITY ="supports-any-density";
public static final String DENSITIES = "densities";
public static final String PACKAGE = "package";
public static final String APPLICATION = "application:";
//api ---- os
static Map<String, String> OSVersion = new HashMap<String,String>();
static {
OSVersion.put("3", "1.5");
OSVersion.put("4", "1.6");
OSVersion.put("5", "2.0");
OSVersion.put("6", "2.0.1");
OSVersion.put("7", "2.1");
OSVersion.put("8", "2.2");
OSVersion.put("9", "2.3");
OSVersion.put("10", "2.3.3");
OSVersion.put("11", "3.0");
OSVersion.put("12", "3.1");
OSVersion.put("13", "3.2");
OSVersion.put("14", "4.0");
OSVersion.put("15", "4.0.3");
OSVersion.put("16", "4.1.1");
OSVersion.put("17", "4.2");
OSVersion.put("18", "4.3");
OSVersion.put("19", "4.4");
OSVersion.put("20", "4.4w");
OSVersion.put("21", "5.0");
OSVersion.put("22", "5.1");
OSVersion.put("23", "6.0");
}
private ProcessBuilder mBuilder;
private static final String SPLIT_REGEX = "(: )|(=')|(')|'";
/**
* aapt所在的目录。
*/
// private String mAaptPath ="D:/sdk/sdk/platform-tools/aapt.exe";
private String mAaptPath;
public ApkUtil(String mAaptPath) {
this.mAaptPath=mAaptPath;
mBuilder = new ProcessBuilder();
mBuilder.redirectErrorStream(true);
}
/**
* 返回一个apk程序的信息。
*
* @param apkPath
* apk的路径。
* @return apkInfo 一个Apk的信息。
*/
public ApkInfo getApkInfo(String apkPath) throws Exception {
Process process =mBuilder.command(mAaptPath, "d", "badging",apkPath).start();
InputStream is = null;
is = process.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(is,"utf8"));
String tmp = br.readLine();
try {
if (tmp == null || !tmp.startsWith("package")) {
throw new Exception("参数不正确,无法正常解析APK包。输出结果为:"+ tmp + "...");
}
ApkInfo apkInfo = new ApkInfo();
do {
setApkInfoProperty(apkInfo,tmp);
} while ((tmp = br.readLine()) != null);
return apkInfo;
} catch (Exception e) {
throw e;
} finally {
process.destroy();
closeIO(is);
closeIO(br);
}
}
/**
* 设置APK的属性信息。
*
* @param apkInfo
* @param source
*/
private void setApkInfoProperty(ApkInfo apkInfo, String source) {
if (source.startsWith(PACKAGE)) {
splitPackageInfo(apkInfo, source);
} else if (source.startsWith(SDK_VERSION)) {
apkInfo.setSdkVersion(getPropertyInQuote(source));
apkInfo.setMinSdkVersion(OSVersion.get(getPropertyInQuote(source)));
} else if (source.startsWith(TARGET_SDK_VERSION)) {
apkInfo.setTargetSdkVersion(getPropertyInQuote(source));
} else if (source.startsWith(USES_PERMISSION)) {
apkInfo.addToUsesPermissions(getPropertyInQuote(source));
} else if (source.startsWith(APPLICATION_LABEL)) {
apkInfo.setAppName(getPropertyInQuote(source));
} else if (source.startsWith(USES_FEATURE)) {
apkInfo.addToFeatures(getPropertyInQuote(source));
}
}
/**
* 返回出格式为name: 'value'中的value内容。
*
* @param source
* @return
*/
private String getPropertyInQuote(String source) {
return source.substring(source.indexOf("'") + 1,source.length() - 1);
}
/**
* 分离出包名、版本等信息。
*
* @param apkInfo
* @param packageSource
*/
private void splitPackageInfo(ApkInfo apkInfo, String packageSource){
String[] packageInfo = packageSource.split(SPLIT_REGEX);
apkInfo.setPackageName(packageInfo[2]);
apkInfo.setVersionCode(packageInfo[4]);
apkInfo.setVersionName(packageInfo[6]);
}
/**
* 释放资源。
*
* @param c
* 将关闭的资源
*/
private final void closeIO(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getmAaptPath() {
return mAaptPath;
}
public void setmAaptPath(String mAaptPath) {
this.mAaptPath = mAaptPath;
}
}
3编写ApkInfo类对apk文件信息进行封装操作
public class ApkInfo {
/**
* apk内部版本号
*/
private String versionCode = null;
/**
* apk外部版本号
*/
private String versionName = null;
/**
* apk的包名
*/
private String packageName = null;
/**
* 支持的android平台最低版本号
*/
private String minSdkVersion = null;
/**
* apk所需要的权限
*/
private List<String> usesPermissions = null;
/**
* 支持的SDK版本。
*/
private String sdkVersion;
/**
* 建议的SDK版本
*/
private String targetSdkVersion;
/**
* 应用程序名
*/
private String appName;
/**
* 所需设备特性。
*/
private List<String> features;
public ApkInfo() {
this.usesPermissions = new ArrayList<String>();
this.features = new ArrayList<String>();
}
/**
* 返回版本代码。
*
* @return 版本代码。
*/
public String getVersionCode() {
return versionCode;
}
/**
* @param versionCode
* the versionCode toset
*/
public void setVersionCode(String versionCode) {
this.versionCode = versionCode;
}
/**
* 返回版本名称。
*
* @return 版本名称。
*/
public String getVersionName() {
return versionName;
}
/**
* @param versionName
* the versionName toset
*/
public void setVersionName(String versionName) {
this.versionName = versionName;
}
/**
* 返回支持的最小sdk平台版本。
*
* @return the minSdkVersion
*/
public String getMinSdkVersion() {
return minSdkVersion;
}
/**
* @param minSdkVersion
* the minSdkVersion toset
*/
public void setMinSdkVersion(String minSdkVersion) {
this.minSdkVersion = minSdkVersion;
}
/**
* 返回包名。
*
* @return 返回的包名。
*/
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
/**
* 返回sdk平台版本。
*
* @return
*/
public String getSdkVersion() {
return sdkVersion;
}
public void setSdkVersion(String sdkVersion) {
this.sdkVersion = sdkVersion;
}
/**
* 返回所建议的SDK版本。
*
* @return
*/
public String getTargetSdkVersion() {
return targetSdkVersion;
}
public void setTargetSdkVersion(String targetSdkVersion) {
this.targetSdkVersion = targetSdkVersion;
}
/**
* 返回所需的用户权限。
*
* @return
*/
public List<String> getUsesPermissions() {
return usesPermissions;
}
public void setUsesPermissions(List<String> usesPermission) {
this.usesPermissions = usesPermission;
}
public void addToUsesPermissions(String usesPermission) {
this.usesPermissions.add(usesPermission);
}
/**
* 返回程序的名称标签。
*
* @return
*/
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
/**
* 返回应用程序所需的特性。
*
* @return
*/
public List<String> getFeatures() {
return features;
}
public void setFeatures(List<String> features) {
this.features = features;
}
public void addToFeatures(String feature) {
this.features.add(feature);
}
@Override
public String toString() {
return "ApkInfo [versionCode=" + versionCode + ",\n versionName="
+ versionName + ",\npackageName=" + packageName
+ ",\nminSdkVersion=" + minSdkVersion + ",\n usesPermissions="
+ usesPermissions + ",\nsdkVersion=" + sdkVersion
+ ",\n targetSdkVersion="+ targetSdkVersion
+ ",\n appName=" +appName
+ ",\n features="+features + "]";
}
}
4使用方式:
//获取apk
File appFile = apk文件路径;
//解析apk
ApkInfo apkInfo=null;
if (appFile.exists()) {
//具体路径根据自己情况更改
StringrealPath = request.getRealPath("/WEB-INF/resource/exe/aapt.exe");
ApkUtilapkUtil = new ApkUtil(realPath);
try{
apkInfo=apkUtil.getApkInfo(appFile.getAbsolutePath());
}catch (Exception e) {
e.printStackTrace();
}
}
//获取apk信息
String appName = apkInfo.getAppName();
String appVersionStr =apkInfo.getVersionName();
String appPackageName =apkInfo.getPackageName();
通过上面的思路即可获取用户上传的apk文件的相关信息,该技术主要应用在应用商店的开发,用于对用户上传的apk文件进行信息提取