I'm using this code (Android 7.0/Nougat) to unpack a zip file in external storage (including multiple folder levels inside):
try {
ZipFile zip = new ZipFile(zippath);
Enumeration enu = zip.entries();
while(enu.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enu.nextElement();
BufferedInputStream bis = null;
String fileName = null;
try {
fileName = zipEntry.getName();
fileName = fileName.replace("\\",File.separator).replace("/",File.separator);
int p = fileName.lastIndexOf(File.separator);
if(p>=0) {
File fd=new File(folderpath+File.separator+fileName.substring(0,p));
fd.mkdirs();
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(folderpath+File.separator+fileName));
bis = new BufferedInputStream(zip.getInputStream(zipEntry));
byte[] buffer = new byte[10000];
int len = 0;
while ((len = bis.read(buffer, 0, 10000)) > 0) {
bos.write(buffer, 0, len);
}
bis.close();
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
return;
}
}
} catch (IOException e2) {
e2.printStackTrace();
}
To get write access to the SD card I'm using createAccessIntent
(Storage Volume) which uses DocumentFile
s instead of the normal File
.
I already did this to get a ZipInputStream
:
InputStream inputStream = this.getContentResolver().openInputStream(myDocumentFileZip.getUri());
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
ZipInputStream zipInputStream = new ZipInputStream(bufferedInputStream);
ZipEntry zipEntry;
...and I'm guessing that you continue like this:
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
But what do you do from there - how to you copy the files onto the SD card and still keep the folder structure like in the code above but using what Storage Volume (or Storage Access Framework) provides?
Unzip with Storage Volume:
Careful: This way it creates copies if you unzip the same .zip file multiple times, while my original code in the first post (which you can't use for an SD card) doesn't but instead overwrites automatically!
Edit: Important:
java.util.zip
doesn't set thesize
orcompressedSize
(will return "-1"), that's why this code will only create files with a size of 0B with zip files that were created by the library - zip files that were created by hand (e.g. with WinRar) work fine. To fix it, replacewith
It's possible to do this because:
Source: https://stackoverflow.com/a/3233600/2016165
The disadvantages with this (in comparison to my non-StorageVolume version) are that you a) can't get the total amount of files in the zip and b) also can't get the (total) size of the files, which means that you can't set the progress bar in an "Unzipping..." dialog unless you iterate through all the zip entries first to count them.