在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中可找到。