Android開發之Zip下載解壓
阿新 • • 發佈:2019-01-06
本篇部落格為需求而發燒,若有雷同需求code拿走不謝。
需求如下:點選Item,從伺服器下載zip包到本地資料夾並解壓,解壓後的圖片檔案全部查詢出來,用於介面預覽
沒有強制每次都下載zip包保持最新,如果有需要FileDownload有函式支援,亦可以自行新增解壓後自動刪除zip包
流程:
下載zip包
解壓zip包
查詢指定檔案格式的檔案路徑集合(.jpg為例)
檔案下載推薦開源庫FileDownloader
compile 'com.liulishuo.filedownloader:library:1.7.2'
接入專案首先Application初始化
FileDownloader.setup(Context)
需求是單任務下載zip,呼叫示例如下
FileDownloader.getImpl().create(url)
.setPath(path)
.setListener(new FileDownloadListener() {
@Override
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void blockComplete(BaseDownloadTask task) {
}
@Override
protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
}
@Override
protected void completed(BaseDownloadTask task) {
}
@Override
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
}
@Override
protected void warn(BaseDownloadTask task) {
}
}).start();
是否支援強制重新下載zip包
setForceReDownload(false)
檔案下載完成後開始解壓,這裡推薦使用開源庫zt-zip
解壓zip但不需要過濾匹配是否含有指定檔案,所以只需要傳入檔案路徑和解壓目錄
private void unPackage(String zipPath,String outputDir){
ZipUtil.unpack(new File(zipPath), new File(outputDir));
}
解壓後遍解壓目錄下的.jpg檔案
/**
* 查詢解壓目錄下的檔案,並過濾檔案格式返回路徑集合
* @hide
* @param outputDir
* @return
*/
private ArrayList<String> queryUnPackageOutputDir(String outputDir){
ArrayList<String> arrayList = new ArrayList<>();
File file = new File(outputDir);
File[] subFile = file.listFiles();
for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
if (!subFile[iFileLength].isDirectory()) {
String filename = subFile[iFileLength].getAbsolutePath();
if (filename.trim().toLowerCase().endsWith(".jpg")) {
arrayList.add(filename);
}
}
}
return arrayList;
}
下面提供一個Helper類以及程式碼呼叫示例
import android.app.Activity;
import android.os.Environment;
import android.util.Log;
import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloader;
import org.zeroturnaround.zip.ZipUtil;
import java.io.File;
import java.util.ArrayList;
/**
* Created by idea on 2018/3/26.
*/
public class ZipHelper {
public static final String TEST_ZIP_URL = "用於測試的zip下載地址,自行完善";
/***
*
* Unpacking
*
* Check if an entry exists in a ZIP archive
* boolean exists = ZipUtil.containsEntry(new File("/tmp/demo.zip"), "foo.txt");
*
* Extract an entry from a ZIP archive into a byte array
* byte[] bytes = ZipUtil.unpackEntry(new File("/tmp/demo.zip"), "foo.txt");
*
* Extract an entry from a ZIP archive with a specific Charset into a byte array
* byte[] bytes = ZipUtil.unpackEntry(new File("/tmp/demo.zip"), "foo.txt", Charset.forName("IBM437"));
*
* Extract an entry from a ZIP archive into file system
* ZipUtil.unpackEntry(new File("/tmp/demo.zip"), "foo.txt", new File("/tmp/bar.txt"));
*
* Extract a ZIP archive
* ZipUtil.unpack(new File("/tmp/demo.zip"), new File("/tmp/demo"));
*
* Extract a ZIP archive which becomes a directory
* ZipUtil.explode(new File("/tmp/demo.zip"));
*
* Extract a directory from a ZIP archive including the directory name
* ZipUtil.unpack(new File("/tmp/demo.zip"), new File("/tmp/demo"), new NameMapper() {
* public String map(String name) {
* return name.startsWith("doc/") ? name : null;
* }
* });
*
* Extract a directory from a ZIP archive excluding the directory name
* final String prefix = "doc/";
* ZipUtil.unpack(new File("/tmp/demo.zip"), new File("/tmp/demo"), new NameMapper() {
* public String map(String name) {
* return name.startsWith(prefix) ? name.substring(prefix.length()) : name;
* }
* });
*
* Extract files from a ZIP archive that match a name pattern
*
* ZipUtil.unpack(new File("/tmp/demo.zip"), new File("/tmp/demo"), new NameMapper() {
* public String map(String name) {
* if (name.contains("/doc")) {
* return name;
* }else {
* // returning null from the map method will disregard the entry
* return null;
* }
* }
* });
*
* Print .class entry names in a ZIP archive
* ZipUtil.iterate(new File("/tmp/demo.zip"), new ZipInfoCallback() {
* public void process(ZipEntry zipEntry) throws IOException {
* if (zipEntry.getName().endsWith(".class"))
* System.out.println("Found " + zipEntry.getName());
* }
* });
*
* Print .txt entries in a ZIP archive (uses IoUtils from Commons IO)
* ZipUtil.iterate(new File("/tmp/demo.zip"), new ZipEntryCallback() {
* public void process(InputStream in, ZipEntry zipEntry) throws IOException {
* if (zipEntry.getName().endsWith(".txt")) {
* System.out.println("Found " + zipEntry.getName());
* IOUtils.copy(in, System.out);
* }
* }
* });
*
* @hide
* 解壓zip檔案
*
*/
private void unPackage(String zipPath,String outputDir){
ZipUtil.unpack(new File(zipPath), new File(outputDir));
}
/**
* 查詢解壓目錄下的檔案,並過濾檔案格式返回路徑集合
* @hide
* @param outputDir
* @return
*/
private ArrayList<String> queryUnPackageOutputDir(String outputDir){
ArrayList<String> arrayList = new ArrayList<>();
File file = new File(outputDir);
File[] subFile = file.listFiles();
for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
if (!subFile[iFileLength].isDirectory()) {
String filename = subFile[iFileLength].getAbsolutePath();
if (filename.trim().toLowerCase().endsWith(".jpg")) {
arrayList.add(filename);
}
}
}
return arrayList;
}
/**
* 判斷指定目錄是否下載過zip檔案
* @param zipName zip檔名稱
* @param zipCachePath 資料夾
* @hide
* @return
*/
private boolean containsZipFile(String zipCachePath,String zipName){
boolean result = false;
File file = new File(zipCachePath);
if (file.exists()) {
File zipFile = new File(zipCachePath+"/"+zipName);
if(zipFile.exists()){
result = true;
} else{
result = false;
}
} else {
file.mkdir();
}
return result;
}
/**
* 下載zip檔案
* @hide
* @param url
* @param zipPath
*/
private void downloadZipFile(String url, String zipPath,final OnDownloadZipListener onDownloadZipListener){
FileDownloader.getImpl().create(url)
.setPath(zipPath)
.setForceReDownload(false)
.setListener(new FileDownloadListener() {
@Override
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void blockComplete(BaseDownloadTask task) {
}
@Override
protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
}
@Override
protected void completed(BaseDownloadTask task) {
onDownloadZipListener.onComplete();
}
@Override
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
onDownloadZipListener.onError();
}
@Override
protected void warn(BaseDownloadTask task) {
}
}).start();
}
/**
* 每載入完成一張圖片就立即刪除檔案
* @param path
*/
public void deleteFile(String path){
File file = new File(path);
if(file.isFile()&&file.exists()){
file.delete();
}
}
/**
* 刪除解壓檔案
*/
public void clearOutputDir(){
String dir = "/iot.monitoring.zip.output";
File outputDirFile = new File(Environment.getExternalStorageDirectory(), dir);
File[] listFiles = outputDirFile.listFiles();
if (outputDirFile.exists()&&listFiles!=null&&listFiles.length>0) {
for(int i = 0;i<listFiles.length;i++){
listFiles[i].delete();
}
}
}
/**
* 下載zip檔案
* @hide
* @param url 下載路徑
* @param zipCachePath 快取目錄
* @param outputDir 解壓目錄
*/
private void doBackground(final Activity activity, final String url, final String zipCachePath, final String outputDir, final UnPackageImageListener unPackageImageListener){
//阿里雲 zip下路路徑格式如下: http//xxxxxx.xx.xx/xxx/xxx.zip?xxxxxx
int index = url.indexOf("?");
final String [] array = url.substring(0,index).split("/");
downloadZipFile(url, zipCachePath + "/" + array[array.length - 1], new OnDownloadZipListener() {
@Override
public void onError() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
unPackageImageListener.onError();
}
});
}
@Override
public void onComplete() {
unPackage(zipCachePath+"/"+array[array.length-1],outputDir);
final ArrayList<String> collection = queryUnPackageOutputDir(outputDir);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
unPackageImageListener.onSuccess(collection);
}
});
}
});
}
/**
* 下載zip圖片集合並解壓到目錄,獲取查詢結果
* @param activity
* @param url
* @param unPackageImageListener
*/
public void queryImageCollection(final Activity activity, final String url, final UnPackageImageListener unPackageImageListener){
String dir = "/idea.analyzesystem.zip";
File zipCachePathDir = new File(Environment.getExternalStorageDirectory(), dir);
if (!zipCachePathDir.exists()) {
zipCachePathDir.mkdir();
}
dir = "/idea.analyzesystem.zip.output";
File outputDir = new File(Environment.getExternalStorageDirectory(), dir);
if (!outputDir.exists()) {
outputDir.mkdir();
}
clearOutputDir();
String zipCachePath = zipCachePathDir.getAbsolutePath();
String outputDirPath = outputDir.getAbsolutePath();
doBackground(activity,url,zipCachePath,outputDirPath,unPackageImageListener);
}
public interface OnDownloadZipListener{
void onError();
void onComplete();
}
public interface UnPackageImageListener{
void onError();
void onSuccess(ArrayList<String> result);
}
}
new ZipHelper().queryImageCollection(getActivity(),url,new ZipHelper.UnPackageImageListener() {
@Override
public void onError() {
}
@Override
public void onSuccess(ArrayList<String> result) {
}
});