第一篇随笔就此开始。

1. 起源

思路源自于项目开发过程中。需要确认apk文件版本以验证其功能差异以便于定位问题,于是度娘,得到APK信息查看器(APK-info)这个工具,其版本号为0.2。
它能显示apk详细的信息,如下图示:

但它使用不够方便,只能通过双击打开对话框找到apk文件然后显示,或者拖放apk到其图标上打开,不支持拖放至界面打开。它也没有再打开入口,且对中文支持很不好,如右图百度手机卫士apk信息。

2. 原理

析其原理,原来通过aapt.exe解开apk包中AndroidManifest.xml文件来实现信息展示。
而aapt.exe使用方法,网上诸多教程。apk信息尽存于AndroidManifest.xml中,它是加密的xml文件,用aapt之dump命令做个解析尝试,其语法如下:

>aapt dump badging QQ_482.apk

似乎想要的信息都有了……慢着,中文呢?
>aapt dump badging QQ_482.apk

中文显示乱码。乱就乱吧,咱转码!
如何不自己写个类似工具?好,整!

3. 实现

以此为思路,c#实现解析,获取cmd管道输出数据,核心代码如下(为界面响流畅,我置解析入一线程中):

        private void Decoder(object state)
{
if (!File.Exists(this.apkPath))
return;
string aaptPath = Path.Combine(this.appPath, @"tools\aapt.exe");
if (!File.Exists(aaptPath))
aaptPath = Path.Combine(this.appPath, @"aapt.exe");
if (!File.Exists(aaptPath))
{
var handler = AaptNotFoundEvent;
if (handler != null)
handler();
return;
} var startInfo = new ProcessStartInfo(aaptPath);
string args = string.Format("dump badging \"{0}\"", this.apkPath);
startInfo.Arguments = args;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.CreateNoWindow = true;
using (var process = Process.Start(startInfo))
{
var sr = process.StandardOutput;
while (!sr.EndOfStream)
{
infos.Add(sr.ReadLine());
}
process.WaitForExit();
//解析
ParseInfo(sr.CurrentEncoding);
}
}
//application: label='MobileGo™' icon='r/l/icon.png'
if (info.IndexOf("application:") == )
{
string appName = GetKeyValue(info, "label=");
this.AppName = Encoding.UTF8.GetString(currentEncoding.GetBytes(appName));
this.IconPath = GetKeyValue(info, "icon=");
GetAppIcon(this.IconPath);
}

其执行界面如下:

可以看得出,对中文支持,仍然不够友好,即便通过utf-8到默认中文编码转换。
怎么办呢?

4. 改进

而用其直接输出于一外部文件中,中文显示却是正确的:
>aapt dump badging QQshurufa_1991.apk > info.txt

解析输出文件吧!对这种方案,我一开始是抵触的,因为不想额外成生文件;能截用内部cmd管道输出,我就不愿生成外部文件,说是情怀也好洁癖也罢,只是个人喜好。
但目前转码方案尝试无效,就只得用吧,获取输出信息代码如下:

        private void Decoder(object state)
{
if (!File.Exists(this.apkPath))
return;
string aaptPath = Path.Combine(this.appPath, @"tools\aapt.exe");
if (!File.Exists(aaptPath))
aaptPath = Path.Combine(this.appPath, @"aapt.exe");
if (!File.Exists(aaptPath))
{
var handler = AaptNotFound;
if (handler != null)
handler();
return;
} StringBuilder sb = new StringBuilder();
int result = GetShortPathName(aaptPath, sb, );
if (result != )
aaptPath = sb.ToString(); var startInfo = new ProcessStartInfo("cmd.exe");
string dumpFile = Path.GetTempFileName();
//如此费事做中转,只为处理中文乱码
string args = string.Format("/k {0} dump badging \"{1}\" > \"{2}\" &exit", aaptPath, this.apkPath, dumpFile);
startInfo.Arguments = args;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
this.infos.Clear();
using (var process = Process.Start(startInfo))
{
process.WaitForExit();
}
if (File.Exists(dumpFile))
{
//解析
using (var sr = new StreamReader(dumpFile, Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
{
this.infos.Add(line);
}
ParseInfo();
}
try
{
File.Delete(dumpFile);
}
catch
{
}
}
}

好吧,一切正常了……只是其中构建cmd管道脚本,颇为费些工夫。

看看下图中文信息显示,一切正常:

5. 后记

这是我第一篇博客,写代码十数年,虽时时想记录经验与心得,奈何懒惰,至此方忍不住,终于写出来。

其实此例成完成已久,只是近来更做完善,查询资料过程中看到Meteoric_cry的博文:windows下apk查看工具的原理,颇觉异曲同工之妙,而他也因此写了APK Helper这一工具,简单而易用。

本欲置源代码入Github,奈何折腾半天,亦未成功,因此计划暂且搁置。

此工具我置于网上,亦根据需要作不定时更新,如有需要伙伴尽管拿去用,下载地址为:ApkInfo.zip。若小伙伴有其它需要,可留言以待

6. 追加

2017-03-14更新:费了许多工夫,终于传代码至GitHub,今夜可以安睡。项目址为:https://github.com/awei78/ApkInfo
希望有需要的朋友以做参考。或者,咱们一起更完善它,以适合实际需要。

c#调用aapt查看apk文件信息功能实现的更多相关文章

  1. Java环境解析apk文件信息

    概述:Java解析apk文件,获取apk文件里的包名,版本号,图标文件等; 功能:可以提供给windows和linux平台使用; 原理:利用aapt.exe或者aapt这些anroid平台解析apk文 ...

  2. 查看apk文件包名的一些方法

    1,如果有源码 直接将apk包修改为zip,并解压找到AndroidManifest.xml文件,在文件中搜索“package”找到相应的包名 2,使用adb命令 前提是已经下载android SDK ...

  3. 移动测试===利用adb命令查看apk文件包名的一些方法

    前提是已经下载android SDK并配好环境变量! 在控制台输入命令$adb shell pm 可以看到adb shell pm的相关用法,详细信息请自己看输出 要看一个apk文件的相关信息最简单实 ...

  4. c# 借助cmd命令解析apk文件信息

    借助aapt.exe文件 aapt.exe 解析apk包信息cmd命令: aapt dump badging *.apkaapt d badging *.apk >1.txt(保存成1.txt文 ...

  5. bbed的使用--查看数据文件信息 & sid信息

    1.得到文件的块大小和数据块个数 在Linux和Unix上,oracle提供了一个小工具dbfsize用于查看文件块大小 (可以参看[ID:360032.1]How to detect and fix ...

  6. Shell脚本查看apk签名信息

    用shell写了一个查看apk签名的脚本.代码很少也很简单 支持递归目录查询 #!/bin/bash #使用方法 ./getcertificate.sh xx.apk get_signature() ...

  7. 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)

    众所周知,通过PackageManager可以获取手机端已安装的apk文件的信息,具体代码如下 PackageManager packageManager = this.getPackageManag ...

  8. ffmpeg查看音频文件信息

    查看音频文件的信息(基于本地路径) import subprocess import json path = r'D:\learn\download\NosVJ60QCIs0b8PVHMPomZJsr ...

  9. [Android Tips] 17. 查看 APK 签名信息

    从 APK 文件中获取签名信息 方法一 $ keytool -list -printcert -jarfile <path of APK> 方法二 解压 APK 文件,释放出 META-I ...

随机推荐

  1. 基于Ubuntu 14.04构建mysql5.6 Docker镜像

    我们的目的是创建一个基于Ubuntu 14.04 的MySQL的 Docker Image,并且在新创建出来的容器里自动启动MySQL服务接受外部连接 步骤: 1. 首先创建一个目录并在目录下创建一个 ...

  2. SQL Server 2008 sp3启用1433端口的方法

    SQL Server 2008 SP3一般的默认端口是1433,但有时候会遇到一些问题导致1433端口无法启用.这是笔者给大家指导如何开启1433端口   工具/原料 SQL Server 2008 ...

  3. Java豆瓣电影爬虫——减少与数据库交互实现批量插入

    节前一个误操作把mysql中record表和movie表都清空了,显然我是没有做什么mysql备份的.所以,索性我把所有的表数据都清空的,一夜回到解放前…… 项目地址:https://github.c ...

  4. 【福利大放送】不止是Android,Github超高影响力开源大放送,学习开发必备教科书

    一.写在前面 最近项目重构,时间贼多,也没什么时间更新博客,个人的开源项目也是多时没有更新了:github地址,然而没有更新不代表我不在乎,后面一有空还是会继续提交的. 还是来冒个泡,给大家献上一些福 ...

  5. Sublime Text3自定义主题

    设置背景色和关键字颜色(Color Scheme 生成器): Color Scheme 生成器地址:http://tmtheme-editor.herokuapp.com/ 首先:点击General- ...

  6. 关于小程序swiper不显示图的那些事

    还有几天快过年了,在这里提前祝大家新年快乐! 今天没事研究了一下小程序,想整个轮播图玩玩,然后开始看看文档https://mp.weixin.qq.com/debug/wxadoc/dev/compo ...

  7. 如何使用Babel将ES6转码为ES5?

    一.前言: 当我们还在沉迷于ES5的时候,殊不知ES6早就已经发布几年了.时代在进步,WEB前端技术也在日新月异,是时候做些改变了! ECMAScript 6(ES6)的发展速度非常之快,但现代浏览器 ...

  8. java 非缓冲与缓冲数据写入比较

    //非缓冲计时package com.swust; import java.io.*; /* *功能:创建一个程序,写10000个随机双精度的数到一个文件中,同时测试运用缓冲和非缓冲技术 * 进行这种 ...

  9. 一篇知乎的故事 - javascript技术贴

    前言 就像文章题目所示,本文的发表源于知乎的一篇文章.文章链接如下:如果你想靠前端技术还房贷,你不能连这个都不会.这篇文章是群里水群时别人发的,像我这样的菜鸟角色才不会逛知乎~~~.这篇文章主要是讲了 ...

  10. 为什么使用enable_shared_from_this——shared_ptr两类错误

    在使用C++实现弱回调时,订阅者应当维护一系列发布者的weak_ptr,而发布者注册回调时要传出this的shared_ptr指针,流行的实现方法是使用std::enable_shared_from_ ...