当我们上传apk或者ipa文件的时候是要读取到里面的一些信息的,而对于未知的apk或者ipa,我们无法直接获取其中的包名、应用名、图标等,这时候通过工具类来获取信息就很有必要了。在这里,我总结了一下读取apk,ipa文件的代码和使用方法,大家可以参考下,取其精华、去其糟粕,以便适用于自己的需求。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 首先看一下使用到的工具
环境:Linux
apktool是google提供的apk编译工具,需要Java运行环境,推荐使用JDK1.6或者JDK1.7;dd-plist-1.16这个jar包需要JDK1.5以上。
所以,建议JDK环境1.6以上。
解析apk:使用windows开发环境的时候直接下载aapt.exe即可
(1)aapt
(2)apktool
(3)apktool.jar (google提供)
解析ipa:
(1)dd-plist-1.16.jar(google提供)
(2)python 2.6
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 解析apk
对于apk的解析,我第一个想到的是导入相应的jar包,然后用一些代码就可以读取出来,这样的话就比较方便简单。事实上,这样做的确是可以读取到一些信息的,比如说apk的包名、版本号、版本名,但是对于apk的名称和图标就读取不到了,显然这个不能满足于我们的要求。所以,我希望可以找到一种能够读取尽量多信息的方法,通过在网上查询比较,我选择了aapt这个工具。尽管aapt工具很烦人,比我之前说的导jar包的方式繁琐很多,但是我们需要解析未知apk的图标,名称,不得不使用这个aapt工具了。
2.1 在Linux下安装aapt工具
下载apktool
# wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool
下载apktool_2.2.1.jar并且重命名为apktool.jar
# wget http://connortumbleson.com/apktool/apktool_2.2.1.jar
# mv apktool_2.2.1.jar apktool.jar
下载aapt
http://connortumbleson.com/apktool/aapt/linux/aapt
新建/usr/local/apktool文件夹,将apktool,apktool.jar和aapt移进来
# mv apktool apktool.jar aapt /usr/local/apktool
赋予apktool,apktool.jar和aapt可执行权限
# chmod +x apktool apktool.jar aapt
将apktool加入环境变量,修改/etc/profile,在最后一行添加如下内容
export PATH="$PATH:/usr/local/apktool"
使环境变量立即生效
# source /etc/profile
使用aapt工具时可能报如下错误
aapt: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by aapt)
这是因为缺少glibc-2.14,安装一下就好了
# wget http://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.gz
# tar zxvf glibc-2.14.tar.gz
# cd glibc-2.14
# mkdir build
# cd build
# ../configure --prefix=/opt/glibc-2.14
# make -j4
# make install
修改/etc/profile,在最后一行添加如下内容
export LD_LIBRARY_PATH=/opt/glibc-2.14/lib:$LD_LIBRARY_PATH
使环境变量立即生效
# source /etc/profile
给aapt相应权限
# chmod 755 aapt
apktool和aapt简单使用方法
# apktool d /data/test.apk //反编译apk
# aapt dump badging /data/test.apk //查看apk包详细信息
2.2 建两个实体类
这两个实体类封装了要解析apk的一些信息字段,比如说apk的包名、版本号、版本名、所需设备特性等。
代码如下:
/*** apk实体信息*/
public classApkInfo {public static final String APPLICATION_ICON_120 = "application-icon-120";public static final String APPLICATION_ICON_160 = "application-icon-160";public static final String APPLICATION_ICON_240 = "application-icon-240";public static final String APPLICATION_ICON_320 = "application-icon-320";/*** apk内部版本号*/
private String versionCode = null;/*** apk外部版本号*/
private String versionName = null;/*** apk的包名*/
private String packageName = null;/*** 支持的android平台最低版本号*/
private String minSdkVersion = null;/*** apk所需要的权限*/
private List usesPermissions = null;/*** 支持的SDK版本。*/
privateString sdkVersion;/*** 建议的SDK版本*/
privateString targetSdkVersion;/*** 应用程序名*/
privateString applicationLable;/*** 各个分辨率下的图标的路径。*/
private MapapplicationIcons;/*** 程序的图标。*/
privateString applicationIcon;/*** 暗指的特性。*/
private ListimpliedFeatures;/*** 所需设备特性。*/
private Listfeatures;/*** 启动界面*/
privateString launchableActivity;publicApkInfo() {this.usesPermissions = new ArrayList();this.applicationIcons = new HashMap();this.impliedFeatures = new ArrayList();this.features = new ArrayList();
}/*** 返回版本代码。
*
*@return版本代码。*/
publicString getVersionCode() {returnversionCode;
}/***@paramversionCode
* the versionCode to set*/
public voidsetVersionCode(String versionCode) {this.versionCode =versionCode;
}/*** 返回版本名称。
*
*@return版本名称。*/
publicString getVersionName() {returnversionName;
}/***@paramversionName
* the versionName to set*/
public voidsetVersionName(String versionName) {this.versionName =versionName;
}/*** 返回支持的最小sdk平台版本。
*
*@returnthe minSdkVersion*/
publicString getMinSdkVersion() {returnminSdkVersion;
}/***@paramminSdkVersion
* the minSdkVersion to set*/
public voidsetMinSdkVersion(String minSdkVersion) {this.minSdkVersion =minSdkVersion;
}/*** 返回包名。
*
*@return返回的包名。*/
publicString getPackageName() {returnpackageName;
}public voidsetPackageName(String packageName) {this.packageName =packageName;
}/*** 返回sdk平台版本。
*
*@return
*/
publicString getSdkVersion() {returnsdkVersion;
}public voidsetSdkVersion(String sdkVersion) {this.sdkVersion =sdkVersion;
}/*** 返回所建议的SDK版本。
*
*@return
*/
publicString getTargetSdkVersion() {returntargetSdkVersion;
}public voidsetTargetSdkVersion(String targetSdkVersion) {this.targetSdkVersion =targetSdkVersion;
}/*** 返回所需的用户权限。
*
*@return
*/
public ListgetUsesPermissions() {returnusesPermissions;
}public void setUsesPermissions(ListusesPermission) {this.usesPermissions =usesPermission;
}public voidaddToUsesPermissions(String usesPermission) {this.usesPermissions.add(usesPermission);
}/*** 返回程序的名称标签。
*
*@return
*/
publicString getApplicationLable() {returnapplicationLable;
}public voidsetApplicationLable(String applicationLable) {this.applicationLable =applicationLable;
}/*** 返回应用程序的图标。
*
*@return
*/
publicString getApplicationIcon() {returnapplicationIcon;
}public voidsetApplicationIcon(String applicationIcon) {this.applicationIcon =applicationIcon;
}/*** 返回应用程序各个分辨率下的图标。
*
*@return
*/
public MapgetApplicationIcons() {returnapplicationIcons;
}public void setApplicationIcons(MapapplicationIcons) {this.applicationIcons =applicationIcons;
}public voidaddToApplicationIcons(String key, String value) {this.applicationIcons.put(key, value);
}public voidaddToImpliedFeatures(ImpliedFeature impliedFeature) {this.impliedFeatures.add(impliedFeature);
}/*** 返回应用程序所需的暗指的特性。
*
*@return
*/
public ListgetImpliedFeatures() {returnimpliedFeatures;
}public void setImpliedFeatures(ListimpliedFeatures) {this.impliedFeatures =impliedFeatures;
}/***