php获取apk中文应用名,php提取apk包信息 - 搜知道网 - 搜知道社区,C, iOS,Android,golang 等的知识....

最近在项目中需要使用 php 提取 apk 包的主要信息如包名、应用名称、版本号、入口地址和应用 Icon 等。安卓 apk 的大部分信息都保存在包内的 AndroidManifest.xml 文件中,Icon 则保存在 drawable | drawable-hdpi | drawable-nodpi | drawable-ldpi | drawable-mdpi 这些文件夹中。

使用 php 读取这些信息,网友大头爸爸提供了一种做法:在服务器上安装 java 包 和 反编译工具 apktool ,通过 php 的 exec() 调用 java 命令来反编译 apk 包,然后获取 AndroidManifest.xml 文件的内容,再根据正则表达式匹配出所需要的信息。提取图标则是通过遍历 drawable | drawable-hdpi | drawable-nodpi | drawable-ldpi | drawable-mdpi 这些文件夹来获取一个 size 最大的 Icon 。但是 反编译 相当耗时,不适用于实时程序。(源代码见大头爸爸 博客:http://www.voidcn.com/article/p-wkluywgx-gw.html)。

还有经典的 ApkParser,原理是使用 PHP 的 zip 功能函数直接解压 apk 包而不需要外加 java 或命令行工具来获取 AndroidManifest.xml 文件的内容,然后也是根据正则表达式匹配出所需信息。这种方法执行速度快但是得不到 Icon 。(源代码见该方法作者 Katana's碎碎念 博客:http://blog.katcin.com/archives/69)。

再后来看到了  cn王帅 的方案,觉得挺棒的。他这样做:

1、用 aapt 读取包信息

aapt dump badging ./xxx.apk

2、用 unzip 直接提取需要的图标文件

#解压apk包中指定图片

unzip ./xxx.apk res/drawable-mdpi/icon.png -d /tmp

#将解压出来的图片移到我们需要的位置

mv /tmp/res/drawable-mdpi/icon.png /tmp/temp.png

aapt 包含在 android sdk 中的 build-tools 文件夹,可以把这个文件拷到服务器上单独使用,大小约1.2M。要记得用 chmod 赋予可执行权限。还要注意的是,这个程序是32位环境的程序,64位系统运行可能需要额外安装大概多个扩展包支持才能运行。aapt 命令执行很快,PHP 调用这个命令可以实时返回数据。返回的数据中包含了包名、应用名称、 Icon 在 apk 包中的位置(类似 res/drawable-mdpi/icon.png)。返回的信息是纯文本,不方便 PHP 直接使用,需要将其转为数组。

因为 apk 本身就是 zip 文件重命名而已,所以无需改名,可以直接解压。另外 unzip 可以指定只解压压缩包中某文件,也节省了很多资源。

class Service_Android {

/**

* 获取Apk包信息

* 需要/usr/bin/aapt

*

* @param $apkFile

* @return array

*/

public function getApkInfo($apkFile) {

try {

exec('/usr/bin/aapt dump badging ' . $apkFile, $out, $return);

$apkInfo = array();

foreach($out as $line) {

$lineana = array();

$a = explode(":", $line);

$key = trim($a[0]);

$value = trim($a[1]);

preg_match_all('/((?P\S+)=)?\'(?P.*?)\'/', $value, $matches, PREG_SET_ORDER);

foreach($matches as $match) {

if ($match['key']) {

$lineana[$match['key']] = $match['value'];

} else {

$lineana[] = $match['value'];

}

}

$apkInfo[$key][] = $lineana;

}

//checkRet会把上面读出来的配置整理一下

$ret = $this->checkRet($apkInfo);

} catch(Exception $e) {

echo $e->getMessage();

$ret = array();

}

return $ret;

}

/**

* 从Apk包中提取指定文件,并移到$toFile

*

* @param $apkFile apk文件

* @param $sourceFile apk文件中相应文件路径

* @param $toFile 输出文件

* @return bool

*/

function getFileFromApk($apkFile, $sourceFile, $toDir, $toFile) {

exec("unzip {$apkFile} {$sourceFile} -d {$toDir}", $out, $return);

if (rename("{$toDir}{$sourceFile}", "{$toDir}{$toFile}")) {

exec("rm -rf {$toDir}/*");

return true;

} else {

exec("rm -rf {$toDir}/*");

return false;

}

}

/**

* 辅助函数,处理Apk信息数组

*

* @param $info

* @return mixed

*/

function checkRet($info) {

foreach($info as $key => $lineana) {

if (is_array($lineana)) {

$info[$key] = $this->checkRet($lineana);

if (count($info[$key]) == 1) {

$info[$key] = current($info[$key]);

}

}

}

return $info;

}

}

使用方法:

include('Service_Android.class.php');

$apk = "b.apk";

$iconDir = '../icon/';

$iconFile = 'icon.png';

$android = new Service_Android();

$res = $android->getApkInfo($apk);

$android->getFileFromApk($apk, $res['application']['icon'], $iconDir , $iconFile);

另外,如果你恰巧真是64位系统,使用过程可能会出现以下错误:

错误1:

-bash: /usr/bin/aapt: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory

错误处理:

#查包

yum whatprovides ld-linux.so.2

#安装

yum install -y glibc-2.12-1.149.el6_6.4.i686

错误2:

/usr/bin/aapt: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory

错误处理:

#查包

yum whatprovides */libz.so.1

#安装

yum install -y zlib-1.2.3-29.el6.i686

错误3:

/usr/bin/aapt: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory

错误处理:

yum install -y libstdc++

#查包

yum whatprovides libstdc++.so.6

#安装

yum install -y libstdc++-4.4.7-11.el6.i686

其实上面的那些错误都是缺少 aapt 的扩展包导致的,使用命令:

#查看依赖

ldd /usr/bin/aapt

来查看缺失哪些包,把它们装上就好了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值