【完美解决方案】纯Java解析Android APK信息,以及icon提取

市面上纯Java解析Android SDK的方式其实较为单一,在这里我先列举【apk-parser】这套体系的解决方案

step1:引入依赖
<dependency>
    <groupId>net.dongliu</groupId>
    <artifactId>apk-parser</artifactId>
    <version>2.5.3</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");
	}

在这里插入图片描述

  • saveBit工具输出icon到target目录的apk文件下
    在这里插入图片描述
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值