Android中使用apk-parser解析apk

一、前言

Apk Parser是一个优秀的解码二进制文件与获取apk各种信息的开源库,具备众多实用的特性:

  • 获取apk各种元数据信息,比如应用名、图标、包名、版本号等
  • 解析二进制XML文件并将其转换为文本格式
  • 从dex文件获取类信息,比如:类名、修饰符等
  • 获取apk签名信息,包括v1、v2签名

不过, Apk Parser无论是该开源库的作者或者是网上有的教程,都只是说java se怎么使用这个开源库,并没有android使用该依赖库的教程,所以,这或许是全网独一份android调用 Apk Parser来解析apk的教程哦

二、Apk Parser需要修改的部分

1、获取apk-parser依赖库
  • 通过gradle来获取
    从开源库作者提供的maven central repo下载链接:
<dependency>
    <groupId>net.dongliugroupId>
    <artifactId>apk-parserartifactId>
    <version>2.6.9version>
dependency>

可以总结出,在Android Studio使用gradle构建系统下载该依赖库的配置: implementation 'net.dongliu:apk-parser:2.6.9'

-或者 直接从github上把整个项目下载下来,集成到你的项目里去
因为apk-parser还需要依赖到以下两个库,需要加进去:

   implementation 'org.bouncycastle:bcprov-jdk15on:1.58'
   implementation 'org.bouncycastle:bcpkix-jdk15on:1.58'
2、把整个项目从github上download下来之后,把/src/main/resources/目录下的两个.ini文件拷贝到assets目录下

Android中使用apk-parser解析apk_第1张图片

3、修改Apk-parser对这两份.ini的读取方式,全局检索,可以搜索到是在net.dongliu.apk.parser.utils.ResourceLoader这个类中,将原代码:
 private static BufferedReader toReader(String path) {
        return new BufferedReader(new InputStreamReader(
                ResourceLoader.class.getResourceAsStream(path)));
    }

修改为:

   private static BufferedReader toReader(String path) {
        InputStream inputStream = null;
        try {
            Context context = ActivityLifecycle.curActivityRef.get();
            if(context != null){
                inputStream = context.getAssets().open(path);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return new BufferedReader(new InputStreamReader(inputStream));
    }

经过上述步骤的配置,android项目就能正常跑了

三、使用教程

1、获取apk元数据
ApkFile apkFile = new ApkFile(apkInfo.getApkPath());
apkFile.setPreferredLocale(Locale.SIMPLIFIED_CHINESE);
ApkMeta apkMeta = apkFile.getApkMeta();
apkInfo.setLabel(apkMeta.getLabel());
apkInfo.setPackageName(apkMeta.getPackageName());
apkInfo.setVersionName(apkMeta.getVersionName());
apkInfo.setVersionCode(String.valueOf(apkMeta.getVersionCode()));
apkInfo.setTargetSdkVersion(apkMeta.getTargetSdkVersion());
apkInfo.setMinSdkVersion(apkMeta.getMinSdkVersion());
2、解析并获取AndroidManifest.xml与其他xml资源文件的内容
try (ApkFile apkFile = new ApkFile(new File(filePath))) {
    String manifestXml = apkFile.getManifestXml();
    String xml = apkFile.transBinaryXml("res/menu/main.xml");
}
3、获取dex的类信息
DexClass[] dexClasses = apkFile.getDexClasses();
if(dexClasses != null && dexClasses.length > 0) {
    for(DexClass dexClass : dexClasses){
        if(dexClass.getClassType().equals("Lcom/ss/android/common/lib/EventUtils;")){
                apkInfo.setHasTodayTopClass(true);
        }else if(dexClass.getClassType().equals("Lcom/qq/gdt/action/GDTAction;")){
                apkInfo.setHasGdtClass(true);
        }else if(dexClass.getClassType().equals("Lcom/alibaba/sdk/android/push/noonesdk/PushServiceFactory;")){
               apkInfo.setHasAlipushClass(true);
       }else if(dexClass.getClassType().equals("Lcom/tendcloud/tenddata/TCAgent;")){
              apkInfo.setHasTalkingDataClass(true);
       }
  }
}
4、获取apk签名信息
List<ApkSigner> apkSingers = apkFile.getApkSingers();
     if(apkSingers != null && apkSingers.size()>0) {
          for (ApkSigner apkSigner : apkSingers) {
              List<CertificateMeta> certificateMetas = apkSigner.getCertificateMetas();
              for (CertificateMeta certificateMeta : certificateMetas) {
                     Log.i("min77", certificateMeta.getCertMd5());
                     if (!TextUtils.isEmpty(certificateMeta.getCertMd5())) {
                          String desc = signatures.optString(certificateMeta.getCertMd5());
                          if(!TextUtils.isEmpty(desc)){
                               apkInfo.setSignatureMd5(certificateMeta.getCertMd5()+"("+desc+")");
                            }else {
                               apkInfo.setSignatureMd5(certificateMeta.getCertMd5());
                            }

                       }
                  }
             }
     }
5、设置首选的Locales

Apk可能针对不同的地区和语言具有不同的信息(标题,图标等),或者我们可以将其称为Locale。 如果未设置语言环境,则使用默认的“ en_US”语言环境(Locale.US)。 您可以通过以下方式设置一个首选语言环境

try (ApkFile apkFile = new ApkFile(new File(filePath))) {
    apkFile.setPreferredLocale(Locale.SIMPLIFIED_CHINESE);
    ApkMeta apkMeta = apkFile.getApkMeta();
}

你可能感兴趣的:(android,android使用apk,parser)