Android – ¿Descomprimir una carpeta?

Tengo una carpeta zip en mi tarjeta SD, ¿cómo descomprimo la carpeta (dentro de mi código de aplicación)?

Estoy usando una versión modificada del método de Beginner que extiende AsyncTask y puede actualizar los observadores en el hilo principal. La compresión byte por byte es extremadamente lenta y debe evitarse. En cambio, un enfoque más eficiente es copiar grandes fragmentos de datos a la secuencia de salida.

package com.blarg.webviewscroller; 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.Observable; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.apache.commons.io.IOUtils; import android.os.AsyncTask; import android.util.Log; public class UnZipper extends Observable { private static final String TAG = "UnZip"; private String mFileName, mFilePath, mDestinationPath; public UnZipper (String fileName, String filePath, String destinationPath) { mFileName = fileName; mFilePath = filePath; mDestinationPath = destinationPath; } public String getFileName () { return mFileName; } public String getFilePath() { return mFilePath; } public String getDestinationPath () { return mDestinationPath; } public void unzip () { String fullPath = mFilePath + "/" + mFileName + ".zip"; Log.d(TAG, "unzipping " + mFileName + " to " + mDestinationPath); new UnZipTask().execute(fullPath, mDestinationPath); } private class UnZipTask extends AsyncTask { @SuppressWarnings("rawtypes") @Override protected Boolean doInBackground(String... params) { String filePath = params[0]; String destinationPath = params[1]; File archive = new File(filePath); try { ZipFile zipfile = new ZipFile(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); unzipEntry(zipfile, entry, destinationPath); } } catch (Exception e) { Log.e(TAG, "Error while extracting file " + archive, e); return false; } return true; } @Override protected void onPostExecute(Boolean result) { setChanged(); notifyObservers(); } 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.v(TAG, "Extracting: " + entry); BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry)); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); try { IOUtils.copy(inputStream, outputStream); } finally { outputStream.close(); inputStream.close(); } } private void createDir(File dir) { if (dir.exists()) { return; } Log.v(TAG, "Creating dir " + dir.getName()); if (!dir.mkdirs()) { throw new RuntimeException("Can not create dir " + dir); } } } } 

Es utilizado por una clase que implementa Observer , como por ejemplo:

 private void unzipWebFile(String filename) { String unzipLocation = getExternalFilesDir(null) + "/unzipped"; String filePath = Environment.getExternalStorageDirectory().toString(); UnZipper unzipper = new UnZipper(filename, filePath, unzipLocation); unzipper.addObserver(this); unzipper.unzip(); } 

Su observador recibirá una update(Observable observable, Object data) callback cuando finalice la descompresión.

 static Handler myHandler; ProgressDialog myProgress; public void unzipFile(File zipfile) { myProgress = ProgressDialog.show(getContext(), "Extract Zip", "Extracting Files...", true, false); File zipFile = zipfile; String directory = null; directory = zipFile.getParent(); directory = directory + "/"; myHandler = new Handler() { @Override public void handleMessage(Message msg) { // process incoming messages here switch (msg.what) { case 0: // update progress bar myProgress.setMessage("" + (String) msg.obj); break; case 1: myProgress.cancel(); Toast toast = Toast.makeText(getContext(), "Zip extracted successfully", Toast.LENGTH_SHORT); toast.show(); provider.refresh(); break; case 2: myProgress.cancel(); break; } super.handleMessage(msg); } }; Thread workthread = new Thread(new UnZip(zipFile, directory)); workthread.start(); } public class UnZip implements Runnable { File archive; String outputDir; public UnZip(File ziparchive, String directory) { archive = ziparchive; outputDir = directory; } public void log(String log) { Log.v("unzip", log); } @SuppressWarnings("unchecked") public void run() { Message msg; try { ZipFile zipfile = new ZipFile(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); msg = new Message(); msg.what = 0; msg.obj = "Extracting " + entry.getName(); myHandler.sendMessage(msg); unzipEntry(zipfile, entry, outputDir); } } catch (Exception e) { log("Error while extracting file " + archive); } msg = new Message(); msg.what = 1; myHandler.sendMessage(msg); } @SuppressWarnings("unchecked") public void unzipArchive(File archive, String outputDir) { try { ZipFile zipfile = new ZipFile(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); unzipEntry(zipfile, entry, outputDir); } } catch (Exception e) { log("Error while extracting file " + archive); } } 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("Extracting: " + entry); BufferedInputStream inputStream = new BufferedInputStream(zipfile .getInputStream(entry)); BufferedOutputStream outputStream = new BufferedOutputStream( new FileOutputStream(outputFile)); try { IOUtils.copy(inputStream, outputStream); } finally { outputStream.close(); inputStream.close(); } } private void createDir(File dir) { log("Creating dir " + dir.getName()); if (!dir.mkdirs()) throw new RuntimeException("Can not create dir " + dir); } } 

Esto es lo que funcionó para mí gracias a la gente

solo “complemento” para @ rich.e respuesta:

en doInBackground() después de iterar a través de ZipEtries debe cerrar el archivo, porque a veces desea eliminar el archivo después de descomprimirlo y arroja una excepción si el archivo no se cerró:

 try { ZipFile zipfile = new ZipFile(archive); int entries = zipfile.size(); int total = 0; if(onZipListener != null) onZipListener.onUncompressStart(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); if(onZipListener != null) onZipListener.onUncompressProgress(archive, (int) (total++ * 100 / entries)); unzipEntry(zipfile, entry, path); } zipfile.close(); } catch (Exception e) { e.printStackTrace(); }