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