Descargar y extraer archivos Zip en Android

Mi aplicación está descargando archivo zip desde el servidor y extraer este archivo zip y guardar los archivos en la tarjeta SD, pero el problema es si estoy descargando archivos zip de 4-5 MB y extraerlo, esto está funcionando bien, pero si estoy descargando 30-35 MB Archivo zip esto me dará error, lo siento por mi mala comunicación en inglés.

El siguiente es mi código para descargar y descomprimir el archivo Zip: –

public class UnzipManager { private static String BASE_FOLDER; public static Context localContext; public static String passurl; public static int count; public static Context context; /* * You can use this flag to check whether Unzippingthread is still running.. */ public static boolean isDownloadInProgress; /* * After unzipping using this flag ,you can check whether any low memory * exceptions Occurred or not..and alert user accordingly.. */ public static boolean isLowOnMemory; public static int i = 0; public static ZipEntry zipEntry; public static void startUnzipping(Context ctx, int c, String url) { context = ctx; count = c; /* * MAKE SURE THAT localContext VARIABLE HAS BEEN INITIALIZED BEFORE * INVOKING THIS METHOD. * * ALSO MAKE SURE YOU HAVE SET "INTERNET" AND "NETWORK ACCESS STATE" * PERMISSIONS IN APPLICATION'S MANIFEST FILE. */ Log.d("DEBUG", "In startUnzipping()"); UnzipManager.BASE_FOLDER = Environment.getExternalStorageDirectory() + File.separator + "samples"; /* * */ Log.d("DEBUG", "BASE_FOLDER:" + UnzipManager.BASE_FOLDER); UnzipManager.isLowOnMemory = false; // Start unzipping in a thread..which is safer // way to do high cost processes.. passurl = url; new UnzipThread().start(); } private static class UnzipThread extends Thread { @Override public void run() { UnzipManager.isDownloadInProgress = true; Log.d("DEBUG", "Unzipping----------------------------"); URLConnection urlConnection; try { /************************************************ * * IF you are unzipping a zipped file save under some URL in * remote server * **********************************************/ URL finalUrl = new URL(passurl /* Url string where the zipped file is stored... */); urlConnection = finalUrl.openConnection(); // Get the size of the ( zipped file's) inputstream from // server.. int contentLength = urlConnection.getContentLength(); Log.d("DEBUG", "urlConnection.getContentLength():" + contentLength); /***************************************************** * * YOU CAN GET INPUT STREAM OF A ZIPPED FILE FROM ASSETS FOLDER * AS WELL..,IN THAT CASE JUST PASS THAT INPUTSTEAM OVER * HERE...MAKE SURE YOU HAVE SET STREAM CONTENT LENGTH OF THE * SAME.. * ******************************************************/ ZipInputStream zipInputStream = new ZipInputStream( urlConnection.getInputStream()); /* * Iterate over all the files and folders */ for (zipEntry = zipInputStream.getNextEntry(); zipEntry != null; zipEntry = zipInputStream .getNextEntry()) { Log.d("DEBUG", "Extracting: " + zipEntry.getName() + "..."); /* * Extracted file will be saved with same file name that in * zipped folder. */ String innerFileName = BASE_FOLDER + File.separator + zipEntry.getName(); File innerFile = new File(innerFileName); /* * Checking for pre-existence of the file and taking * necessary actions */ if (innerFile.exists()) { Log.d("DEBUG", "The Entry already exits!, so deleting.."); innerFile.delete(); } /* * Checking for extracted entry for folder type..and taking * necessary actions */ if (zipEntry.isDirectory()) { Log.d("DEBUG", "The Entry is a directory.."); innerFile.mkdirs(); } else { Log.d("DEBUG", "The Entry is a file.."); FileOutputStream outputStream = new FileOutputStream( innerFileName); final int BUFFER_SIZE = 2048; /* * Get the buffered output stream.. */ BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( outputStream, BUFFER_SIZE); /* * Write into the file's buffered output stream ,.. */ int count = 0; byte[] buffer = new byte[BUFFER_SIZE]; while ((count = zipInputStream.read(buffer, 0, BUFFER_SIZE)) != -1) { bufferedOutputStream.write(buffer, 0, count); } /*********************************************** * IF YOU WANT TO TRACK NO OF FILES DOWNLOADED, HAVE A * STATIC COUNTER VARIABLE, INITIALIZE IT IN * startUnzipping() before calling startUnZipping(), AND * INCREMENT THE COUNTER VARIABLE OVER HERE..LATER YOU * CAN USE VALUE OF COUNTER VARIABLE TO CROSS VERIFY * WHETHER ALL ZIPPED FILES PROPERLY UNZIPPED AND SAVED * OR NOT. * * ************************************************ */ /* * Handle closing of output streams.. */ bufferedOutputStream.flush(); bufferedOutputStream.close(); } /* * Finish the current zipEntry */ zipInputStream.closeEntry(); } /* * Handle closing of input stream... */ zipInputStream.close(); Log.d("DEBUG", "--------------------------------"); Log.d("DEBUG", "Unzipping completed.."); i = 1; } catch (IOException e) { Log.d("DEBUG", "Exception occured: " + e.getMessage()); if (e.getMessage().equalsIgnoreCase("No space left on device")) { UnzipManager.isLowOnMemory = true; } e.printStackTrace(); } MainActivity.pd.dismiss(); ((MainActivity)context).finish(); UnzipManager.isDownloadInProgress = false; } }; } 

Logcat Error es: –

 02-17 12:21:16.835: D/DEBUG(20562): Exception occured: /mnt/sdcard/samples/iPhone_zendura_Q4a/0.png (No such file or directory) 02-17 12:21:16.835: W/System.err(20562): java.io.FileNotFoundException: /mnt/sdcard/samples/iPhone_zendura_Q4a/0.png (No such file or directory) 02-17 12:21:16.906: W/System.err(20562): at org.apache.harmony.luni.platform.OSFileSystem.open(Native Method) 02-17 12:21:16.906: W/System.err(20562): at dalvik.system.BlockGuard$WrappedFileSystem.open(BlockGuard.java:232) 02-17 12:21:16.906: W/System.err(20562): at java.io.FileOutputStream.<init>(FileOutputStream.java:94) 02-17 12:21:16.906: W/System.err(20562): at java.io.FileOutputStream.<init>(FileOutputStream.java:165) 02-17 12:21:16.906: W/System.err(20562): at java.io.FileOutputStream.<init>(FileOutputStream.java:144) 02-17 12:21:16.906: W/System.err(20562): at com.android.screens.UnzipManager$UnzipThread.run(UnzipManager.java:129) 

Descomprimir archivo

Descargar archivo zip

Escribí un IntentService que IntentService las cosas junto con el progreso:

Agregue la siguiente clase de servicio a su aplicación (también declare en el archivo Manifest de su aplicación):

 import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.os.Handler; import android.os.Parcel; import android.os.Parcelable; import android.os.ResultReceiver; import android.util.Log; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * Created by Vaibhav.Jani on 6/4/15. */ public class FileDownloadService extends IntentService { private static int STATUS_OK = 100; private static int STATUS_FAILED = 200; private static final String DOWNLOADER_RECEIVER = "downloader_receiver"; private static final String DOWNLOAD_DETAILS = "download_details"; private static final String DOWNLOAD_STARTED = "download_started"; private static final String DOWNLOAD_FAILED = "download_failed"; private static final String DOWNLOAD_COMPLETED = "download_completed"; private static final String DOWNLOAD_PROGRESS = "download_progress"; public FileDownloadService() { super(""); } @Override protected void onHandleIntent(Intent intent) { Bundle bundle = intent.getExtras(); if (bundle == null || !bundle.containsKey(DOWNLOADER_RECEIVER) || !bundle.containsKey(DOWNLOAD_DETAILS)) { return; } ResultReceiver resultReceiver = bundle.getParcelable(DOWNLOADER_RECEIVER); DownloadRequest downloadDetails = bundle.getParcelable(DOWNLOAD_DETAILS); try { assert downloadDetails != null; URL url = new URL(downloadDetails.getServerFilePath()); URLConnection urlConnection = url.openConnection(); urlConnection.connect(); int lengthOfFile = urlConnection.getContentLength(); Log.d("FileDownloaderService", "Length of file: " + lengthOfFile); downloadStarted(resultReceiver); InputStream input = new BufferedInputStream(url.openStream()); String localPath = downloadDetails.getLocalFilePath(); OutputStream output = new FileOutputStream(localPath); byte data[] = new byte[1024]; long total = 0; int count; while ((count = input.read(data)) != -1) { total += count; int progress = (int) ((total * 100) / lengthOfFile); sendProgress(progress, resultReceiver); output.write(data, 0, count); } output.flush(); output.close(); input.close(); if (downloadDetails.isRequiresUnzip()) { String unzipDestination = downloadDetails.getUnzipAtFilePath(); if(unzipDestination == null){ File file = new File(localPath); unzipDestination = file.getParentFile().getAbsolutePath(); } unzip(localPath, unzipDestination); } downloadCompleted(resultReceiver); if (downloadDetails.isDeleteZipAfterExtract()) { File file = new File(localPath); file.delete(); } } catch (Exception e) { e.printStackTrace(); downloadFailed(resultReceiver); } } public void sendProgress(int progress, ResultReceiver receiver) { Bundle progressBundle = new Bundle(); progressBundle.putInt(FileDownloadService.DOWNLOAD_PROGRESS, progress); receiver.send(STATUS_OK, progressBundle); } public void downloadStarted(ResultReceiver resultReceiver) { Bundle progressBundle = new Bundle(); progressBundle.putBoolean(FileDownloadService.DOWNLOAD_STARTED, true); resultReceiver.send(STATUS_OK, progressBundle); } public void downloadCompleted(ResultReceiver resultReceiver) { Bundle progressBundle = new Bundle(); progressBundle.putBoolean(FileDownloadService.DOWNLOAD_COMPLETED, true); resultReceiver.send(STATUS_OK, progressBundle); } public void downloadFailed(ResultReceiver resultReceiver) { Bundle progressBundle = new Bundle(); progressBundle.putBoolean(FileDownloadService.DOWNLOAD_FAILED, true); resultReceiver.send(STATUS_FAILED, progressBundle); } private void unzip(String zipFilePath, String unzipAtLocation) throws Exception { File archive = new File(zipFilePath); try { ZipFile zipfile = new ZipFile(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements(); ) { ZipEntry entry = (ZipEntry) e.nextElement(); unzipEntry(zipfile, entry, unzipAtLocation); } } catch (Exception e) { Log.e("Unzip zip", "Unzip exception", e); } } 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("ZIP E", "Extracting: " + entry); InputStream zin = zipfile.getInputStream(entry); BufferedInputStream inputStream = new BufferedInputStream(zin); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); try { //IOUtils.copy(inputStream, outputStream); try { for (int c = inputStream.read(); c != -1; c = inputStream.read()) { outputStream.write(c); } } finally { outputStream.close(); } } finally { outputStream.close(); inputStream.close(); } } private void createDir(File dir) { if (dir.exists()) { return; } Log.v("ZIP E", "Creating dir " + dir.getName()); if (!dir.mkdirs()) { throw new RuntimeException("Can not create dir " + dir); } } public static class FileDownloader extends ResultReceiver { private DownloadRequest downloadDetails; private OnDownloadStatusListener onDownloadStatusListener; public static FileDownloader getInstance(DownloadRequest downloadDetails, OnDownloadStatusListener downloadStatusListener) { Handler handler = new Handler(); FileDownloader fileDownloader = new FileDownloader(handler); fileDownloader.downloadDetails = downloadDetails; fileDownloader.onDownloadStatusListener = downloadStatusListener; return fileDownloader; } public void download(Context context) { if (isOnline(context)) { Intent intent = new Intent(context, FileDownloadService.class); intent.putExtra(FileDownloadService.DOWNLOADER_RECEIVER, this); intent.putExtra(FileDownloadService.DOWNLOAD_DETAILS, downloadDetails); context.startService(intent); } } private FileDownloader(Handler handler) { super(handler); } @Override protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); if (onDownloadStatusListener == null) { return; } if (resultCode == FileDownloadService.STATUS_OK) { if (resultData.containsKey(FileDownloadService.DOWNLOAD_STARTED) && resultData.getBoolean(FileDownloadService.DOWNLOAD_STARTED)) { onDownloadStatusListener.onDownloadStarted(); } else if (resultData.containsKey(FileDownloadService.DOWNLOAD_COMPLETED) && resultData.getBoolean(FileDownloadService.DOWNLOAD_COMPLETED)) { onDownloadStatusListener.onDownloadCompleted(); } else if (resultData.containsKey(FileDownloadService.DOWNLOAD_PROGRESS)) { int progress = resultData.getInt(FileDownloadService.DOWNLOAD_PROGRESS); onDownloadStatusListener.onDownloadProgress(progress); } } else if (resultCode == FileDownloadService.STATUS_FAILED) { onDownloadStatusListener.onDownloadFailed(); } } public DownloadRequest getDownloadDetails() { return downloadDetails; } public void setDownloadDetails(DownloadRequest downloadDetails) { this.downloadDetails = downloadDetails; } public OnDownloadStatusListener getOnDownloadStatusListener() { return onDownloadStatusListener; } public void setOnDownloadStatusListener(OnDownloadStatusListener onDownloadStatusListener) { this.onDownloadStatusListener = onDownloadStatusListener; } } public static interface OnDownloadStatusListener { void onDownloadStarted(); void onDownloadCompleted(); void onDownloadFailed(); void onDownloadProgress(int progress); } public static class DownloadRequest implements Parcelable { private String tag; private boolean requiresUnzip; private String serverFilePath; private String localFilePath; private String unzipAtFilePath; private boolean deleteZipAfterExtract = true; public DownloadRequest(String serverFilePath, String localPath) { this.serverFilePath = serverFilePath; this.localFilePath = localPath; this.requiresUnzip = requiresUnzip; } protected DownloadRequest(Parcel in) { requiresUnzip = in.readByte() != 0x00; serverFilePath = in.readString(); localFilePath = in.readString(); unzipAtFilePath = in.readString(); deleteZipAfterExtract = in.readByte() != 0x00; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeByte((byte) (requiresUnzip ? 0x01 : 0x00)); dest.writeString(serverFilePath); dest.writeString(localFilePath); dest.writeString(unzipAtFilePath); dest.writeByte((byte) (deleteZipAfterExtract ? 0x01 : 0x00)); } @SuppressWarnings("unused") public static final Parcelable.Creator<DownloadRequest> CREATOR = new Parcelable.Creator<DownloadRequest>() { @Override public DownloadRequest createFromParcel(Parcel in) { return new DownloadRequest(in); } @Override public DownloadRequest[] newArray(int size) { return new DownloadRequest[size]; } }; public boolean isRequiresUnzip() { return requiresUnzip; } public void setRequiresUnzip(boolean requiresUnzip) { this.requiresUnzip = requiresUnzip; } public String getServerFilePath() { return serverFilePath; } public void setServerFilePath(String serverFilePath) { this.serverFilePath = serverFilePath; } public String getLocalFilePath() { return localFilePath; } public void setLocalFilePath(String localFilePath) { this.localFilePath = localFilePath; } public static Creator<DownloadRequest> getCreator() { return CREATOR; } public String getUnzipAtFilePath() { return unzipAtFilePath; } public void setUnzipAtFilePath(String unzipAtFilePath) { this.unzipAtFilePath = unzipAtFilePath; } public String getTag() { return tag; } public void setTag(String tag) { this.tag = tag; } public boolean isDeleteZipAfterExtract() { return deleteZipAfterExtract; } public void setDeleteZipAfterExtract(boolean deleteZipAfterExtract) { this.deleteZipAfterExtract = deleteZipAfterExtract; } } private static boolean isOnline(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnectedOrConnecting() && cm.getActiveNetworkInfo().isAvailable() && cm.getActiveNetworkInfo().isConnected()) { return true; } return false; } } 

Ejemplo de caso de uso:

 String serverFilePath = "http://www.colorado.edu/conflict/peace/download/peace_problem.ZIP"; String path = FileUtils.getDataDir(context).getAbsolutePath(); String fileName = "sample_download"; File file = new File(path, fileName); String localPath = file.getAbsolutePath(); String unzipPath = FileUtils.getDataDir(context, "ExtractLoc").getAbsolutePath(); FileDownloadService.DownloadRequest downloadRequest = new FileDownloadService.DownloadRequest(serverFilePath, localPath); downloadRequest.setRequiresUnzip(true); downloadRequest.setDeleteZipAfterExtract(false); downloadRequest.setUnzipAtFilePath(unzipPath); FileDownloadService.OnDownloadStatusListener listener = new FileDownloadService.OnDownloadStatusListener() { @Override public void onDownloadStarted() { subscriber.onNext(String.valueOf(0)); } @Override public void onDownloadCompleted() { subscriber.onNext(String.valueOf(100)); } @Override public void onDownloadFailed() { } @Override public void onDownloadProgress(int progress) { } }; FileDownloadService.FileDownloader downloader = FileDownloadService.FileDownloader.getInstance(downloadRequest, listener); downloader.download(context); 

También puede utilizar (si es necesario) FileUtils.java

 import android.content.Context; import java.io.File; public class FileUtils { public static File getDataDir(Context context) { String path = context.getFilesDir().getAbsolutePath() + "/SampleZip"; File file = new File(path); if(!file.exists()) { file.mkdirs(); } return file; } public static File getDataDir(Context context, String folder) { String path = context.getFilesDir().getAbsolutePath() + "/" + folder; File file = new File(path); if(!file.exists()) { file.mkdirs(); } return file; } } 

Como JoxTraex dijo: el error es realmente obvio.

En UnzipManager línea 129 intenta abrir un archivo que no está allí. Ése es porqué usted consigue una FileNotFoundException . Debe comprobar su archivo zip si es correcto y puede extraerse correctamente en su PC.

Intente depurar, también. Agregue un punto de interrupción en esa línea y deje que la aplicación se depure y observe lo que ocurre allí cuando aparezca la ubicación de archivo específica.

No elimine el archivo si existe (ya que los archivos se sobrescribirán) o instanciar innerFile de nuevo.

 if (innerFile.exists()) { Log.d("DEBUG", "The Entry already exits!, so deleting.."); innerFile.delete(); } //Instantiate Again innerFile = new File(innerFileName); 

Borrando innerFile usted pierde el archivo y al intentar crear directorio usando innerFile hace que el FileNotFoundException.

Este es el código final que utiliza la respuesta de mejora de rendimiento , que descomprimió un archivo de 23 MB en una carpeta de 130 MB en exactamente 1 minuto:

 public class Decompress { private String _zipFile; private String _location; public Decompress(String zipFile, String location) { _zipFile = zipFile; _location = location; _dirChecker(""); } public void unzip() { try { FileInputStream fin = new FileInputStream(_zipFile); ZipInputStream zin = new ZipInputStream(fin); byte b[] = new byte[1024]; ZipEntry ze = null; while ((ze = zin.getNextEntry()) != null) { Log.v("Decompress", "Unzipping " + ze.getName()); if(ze.isDirectory()) { _dirChecker(ze.getName()); } else { FileOutputStream fout = new FileOutputStream(_location + ze.getName()); BufferedInputStream in = new BufferedInputStream(zin); BufferedOutputStream out = new BufferedOutputStream(fout); int n; while ((n = in.read(b,0,1024)) >= 0) { out.write(b,0,n); } zin.closeEntry(); out.close(); } } zin.close(); } catch(Exception e) { Log.e("Decompress", "unzip", e); } } private void _dirChecker(String dir) { File f = new File(_location + dir); if(!f.isDirectory()) { f.mkdirs(); } }} 
  • MediaPlayer java.io.IOException: Prepare failed .: status = 0x1 con Huawei ALE-L21
  • Creación de una instancia sencilla de ExoPlayer
  • Android: descargar archivo grande
  • Descargar imagen para imageview en Android
  • cómo: descargar y abrir un archivo pdf mediante programación a través de conexión http
  • Obtener la URL de descarga para el vídeo de YouTube (Android / Java)
  • Cómo establecer el tiempo de espera a cero en la acción HTTP Obtener de Tasker?
  • ¿Cómo puedo descargar el archivo mediante webview? (Este caso es raro)
  • Trigger android gestor de descargas Cordova
  • Android instala un apk de la URL
  • Filtro de intenciones para descargar adjuntos de aplicaciones de gmail en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.