package org.openintents.filemanager.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.openintents.filemanager.R; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; public class ExtractManager { /** * TAG for log messages. */ static final String TAG = "ExtractManager"; private static final int BUFFER_SIZE = 1024; private Context context; private ProgressDialog progressDialog; private OnExtractFinishedListener onExtractFinishedListener = null; public ExtractManager(Context context) { this.context = context; } public void extract(File f, String destinationPath) { new ExtractTask().execute(f, destinationPath); } private class ExtractTask extends AsyncTask<Object, Void, Integer> { private static final int SUCCESS = 0; private static final int ERROR = 1; /** * count of extracted files to update the progress bar */ private int isExtracted = 0; /** * Recursively extract file or directory */ public boolean extract(File archive, String destinationPath) { ZipFile zipfile = null; try { zipfile = new ZipFile(archive); int fileCount = zipfile.size(); for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); unzipEntry(zipfile, entry, destinationPath); isExtracted++; progressDialog.setProgress((isExtracted * 100)/ fileCount); } return true; } catch (Exception e) { Log.e(TAG, "Error while extracting file " + archive, e); return false; } finally { if (zipfile != null) { try { zipfile.close(); } catch (IOException e) { // ignore } } } } private void createDir(File dir) { if (dir.exists()) { return; } Log.i(TAG, "Creating dir " + dir.getName()); if (!dir.mkdirs()) { throw new RuntimeException("Can not create dir " + dir); } } private void unzipEntry(ZipFile zipfile, ZipEntry entry, String outputDir) throws IOException { if (entry.isDirectory()) { createDir(new File(outputDir, entry.getName())); return; } File outputFile = new File(outputDir, entry.getName()); if (!outputFile.getParentFile().exists()) { createDir(outputFile.getParentFile()); } Log.i(TAG, "Extracting: " + entry); BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry)); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); try { int len; byte[] buf = new byte[BUFFER_SIZE]; while ((len = inputStream.read(buf)) > 0) { outputStream.write(buf, 0, len); } } finally { outputStream.close(); inputStream.close(); } } @Override protected void onPreExecute() { progressDialog = new ProgressDialog(context); progressDialog.setCancelable(false); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage(context.getResources().getString(R.string.extracting)); progressDialog.show(); progressDialog.setProgress(0); isExtracted = 0; } @Override protected Integer doInBackground(Object... params) { File f= (File) params[0]; String destination = (String) params[1]; boolean result = extract(f, destination); return result ? SUCCESS : ERROR; } @Override protected void onPostExecute(Integer result) { progressDialog.cancel(); if (result == ERROR){ Toast.makeText(context, R.string.extracting_error, Toast.LENGTH_SHORT).show(); } else if (result == SUCCESS){ Toast.makeText(context, R.string.extracting_success, Toast.LENGTH_SHORT).show(); } if(onExtractFinishedListener != null) onExtractFinishedListener.extractFinished(); } } public interface OnExtractFinishedListener{ public abstract void extractFinished(); } public ExtractManager setOnExtractFinishedListener(OnExtractFinishedListener listener) { this.onExtractFinishedListener = listener; return this; } }