【Java】Android解析apk文件中的AndroidManifest.xml

该ApkUtil的主要功能是通过解析AndroidManifest.xml,获取apk的版本号(即versionCode)和名字(versionName)。

import android.util.TypedValue;
import brut.androlib.res.decoder.AXmlResourceParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmlpull.v1.XmlPullParser;

import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class ApkUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApkUtil.class);

    private static final float RADIX_MULTS[] = {0.00390625F, 3.051758E-005F, 1.192093E-007F, 4.656613E-010F};

    private static final String DIMENSION_UNITS[] = {"px", "dip", "sp", "pt", "in", "mm", "", ""};

    private static final String FRACTION_UNITS[] = {"%", "%p", "", "", "", "", "", ""};

    /
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个工具前后用了好多天的时间查阅资料并不断修改才完成。本工具可以用于读取apk包的大量信息,无其他依赖。可以直接通过命令行运行,也可以当作架包使用。 命令行方式使用举例: 获取AndroidManifest.xml文件定义的versionCode: java -jar ApkAnalysis.jar “apk路径” -versionCode 获取apk证书详情: java -jar ApkAnalysis.jar “apk路径” -certs 获取apk证书的第一条的详情: java -jar ApkAnalysis.jar “apk路径” -certs 0 获取证书摘要(百度、高德地图等API需要的那个SHA1): java -jar ApkAnalysis.jar “apk路径” -certs 0 SHA1 获取apk发布者信息: java -jar ApkAnalysis.jar “apk路径” -certs 0 issuer 获取apk声明的权限: java -jar ApkAnalysis.jar “apk路径” -permissions 当作为架包使用时,通过 ApkAnalysis apkAnalysis = ApkAnalysis.getApkReader(apkFilePath); 获取ApkAnalysis的实例,然后就调用对应方法读取即可。相信都会使用自动补全等功能吧?那个会告诉你有哪些可用的方法,这里不例举了。 输入 java -jar ApkAnalysis.jar -help会给出如下提示,请慢慢研究。如果好用,请不吝评价一下,谢谢~至于源码么,会反编译的就反编译吧,我也拦不住的,纯Java写的,还是很好反编译的,也没有代码混淆过。感兴趣愿意一起交流的可以留言问我要,纯粹伸手党就算了。 Apk分析工具 v1.0.7 编译时JDK版本:1.6.0_33 当前JRE版本:1.6.0_33 作者:周骞 发布日期:2015-01-08 --------------------------------------------------- ApkAnalysis [-versionCode] [-versionName] [-packageName]... 可用的选项: -versionCode 版本号 -versionName 版本名称,如1.0.3 -packageName Apk包名 -certs [index] [MD5|SHA1|issuer|subject|validity] 获取证书的信息 -verify 校验apk文件的签名,并列出未通过校验的文件 -permissions 获取apk所需的权限 -features 获取apk所需的特性 -activities [detail] 获取apk所含的Activity -services [detail] 获取apk所含的Service -receivers [detail] 获取apk所含的静态Receiver -content [name] 获取AndroidManifest.xml的内容 -extract 抽取apk文件 -h[elp] 显示此帮助信息 --------------------------------------------------- 如在程序引用本包,方法如下: ApkAnalysis apkAnalysis = ApkAnalysis.getApkReader(apkFilePath); 需要判断apkAnalysis是否为null,为null表示读取失败,不为null时即可调用getXX()获取数据
动态加载 AndroidManifest.xml 文件需要使用反射机制,具体代码如下: ```java public void loadManifest(Context context, String packageName) { try { // 获取 AssetManager 对象 AssetManager assetManager = AssetManager.class.newInstance(); // 反射调用 addAssetPath 方法,将 apk 文件路径添加到 AssetManager Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class); addAssetPath.invoke(assetManager, context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir); // 获取 Resources 对象 Resources resources = new Resources(assetManager, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration()); // 反射调用 parsePackage 方法,解析 apk 文件AndroidManifest.xml 文件 Class<?> packageParserClass = Class.forName("android.content.pm.PackageParser"); Method parsePackage = packageParserClass.getDeclaredMethod("parsePackage", File.class, int.class); Object packageParser = packageParserClass.newInstance(); Object packageObj = parsePackage.invoke(packageParser, new File(context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir), PackageManager.GET_ACTIVITIES); // 反射调用 generateActivityInfo 方法,获取 apk 文件的 Activity 信息 Class<?> packageParser$ActivityClass = Class.forName("android.content.pm.PackageParser$Activity"); Field infoField = packageParser$ActivityClass.getDeclaredField("info"); Class<?> packageUserStateClass = Class.forName("android.content.pm.PackageUserState"); Object defaultUserState = packageUserStateClass.newInstance(); List<?> activities = (List<?>) packageObj.getClass().getField("activities").get(packageObj); for (Object activity : activities) { ActivityInfo info = (ActivityInfo) infoField.get(activity); ComponentName componentName = new ComponentName(packageName, info.name); // 调用 PackageManager 的 addActivity 方法,将 Activity 信息添加到 PackageManager context.getPackageManager().addActivity(componentName, info); } } catch (Exception e) { e.printStackTrace(); } } ``` 这段代码,我们首先获取 AssetManager 对象,然后使用反射调用 addAssetPath 方法,将 apk 文件路径添加到 AssetManager ,接着获取 Resources 对象,使用反射调用 parsePackage 方法,解析 apk 文件AndroidManifest.xml 文件,最后使用反射调用 generateActivityInfo 方法,获取 apk 文件的 Activity 信息,并调用 PackageManager 的 addActivity 方法,将 Activity 信息添加到 PackageManager

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值