市面上纯Java解析Android SDK的方式其实较为单一,在这里我先列举【apk-parser】这套体系的解决方案
step1:引入依赖
<dependency>
<groupId>net.dongliu</groupId>
<artifactId>apk-parser</artifactId>
<version>2.6.10</version>
</dependency>`
step2:核心工具类(APK信息解析、获取icon图标输出)
import net.dongliu.apk.parser.ApkFile;
import net.dongliu.apk.parser.bean.ApkMeta;
import org.springframework.util.ResourceUtils;
import java.io.*;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
/**
* APK解析工具
*
* @Author: yangshiwen
* @Date: 2021-11-19
*/
public class ApkFileParseUtil {
/**
* 解析apk
*
* @param file
* @return
*/
public static ApkMeta getApkMeta(File file) {
//注释:apk所有信息都在apkMeta类里面。可以输出整个apkMeta来查看跟多详情信息
ApkFile apkFile = null;
if (file.exists() && file.isFile()) {
try {
apkFile = new ApkFile(file);
if (Objects.nonNull(apkFile)) {
return apkFile.getApkMeta();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != apkFile) {
// 注意,此处一定要close,否则进行IO流操作时无法删除当前file
apkFile.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* 解析apk, 拷贝图标到指定url文件的目录下
*
* @param apkIconUrl apk的iconUrl
* @param apkFile apk包文件
* @param packageName apk包所放的项目包路径
* @param imageName 输出的icon名
*/
public static void saveBit(String apkIconUrl, File apkFile, String packageName, String imageName) {
ZipInputStream zin = null;
boolean flag = true;
try {
// 访问apk 里面的文件
ZipFile zf = new ZipFile(apkFile);
InputStream in = new BufferedInputStream(new FileInputStream(apkFile));
zin = new ZipInputStream(in);
ZipEntry ze;
while ((ze = zin.getNextEntry()) != null) {
if (ze.getName().equals(apkIconUrl)) {
InputStream inStream = zf.getInputStream(ze);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while ((len = inStream.read(buffer)) != -1) {
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] data = outStream.toByteArray();
//new一个文件对象用来保存图片,默认保存当前工程根目录
File imageFile = new File(ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX) + File.separator +
packageName + File.separator + imageName);
//创建输出流
FileOutputStream fileOutStream = new FileOutputStream(imageFile);
//写入数据
fileOutStream.write(data);
fileOutStream.close();
outStream.close();
}
}
in.close();
zf.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
zin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
step3:应用落地
- 工具类的调用
public static void main(String[] args) {
ApkMeta apkMeta = getApkMeta(new File("D:\\RunningMetronome.apk"));
System.out.println(apkMeta.getName());
System.out.println(apkMeta.getPackageName());
System.out.println(apkMeta.getIcon());
System.out.println(apkMeta.getVersionName());
System.out.println(apkMeta.getVersionCode());
System.out.println(apkMeta.getLabel());
// 这里传参的packageName是在resource目录下创建的文件名,具体的可以灵活修改
saveBit("res/mipmap-mdpi-v4/rm_launcher.png", new File("D:\\RunningMetronome.apk"), "apk", "apkImage.jpg");
}
![[资源/文件/95db345f9a21f978d98f65f8c0cc3b4e_MD5.png]]
- saveBit工具输出icon到target目录的apk文件下
![[资源/文件/18a0c838961b2b7f3a2707f8b57609a2_MD5.png]]
评论区