现在的位置: 首页 > 综合 > 正文

java环境下从apk文件中抽取应用图标

2014年02月03日 ⁄ 综合 ⁄ 共 2720字 ⁄ 字号 评论关闭

       在android环境下提取应用的图标因为有专门的接口是比较简单,但是在纯java环境下事情好像变的有点复杂了,不过借助android的反汇编工具aapt.exe这个问题就可以解决。废话不多说,直接上代码!

package com.yg.lichao;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * 抽取apk程序的应用图标
 * @author lichao
 * Jan 12, 2013 -- 9:51:54 AM
 */
public class GetApkIcon {

	/**
	 * 抽取apk程序的应用图标
	 * @param apkPath apk的路径名
	 * @param aaptPath aapt工具的全路径名
	 * @param outDir 图标的输出路径
	 */
	public static void getApkIcon(String apkPath, String aaptPath, String outDir){
		String iconName = getIconName(apkPath, aaptPath);
		File iconOutDir = new File(outDir);
		if(!iconOutDir.exists()){
			iconOutDir.mkdirs();
		}
		getIcon(apkPath, iconName, outDir + iconName);
	}
	
	/**
	 * 获取图标的名字
	 */
	private static String getIconName(String apkPath, String aaptPath) {
		String iconName = "";
		try {
			/**
			 * Runtime类封装了运行时的环境。每个Java应用程序都有一个Runtime 类实例,使应用程序能够与其运行的环境相连接。
             * 一般不能实例化一个Runtime对象,应用程序也不能创建自己的Runtime类实例,但可以通过getRuntime方法获取当前Runtime运行时对象的引用。
			 */
			Runtime rt = Runtime.getRuntime();
			String order = aaptPath + "aapt.exe" + " d badging \"" + apkPath + "\"";
			Process proc = rt.exec(order);
			InputStream inputStream = proc.getInputStream();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
			String line = null;
			while((line = bufferedReader.readLine()) != null){
				if(line.contains("application:")){//application: label='UC浏览器' icon='res/drawable-hdpi/icon.png'
					iconName = line.substring(line.lastIndexOf("/") + 1, line.lastIndexOf("'")).trim().toLowerCase();
					break;
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return iconName;
	}

	/**
	 * 抽取图标
	 */
	private static void getIcon(String apkPath, String iconName, String outPath) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		ZipInputStream zis = null;
		File apkFile = new File(apkPath);
		try {
			fis = new FileInputStream(apkFile);
			zis = new ZipInputStream(fis);
			ZipEntry zipEntry = null;
			while((zipEntry = zis.getNextEntry()) != null){
				String name = zipEntry.getName().toLowerCase();
				if((name.endsWith("/" + iconName) && name.contains("drawable") && name.contains("res")) || 
						(name.endsWith("/" + iconName) && name.contains("raw") && name.contains("res"))){
					fos = new FileOutputStream(new File(outPath));
					byte[] buffer = new byte[1024];
					int n = 0;
					while((n = zis.read(buffer, 0, buffer.length)) != -1){
						fos.write(buffer, 0, n);
					}
					break;
				}
			}
			fos = null;
			zis.closeEntry();
			zipEntry = null;
			System.out.println("图标抽取成功"+outPath);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if (zis != null) {
					zis.close();
				}
				if (fis != null) {
					fis.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

再写个调用方法调用下就可以了:

package com.yg.lichao;

/**
 * 抽取apk程序的应用图标
 * @author lichao
 * Apr 19, 2013 -- 5:30:50 PM
 */
public class Test {

	public static void main(String[] args) {
		GetApkIcon.getApkIcon("G:\\com.sds.android.ttpod_133633.apk", "./src/", "G:\\apkIconPath\\");
	}

}

PS:反汇编工具aapt.exe在android sdk中可找到。 

抱歉!评论已关闭.