PHP获取安卓APK文件的信息(名称、版本、图标文件等)

news2025/1/13 6:31:11

最近业务需要一个功能,后台上传apk文件,需要自动获取到此apk的名称、版本、图标、PackageName等信息。网上查了很多资料,看大家都是使用aapt工具来获取信息,不过不能获取图标。后来发现有大神已经封装了一套组件【php-apk-parser】可以使用,在此总结一下,方便大家使用。

第一种方式:使用aapt工具获取apk的名称、版本等信息

我这边环境是docker,内核是64位的centos,因此将下载的64位aapt工具及所需依赖库放到docker容器内即可(使用linux服务器与此同样的操作)。

使用docker cp命令,将文件拷贝到容器内(工具及依赖百度网盘下载链接会放到文章末尾):

docker cp ./aapt 20108524628e:/usr/bin/
docker cp ./libc++.so 20108524628e:/usr/lib/

进入容器输入aapt命令进行验证:

接下来就是在PHP中使用exec函数执行“aapt dump badging 【apk文件路径】”,这样即可获取到基础信息 

大家可以参照网上的一些教程获取相关信息,如:https://blog.csdn.net/xiojing825/article/details/72772905

声明:我对安卓apk并不了解,只是大致看了下相关资料,以下结论是结合自身能力得出,若有错误之处,恳请指正,谢谢!】不过使用aapt方式获取图标icon很麻烦,获取到png格式的还能处理,获取到xml格式的就不好处理了。因为在安卓8之后,为了适配各种分辨率,图标指向了xml格式的文件,还涉及到分层什么的,我试验了几次用aapt遇到xml格式的就没办法获取到图标了。

第二种方式:使用php-apk-parser扩展组件获取apk的名称、版本、图标文件等信息

有大神把java使用的apk-parser工具做了封装,PHP也可以使用了,因此第二种方式就是使用这个扩展来解析apk,大神推荐的安装方式是使用composer来安装,且对PHP版本有要求(7.3以上或8.0):

如果你的PHP版本是8.0以上可以直接访问此链接参考安装:

GitHub - tufanbarisyildirim/php-apk-parser: Read basic info about an application from .apk file.

但是我这边PHP版本是7.2,所以我就下载了代码看了下,发现大神代码里使用了Union types(Union types是PHP 8.0引入的一个新特性,允许用管道符|来指定一个参数或者变量可以接受多种类型。),因此我就粗暴的修改了一下大神的代码,把7.2版本不支持的语法去掉就可以使用了。(修改后的代码已打包放到文件末尾,只修改了lib下的ApkParser

大神代码下载后结构是这样(examples中是使用实例,还有自动加载入口autoload.php):

我这里使用的是Yii2框架,因为无法使用composer,我就自己导入到vendor文件夹中了。

和我一样的小伙伴可以这么做:

  1. 将php-apk-parser-master\lib中的ApkParser文件夹拷贝到vendor文件中
  2. 修改vendor\yiisoft\extensions.php 文件,增加配置如下:
    'ApkParser' =>
        array (
            'name' => 'ApkParser',
            'version' => '0.1.0.0',
            'alias' =>
                array (
                    '@ApkParser' => $vendorDir . '/ApkParser',
            ),
    ),

这样即可使用:

引用:
use ApkParser\Parser;


封装的方法:
/**
     * @param $apkPath *apk文件路径 ./aa/bb/cc.apk
     * @param $iconRoute *icon文件目标存放区域(从apk中拷贝出来) ./aa/bb
     * @param $prefix *文件前缀,防止多个文件重名
     * @return array
     * @throws \ApkParser\Exceptions\XmlParserException
     * @time 2024/11/28 14:05
     * @author zsh
     */
    public static function getApkInfo($apkPath, $iconRoute, $prefix = '')
    {
        if(empty($prefix)){
            $prefix = date('YmdHis').'_'.rand(10000, 99999).'_';
        }

        $return = [];

        $apk = new Parser($apkPath, ['manifest_only' => false]);
        $manifest = $apk->getManifest();

        $return['package_name'] = $manifest->getPackageName();
        $return['version'] = $manifest->getVersionName();

//        echo "Package Name      : " . $manifest->getPackageName() . "" . PHP_EOL;
//        echo "Version           : " . $manifest->getVersionName() . " (" . $manifest->getVersionCode() . ")" . PHP_EOL;
//        echo "Min Sdk Level     : " . $manifest->getMinSdkLevel() . "" . PHP_EOL;
//        echo "Min Sdk Platform  : " . $manifest->getMinSdk()->platform . "" . PHP_EOL;
//        echo "Target Sdk Level     : " . $manifest->getTargetSdkLevel() . "" . PHP_EOL;
//        echo "Target Sdk Platform  : " . $manifest->getTargetSdk()->platform . "" . PHP_EOL;

        $application = $manifest->getApplication();

        $labelResourceId = $application->getLabel();
        $appLabel = $apk->getResources($labelResourceId);

        $apkName = '';
        if(!empty($appLabel)){
            if(count($appLabel) > 1){
                $apkName = end($appLabel);
            }else{
                $apkName = $appLabel[0];
            }
        }

        $return['apk_name'] = $apkName;

        $resourceId = $application->getIcon();
        $resources = $apk->getResources($resourceId);

        $return['apk_icon_path'] = '';

        foreach ($resources as $resource) {
            // 获取图标文件
            $fileName = basename($resource);
            $extension = pathinfo($fileName, PATHINFO_EXTENSION);
            $extension = strtoupper($extension);
            if($extension == 'PNG' || $extension == 'WEBP' || $extension == 'JPG'){
                $iconFile = $iconRoute.'/'.$prefix.$fileName;
                $result = file_put_contents($iconFile, $apk->getStream($resource));
                if($result){
                    $return['apk_icon_path'] = $iconFile;
                    break;
                }
            }
//            echo '<img src="data:image/png;base64,', base64_encode(stream_get_contents($apk->getStream($resource))), '" />';
        }

        return $return;
    }

   下载链接: https://pan.baidu.com/s/1XlRhP_0WDKIEINnnE8CJKw 提取码: bzaf 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249706.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

扫雷-完整源码(C语言实现)

云边有个稻草人-CSDN博客 在学完C语言函数之后&#xff0c;我们就有能力去实现简易版扫雷游戏了&#xff08;成就感满满&#xff09;&#xff0c;下面是扫雷游戏的源码&#xff0c;快试一试效果如何吧&#xff01; 在test.c里面进行扫雷游戏的测试&#xff0c;game.h和game.c…

Docker:在 ubuntu 系统上生成和加载 Docker 镜像

本文将介绍在 ubuntu系统上进行 Docker 镜像的生成和加载方法和代码。 文章目录 一、下载和安装 docker二、加载 docker 文件三、保存你的镜像四、将镜像上传到云端并通过连接下载和加载 Docker 镜像五、Docker 容器和本地的文件交互5.1 从容器复制文件到本地宿主机5.1.1 单个文…

【排序算法】之快速排序篇

思想&#xff1a; 分而治之&#xff0c;通过选定某一个元素作为基准值&#xff0c;将序列分为两部分&#xff0c;左边的序列小于基准值&#xff0c;右边的序列大于基准值&#xff0c; 然后再分别将左序列和右序列进行递归排序&#xff0c;直至每部分有序。 性质&#xff1a;这…

Unity中的数学应用 之 角色移动中单位化向量的妙用 (小学难度)

最近准备从简单到困难跟几个教程用以加强自己的业务能力&#xff0c;相信很多小伙伴都做过胡闹厨房这一个案例&#xff0c;其实这个案例比较初级&#xff0c;但是也包含了很多平常可能注意不到小细节&#xff0c;所以我就以它为举例&#xff0c;拓展其中的数学知识 CodeMonkey教…

远程视频验证如何改变商业安全

如今&#xff0c;商业企业面临着无数的安全挑战。尽管企业的形态和规模各不相同——从餐厅、店面和办公楼到工业地产和购物中心——但诸如入室盗窃、盗窃、破坏和人身攻击等威胁让安全主管时刻保持警惕。 虽然传统的监控摄像头网络帮助组织扩大了其态势感知能力&#xff0c;但…

简释下oracle的set define的使用场景

我们在使用oracle的时候&#xff0c;有些菜单表存在url字段&#xff0c;url字段中存在这&字符。但我们通过sql语句进行插入表记录的时候&#xff0c;数据库会提示要我们输入变量值。这个时候有些人难免会不知所措&#xff0c;今天告诉大家一个非常简单的办法解决。 一、问…

在ACK集群中自动化执行Ray Job

企业在管理集群资源时面临的主要挑战是任务量庞大而资源有限。为解决这一问题&#xff0c;需要优先将资源分配给关键部门或个人&#xff0c;并保持高度的灵活性以随时调整资源分配。本文将介绍如何提高企业集群资源的利用率&#xff0c;并通过统一的任务管理平台自动化处理来自…

分布式锁的实现原理

作者&#xff1a;来自 vivo 互联网服务器团队- Xu Yaoming 介绍分布式锁的实现原理。 一、分布式锁概述 分布式锁&#xff0c;顾名思义&#xff0c;就是在分布式环境下使用的锁。众所周知&#xff0c;在并发编程中&#xff0c;我们经常需要借助并发控制工具&#xff0c;如 mu…

【北京迅为】iTOP-4412全能版使用手册-第十九章 搭建和测试TFTP服务器

iTOP-4412全能版采用四核Cortex-A9&#xff0c;主频为1.4GHz-1.6GHz&#xff0c;配备S5M8767 电源管理&#xff0c;集成USB HUB,选用高品质板对板连接器稳定可靠&#xff0c;大厂生产&#xff0c;做工精良。接口一应俱全&#xff0c;开发更简单,搭载全网通4G、支持WIFI、蓝牙、…

webrtc 3A移植以及实时处理

文章目录 前言一、交叉编译1.Pulse Audio webrtc-audio-processing2.交叉编译 二、基于alsa进行实时3A处理1.demo源码2.注意项3.效果展示 总结 前言 由于工作需要&#xff0c;硬件3A中的AEC效果实在太差&#xff0c;后面使用SpeexDSP的软3A&#xff0c;效果依旧不是很好&#…

Python学习第十天--处理CSV文件和JSON数据

CSV&#xff1a;简化的电子表格&#xff0c;被保存为纯文本文件 JSON&#xff1a;是一种数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;以JavaScript源代码的形式将信息保存在纯文本文件中 一、csv模块 CSV文件中的每行代表电…

Layui表格的分页下拉框新增“全部”选项

1、首先需要从后端接口获取表格的全部数据长度&#xff0c;这里以100为例。 2、根据请求到的数据进行表格的渲染。示例代码&#xff1a; let pageSize 5 let pageNo 1 let count 100 table.render({elem: XXX,done: function(res, curr, count){pageNo curr; // 将当前选…

CBK7运营安全

1 运营部门的角色 ​ prudent man、due care&#xff08;按要求执行&#xff09;VS due diligence&#xff08;承担管理者责任&#xff09; ​ 应尽关注&#xff1a;执行了负责任的动作降低了风险。 ​ 应尽职责&#xff1a;采取了所有必要的安全步骤以了解公司或个人的实际风…

AIGC引领金融大模型革命:未来已来

文章目录 金融大模型的应用场景1. **金融风险管理**2. **量化交易**3. **个性化投资建议**4. **金融欺诈检测和预防**5. **智能客户服务** 金融大模型开发面临的挑战应对策略《金融大模型开发基础与实践》亮点内容简介作者简介获取方式 在AIGC&#xff08;Artificial Intellige…

Linux操作系统2-进程控制3(进程替换,exec相关函数和系统调用)

上篇文章&#xff1a;Linux操作系统2-进程控制2(进程等待&#xff0c;waitpid系统调用&#xff0c;阻塞与非阻塞等待)-CSDN博客 本篇代码Gitee仓库&#xff1a;Linux操作系统-进程的程序替换学习 d0f7bb4 橘子真甜/linux学习 - Gitee.com 本篇重点&#xff1a;进程替换 目录 …

Java函数式编程+Lambda表达式

文章目录 函数式编程介绍纯函数Lambda表达式基础Lambda的引入传统方法1. 顶层类2. 内部类3. 匿名类 Lambda 函数式接口&#xff08;Functional Interface&#xff09;1. **函数式接口的定义**示例&#xff1a; 2. **函数式接口与Lambda表达式的关系**关联逻辑&#xff1a;示例&…

DI依赖注入详解

DI依赖注入 声明了一个成员变量&#xff08;对象&#xff09;之后&#xff0c;在该对象上面加上注解AutoWired注解&#xff0c;那么在程序运行时&#xff0c;该对象自动在IOC容器中寻找对应的bean对象&#xff0c;并且将其赋值给成员变量&#xff0c;完成依赖注入。 AutoWire…

自动化运维(k8s)之微服务信息自动抓取:namespaceName、deploymentName等全解析

前言&#xff1a;公司云原生k8s二开工程师发了一串通用性命令用来查询以下数值&#xff0c;我想着能不能将这命令写成一个自动化脚本。 起初设计的 版本一&#xff1a;开头加一条环境变量&#xff0c;执行脚本后&#xff0c;提示输入&#xff1a;需要查询的命名空间&#xff0c…

[Python/网络安全] Git漏洞之Githack工具基本安装及使用详析

前言 本文仅分享Githack工具基本安装及使用相关知识&#xff0c;不承担任何法律责任。 Git是一个非常流行的开源分布式版本控制系统&#xff0c;它被广泛用于协同开发和代码管理。许多网站和应用程序都使用Git作为其代码管理系统&#xff0c;并将其部署到生产环境中以维护其代…

解决水库安全监测难题 长期无外接电源 低功耗设备智能化监测系统

解决水库安全监测难题 长期无外接电源 低功耗设备智能化监测系统 国内某水库安全监测项目需要监测点分散&#xff0c;且无外接供电。项目年限为4年&#xff0c;不允许使用太阳能电板。因此&#xff0c;我们需要设备具备低功耗且内置电池的功能。为了满足客户的要求&#xff0c;…