import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.progress.ProgressMonitor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/**
* 解压工具类
*
* @author LangK
*
*/
public class UnZipUtil {
private static final String TAG = "UnZipUtil";
/**
* 解压
*
* @param zipFile
* 源文件
* @param filePath
* 解压文件路径
* @param handler进度回调
* @param isDeleteZip是否删除源文件
* @param password解压密码
* @param isEncryption文件是否加密
* @throws ZipException
*/
private static void unZip(final File zipFile, String filePath,
final Handler handler, final boolean isDeleteZip, String password,
boolean isEncryption) throws ZipException {
if (isEncryption) {
final File decodeFile = new File(zipFile.getParentFile(), "test");
try {
// 解密
decodeFile(zipFile, decodeFile, true);
} catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG, "开始解压");
ZipFile zFile = new ZipFile(decodeFile);
zFile.setFileNameCharset("GBK");
if (!zFile.isValidZipFile()) {
throw new ZipException("exception!");
}
File destDir = new File(filePath); // 解压目录文件
if (destDir.isDirectory() && !destDir.exists()) {
destDir.mkdir();
}
if (zFile.isEncrypted()) {
zFile.setPassword(password); // 设置解压密码
}
final ProgressMonitor progressMonitor = zFile.getProgressMonitor();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Bundle bundle = null;
Message msg = null;
try {
int precentDone = 0;
if (handler == null) {
return;
}
handler.sendEmptyMessage(CompressStatus.START);
while (true) {
// 每隔50ms,发送一个解压进度出去
Thread.sleep(50);
precentDone = progressMonitor.getPercentDone();
System.out.println(precentDone);
bundle = new Bundle();
bundle.putInt(CompressStatus.PERCENT, precentDone);
msg = new Message();
msg.what = CompressStatus.HANDLING;
msg.setData(bundle);
handler.sendMessage(msg); // 通过 Handler将进度扔出去
if (precentDone >= 100) {
break;
}
}
handler.sendEmptyMessage(CompressStatus.COMPLETED);
} catch (InterruptedException e) {
bundle = new Bundle();
bundle.putString(CompressStatus.ERROR_COM,
e.getMessage());
msg = new Message();
msg.what = CompressStatus.ERROR;
msg.setData(bundle);
handler.sendMessage(msg);
e.printStackTrace();
} finally {
if (isDeleteZip) {
decodeFile.delete();// 将原压缩文件删除
}
}
}
});
thread.start();
zFile.setRunInThread(true); // true 在子线程中进行解压 , false主线程中解压
zFile.extractAll(filePath); // 将压缩文件解压到filePath中...
} else {
Log.d(TAG, "开始解压");
ZipFile zFile = new ZipFile(zipFile);
zFile.setFileNameCharset("GBK");
if (!zFile.isValidZipFile()) {
throw new ZipException("exception!");
}
File destDir = new File(filePath); // 解压目录文件
if (destDir.isDirectory() && !destDir.exists()) {
destDir.mkdir();
}
if (zFile.isEncrypted()) {
zFile.setPassword(password); // 设置解压密码
}
final ProgressMonitor progressMonitor = zFile.getProgressMonitor();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Bundle bundle = null;
Message msg = null;
try {
int precentDone = 0;
if (handler == null) {
return;
}
handler.sendEmptyMessage(CompressStatus.START);
while (true) {
// 每隔50ms,发送一个解压进度出去
Thread.sleep(50);
precentDone = progressMonitor.getPercentDone();
System.out.println(precentDone);
bundle = new Bundle();
bundle.putInt(CompressStatus.PERCENT, precentDone);
msg = new Message();
msg.what = CompressStatus.HANDLING;
msg.setData(bundle);
handler.sendMessage(msg); // 通过 Handler将进度扔出去
if (precentDone >= 100) {
break;
}
}
handler.sendEmptyMessage(CompressStatus.COMPLETED);
} catch (InterruptedException e) {
bundle = new Bundle();
bundle.putString(CompressStatus.ERROR_COM,
e.getMessage());
msg = new Message();
msg.what = CompressStatus.ERROR;
msg.setData(bundle);
handler.sendMessage(msg);
e.printStackTrace();
} finally {
if (isDeleteZip) {
zipFile.delete();// 将原压缩文件删除
}
}
}
});
thread.start();
zFile.setRunInThread(true); // true 在子线程中进行解压 , false主线程中解压
zFile.extractAll(filePath); // 将压缩文件解压到filePath中...
}
}
/**
* 无密码解压
*
* @param zipFile
* 源文件
* @param filePath
* 解压文件路径
* @param handler进度回调
* @param isDeleteZip是否删除源文件
* @param isEncryption文件是否加密
* @throws ZipException
*/
public void unZip(final File zipFile, String filePath,
final Handler handler, final boolean isDeleteZip,
boolean isEncryption) throws ZipException {
unZip(zipFile, filePath, handler, isDeleteZip, "", isEncryption);
}
/**
* 解压 无密码、删除源解压文件
*
* @param context
* @param zipFile源文件
* @param filePath 解压文件路径
* @param handler 进度回调
* @param isEncryption文件是否加密
* @throws ZipException
*/
public static void unZip(final File zipFile, String filePath,
final Handler handler, boolean isEncryption) throws ZipException {
unZip(zipFile, filePath, handler, true, "", isEncryption);
}
/**
* 封装不同的解压状态
*
**/
public class CompressStatus {
public final static int START = 10000;
public final static int HANDLING = 10001;
public final static int COMPLETED = 10002;
public final static int ERROR = 10003;
public final static String PERCENT = "PERCENT";
public final static String ERROR_COM = "ERROR";
}
/**
* 解密文件
*
* @param sourceFile
* 加密文件
* @param decodeFile
* 解密文件
* @param b
* 是否删除加密文件
*/
public static void decodeFile(File sourceFile, File decodeFile, boolean b) {
byte[] bs = new byte[1024];
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream(sourceFile));
out = new BufferedOutputStream(new FileOutputStream(decodeFile,
false));
while ((in.read(bs)) != -1) {
for (int i = 0; i < bs.length; i++) {
out.write(bs[i] - 1);
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
out.flush();
in.close();
out.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
if (b) {
sourceFile.delete();
}
}
}
/**
*
* 十六进制转换字符串
*/
public static String hexStr2Str(String hexStr) {
String str = "0123456789ABCDEF";
char[] hexs = hexStr.toCharArray();
byte[] bytes = new byte[hexStr.length() / 2];
int n;
for (int i = 0; i < bytes.length; i++) {
n = str.indexOf(hexs[2 * i]) * 16;
n += str.indexOf(hexs[2 * i + 1]);
bytes[i] = (byte) (n & 0xff);
}
return new String(bytes);
}
/**
* 16进制加密串
*/
private final static String zipCharString = "377ABCAF271C00038D9BD50F000000000000000000000000000000000000";
}