how to extract zip file content into sd card?
try {
ZipResourceFile expansionFile = APKExpansionSupport
.getAPKExpansionZipFile(this, 4, 0);
ZipEntryRO[] zip = expansionFile.getAllEntries();
Log.e("", "zip[0].isUncompressed() : " + zip[0].isUncompressed());
Log.e("",
"mFile.getAbsolutePath() : "
+ zip[0].mFile.getAbsolutePath());
Log.e("", "mFileName : " + zip[0].mFileName);
Log.e("", "mZipFileName : " + zip[0].mZipFileName);
Log.e("", "mCompressedLength : " + zip[0].mCompressedLength);
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "");
ZipHelper.unzip(zip[0].mZipFileName, file);
if (file.exists()) {
Log.e("", "unzipped : " + file.getAbsolutePath());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
this.mCancelValidation = true;
super.onDestroy();
}
and use java helper class.
public class ZipHelper {
static boolean zipError = false;
public static boolean isZipError() {
return zipError;
}
public static void setZipError(boolean zipError) {
ZipHelper.zipError = zipError;
}
public static void unzip(String archive, File outputDir) {
try {
Log.d("control", "ZipHelper.unzip() - File: " + archive);
ZipFile zipfile = new ZipFile(archive);
for (Enumeration<? extends ZipEntry> e = zipfile.entries(); e
.hasMoreElements();) {
ZipEntry entry = (ZipEntry) e.nextElement();
unzipEntry(zipfile, entry, outputDir);
}
} catch (Exception e) {
Log.d("control", "ZipHelper.unzip() - Error extracting file "
+ archive + ": " + e);
setZipError(true);
}
}
private static void unzipEntry(ZipFile zipfile, ZipEntry entry,
File outputDir) throws IOException {
if (entry.isDirectory()) {
createDirectory(new File(outputDir, entry.getName()));
return;
}
File outputFile = new File(outputDir, entry.getName());
if (!outputFile.getParentFile().exists()) {
createDirectory(outputFile.getParentFile());
}
Log.d("control", "ZipHelper.unzipEntry() - Extracting: " + entry);
BufferedInputStream inputStream = new BufferedInputStream(
zipfile.getInputStream(entry));
BufferedOutputStream outputStream = new BufferedOutputStream(
new FileOutputStream(outputFile));
try {
IOUtils.copy(inputStream, outputStream);
} catch (Exception e) {
Log.d("control", "ZipHelper.unzipEntry() - Error: " + e);
setZipError(true);
} finally {
outputStream.close();
inputStream.close();
}
}
private static void createDirectory(File dir) {
Log.d("control",
"ZipHelper.createDir() - Creating directory: " + dir.getName());
if (!dir.exists()) {
if (!dir.mkdirs())
throw new RuntimeException("Can't create directory " + dir);
} else
Log.d("control",
"ZipHelper.createDir() - Exists directory: "
+ dir.getName());
}
}
How do you unzip a file with Storage Volume (/StorageAccessFramework)?
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!
try {
InputStream is = getContentResolver().openInputStream(myZip.getUri());
BufferedInputStream bis = new BufferedInputStream(is);
ZipInputStream zis = new ZipInputStream(bis);
ZipEntry zipEntry;
while ((zipEntry = zis.getNextEntry()) != null) {
String fileName = null;
try {
fileName = zipEntry.getName();
fileName = fileName.replace("\\",File.separator).replace("/",File.separator);
int p=fileName.lastIndexOf(File.separator);
DocumentFile destFolder = myDestFolder; //DocumentFile of the destination folder
String destName = fileName;
if (p>=0) {
String[] split = fileName.split(File.separator);
//If the .zip file contains multiple folder levels, this is where you
//have to check and then create them, e.g. for 3 levels:
if(split.length==1) {
destFolder = myFolder;
destName = filename;
} else if(split.length==2) {
if(mySubFolder==null) {
mySubFolder = myFolder.createDirectory(split[0]);
}
destFolder = mySubFolder;
destName = split[1];
} else if(split.length==3) {
if(mySubFolder==null) {
mySubFolder = myFolder.createDirectory(split[0]);
}
if(mySubSubFolder==null) {
mySubSubFolder = mySubFolder.createDirectory(split[1]);
}
destFolder = mySubSubFolder;
destName = split[2];
}
}
DocumentFile df = null;
//Now you have to tell it what file extensions ("MIME" type) you want to use, e.g.:
if(destName.endsWith(".txt")) {
df = destFolder.createFile("text/plain",destName.substring(0,destName.length()-4));
} else if(destName.endsWith(".jpg")) {
df = destFolder.createFile("image/jpeg",destName.substring(0,destName.length()-4));
}
OutputStream out = getContentResolver().openOutputStream(df.getUri());
BufferedOutputStream bos = new BufferedOutputStream(out);
long zipfilesize = zipEntry.getSize();
byte[] buffer = new byte[10000];
int len = 0;
int totlen = 0;
while (((len = zis.read(buffer, 0, 10000)) > 0) && (totlen < zipfilesize)) {
bos.write(buffer, 0, len);
totlen += len;
}
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
return;
}
}
is.close();
bis.close();
zis.close();
} catch (IOException e2) {
e2.printStackTrace();
}
Edit: Important: java.util.zip
doesn't set the size
or compressedSize
(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, replace
while (((len = zis.read(buffer, 0, 10000)) > 0) && (totlen < zipfilesize)) {
with
while (((len = zis.read(buffer, 0, 10000)) > 0)) {
It's possible to do this because:
the call to ZipInputStream.getNextEntry() positions the InputStream at the start of the entry and therefore supplying the ZipInputStream is the equivalent of supplying a ZipEntry's InputStream.
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.
Related Topics
Editing Functionality of Host Card Emulation in Android
Where/How to Getintent().Getextras() in an Android Fragment
Error: File Path Too Long on Windows, Keep Below 240 Characters
Android: How to Get a File's Creation Date
Why Use Armeabi-V7A Code Over Armeabi Code
What Is a Full Android Database Helper Class for an Existing SQLite Database
How to Use Front and Back Camera at Same Time in Android
Android How to Runonuithread in Other Class
Kotlin Error:Could Not Find Org.Jetbrains.Kotlin:Kotlin-Stdlib-Jre7:1.0.7
How Does Native Android Code Written for Arm Run on X86
How to Launch Front Camera with Intent
Mediaplayer.Setdatasource Causes Ioexception for Valid File
Get Nfc Tag with Ndef Android Application Record (Aar)
How to Use the Android Volley API
Android Fragments: When to Use Hide/Show or Add/Remove/Replace