Hello Folks,
Its about after 2 months I thought of writing a post. So here is it. I was thinking to extract a .zip file from PhoneGap on android and I ended up implementing a plugin for it.
Include the below .java file with the same package mentioned.
/*
Author: Vishal Rajpal
Filename: ExtractZipFilePlugin.java
Date: 21-02-2012
*/
package com.phonegap.plugin.ExtractZipFile;
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.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import org.json.JSONArray;
import org.json.JSONException;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
public class ExtractZipFilePlugin extends Plugin {
@Override
public PluginResult execute(String arg0, JSONArray args, String arg2) {
PluginResult.Status status = PluginResult.Status.OK;
JSONArray result = new JSONArray();
try {
String filename = args.getString(0);
File file = new File(filename);
String[] dirToSplit=filename.split("/");
String dirToInsert="";
for(int i=0;i<dirToSplit.length-1;i++)
{
dirToInsert+=dirToSplit[i]+"/";
}
BufferedOutputStream dest = null;
BufferedInputStream is = null;
ZipEntry entry;
ZipFile zipfile;
try {
zipfile = new ZipFile(file);
Enumeration e = zipfile.entries();
while (e.hasMoreElements())
{
entry = (ZipEntry) e.nextElement();
is = new BufferedInputStream(zipfile.getInputStream(entry));
int count;
byte data[] = new byte[102222];
String fileName = dirToInsert + entry.getName();
File outFile = new File(fileName);
if (entry.isDirectory())
{
outFile.mkdirs();
}
else
{
FileOutputStream fos = new FileOutputStream(outFile);
dest = new BufferedOutputStream(fos, 102222);
while ((count = is.read(data, 0, 102222)) != -1)
{
dest.write(data, 0, count);
}
dest.flush();
dest.close();
is.close();
}
}
} catch (ZipException e1) {
// TODO Auto-generated catch block
return new PluginResult(PluginResult.Status.MALFORMED_URL_EXCEPTION);
} catch (IOException e1) {
// TODO Auto-generated catch block
return new PluginResult(PluginResult.Status.IO_EXCEPTION);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
return new PluginResult(status);
}
}
Include the below .js file in your phonegap project.
/*
Author: Vishal Rajpal
Filename: ZipPlugin.js
Date: 21-02-2012
*/
var ExtractZipFilePlugin=function(){
};
PhoneGap.addConstructor(function()
{
PhoneGap.addPlugin('ExtractZipFilePlugin', new ZipPlugin());
});
ExtractZipFilePlugin.prototype.extractFile = function(file, successCallback, errorCallback)
{
alert(file);
return PhoneGap.exec(successCallback, errorCallback, "ZipPlugin", "extract", [file]);
};
Lastly include this plugin in the plugins.xml of your project.
<plugin name="ZipPlugin" value="com.phonegap.plugin.ExtractZipFile.ExtractZipFilePlugin" />
Usage i.e. .html file
Thanks. Any suggestions or comments will be helpful.
Its about after 2 months I thought of writing a post. So here is it. I was thinking to extract a .zip file from PhoneGap on android and I ended up implementing a plugin for it.
Include the below .java file with the same package mentioned.
/*
Author: Vishal Rajpal
Filename: ExtractZipFilePlugin.java
Date: 21-02-2012
*/
package com.phonegap.plugin.ExtractZipFile;
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.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import org.json.JSONArray;
import org.json.JSONException;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
public class ExtractZipFilePlugin extends Plugin {
@Override
public PluginResult execute(String arg0, JSONArray args, String arg2) {
PluginResult.Status status = PluginResult.Status.OK;
JSONArray result = new JSONArray();
try {
String filename = args.getString(0);
File file = new File(filename);
String[] dirToSplit=filename.split("/");
String dirToInsert="";
for(int i=0;i<dirToSplit.length-1;i++)
{
dirToInsert+=dirToSplit[i]+"/";
}
BufferedOutputStream dest = null;
BufferedInputStream is = null;
ZipEntry entry;
ZipFile zipfile;
try {
zipfile = new ZipFile(file);
Enumeration e = zipfile.entries();
while (e.hasMoreElements())
{
entry = (ZipEntry) e.nextElement();
is = new BufferedInputStream(zipfile.getInputStream(entry));
int count;
byte data[] = new byte[102222];
String fileName = dirToInsert + entry.getName();
File outFile = new File(fileName);
if (entry.isDirectory())
{
outFile.mkdirs();
}
else
{
FileOutputStream fos = new FileOutputStream(outFile);
dest = new BufferedOutputStream(fos, 102222);
while ((count = is.read(data, 0, 102222)) != -1)
{
dest.write(data, 0, count);
}
dest.flush();
dest.close();
is.close();
}
}
} catch (ZipException e1) {
// TODO Auto-generated catch block
return new PluginResult(PluginResult.Status.MALFORMED_URL_EXCEPTION);
} catch (IOException e1) {
// TODO Auto-generated catch block
return new PluginResult(PluginResult.Status.IO_EXCEPTION);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
return new PluginResult(status);
}
}
Include the below .js file in your phonegap project.
/*
Author: Vishal Rajpal
Filename: ZipPlugin.js
Date: 21-02-2012
*/
var ExtractZipFilePlugin=function(){
};
PhoneGap.addConstructor(function()
{
PhoneGap.addPlugin('ExtractZipFilePlugin', new ZipPlugin());
});
ExtractZipFilePlugin.prototype.extractFile = function(file, successCallback, errorCallback)
{
alert(file);
return PhoneGap.exec(successCallback, errorCallback, "ZipPlugin", "extract", [file]);
};
Lastly include this plugin in the plugins.xml of your project.
<plugin name="ZipPlugin" value="com.phonegap.plugin.ExtractZipFile.ExtractZipFilePlugin" />
Usage i.e. .html file
<!--
Author: Vishal Rajpal
Filename: index.html
Date: 21-02-2012
-->
<html>
<head>
<script type="text/javascript" src="phonegap-1.3.0.js"></script>
<script type="text/javascript" src="ZipPlugin.js"></script>
<script type="text/javascript">
document.addEventListener("deviceready",onDeviceReady);
function onDeviceReady()
{
}
function extractFile(fileName)
{
alert(fileName);
var ZipClient = new ExtractZipFilePlugin();
ZipClient.extractFile('sdcard/'+fileName,win,fail,'ExtractZipFilePlugin');
}
function win(status)
{
alert('Success'+status);
}
function fail(error)
{
alert(error);
}
</script>
</head>
<body>
<input type="button" value="Extract Zip File" onClick="extractFile('SampleDir/AnotherDir/SampleFile.zip');"/>
</body>
</html>
Author: Vishal Rajpal
Filename: index.html
Date: 21-02-2012
-->
<html>
<head>
<script type="text/javascript" src="phonegap-1.3.0.js"></script>
<script type="text/javascript" src="ZipPlugin.js"></script>
<script type="text/javascript">
document.addEventListener("deviceready",onDeviceReady);
function onDeviceReady()
{
}
function extractFile(fileName)
{
alert(fileName);
var ZipClient = new ExtractZipFilePlugin();
ZipClient.extractFile('sdcard/'+fileName,win,fail,'ExtractZipFilePlugin');
}
function win(status)
{
alert('Success'+status);
}
function fail(error)
{
alert(error);
}
</script>
</head>
<body>
<input type="button" value="Extract Zip File" onClick="extractFile('SampleDir/AnotherDir/SampleFile.zip');"/>
</body>
</html>
The default location for the file has to be sdcard then it can be as many directories or no directory i.e.
extractFile('SampleFile.zip');
The plugin will work both ways.
Thanks. Any suggestions or comments will be helpful.
Thanks. And I will test it. I need it.
ReplyDeleteI tested it. And it work ok. Thanks.
ReplyDeletei tried it but it gives me this error
ReplyDeleteDefault buffer size used in BufferedInputStream constructor. It would be better to be explicit if an 8k buffer is required.
please what does that mean or what did i get wrong?
Hi Kamal
DeleteTry
new BufferedInputStream(zipfile.getInputStream(entry), 8192);
instead of
new BufferedInputStream(zipfile.getInputStream(entry));
Hi Vishal, I am having a bit of trouble implementing this code in phonegap 1.9.0 I am using it to unzip an epub file and it gets as far as FileOutputStream fos = new FileOutputStream(outFile); but then throws the FileNotFoundException any ideas ? It can definately read the file ok as I can see it loop through all the contents.
ReplyDeleteJust in case someone else has the same issue, I had to add the following two lines File destinationParent = outFile.getParentFile();
DeletedestinationParent.mkdirs();
above:
if (entry.isDirectory())
{
outFile.mkdirs();
}
That's great Sam, I will make the changes and commit it to the phonegap directory.
Deletehi i am using your plugin but is given the error " Uncaught TypeError: Object [object Object] has no method 'extractFile'" i am using cordova-2.0.0.js
ReplyDeleteHi Kapil,
DeleteHere is a link to the plugin
https://github.com/vishalrajpal/phonegap-plugins/tree/master/Android/ExtractZipFile
Though I have added a pull request to PhoneGap repository they haven't updated it yet.
Please, I have same problem in cordova 2.0.0
Delete" Uncaught TypeError: Object [object Object] has no method 'extractFile'"
How can I fix this.
Thank you
Hi Rafa,
DeleteDid you downloaded the plugin from the below github link?
https://github.com/vishalrajpal/phonegap-plugins/tree/master/Android/ExtractZipFile
I have implement this plugin its work fine for 2.0 but how can I get destination directory or location.
ReplyDeleteHi Im...
DeleteThe destination directory is where the .zip file is located.
Thx vishal
Deletebut can we get extract content(listing of extracted zip file ) in success call back or using anything else ?
Success callback is when the zip file is extracted...
Deleteok I am agree with you but I need listing of extracted zip file
Deleteafter the extraction use PhoneGap DirectoryReader....
Deleteisn't that simple??
this plugin is not working for me in 2.3.0 can someone help me implement it?
DeleteHi Neels
DeleteRefer to the below repo as there are some changes in 2.3.0
https://github.com/vishalrajpal/PhoneGap-ZipFile-Plugin-2.3.0
Thanks
Thank you for your help.
DeleteWhen adding the plugin i get "The import java.io.Console cannot be resolved" .
what am i doing wrong and is this needed to perform the unzip?
thanks again.
Neels that was just for debugging. You may remove it.
Deletethank you. got it running but now i get "class not found" on fail. what can be the problem?
Deletechanged the ZipPlugin.js to:
Deletereturn cordova.exec(successCallback, errorCallback, "ZipPlugin", "extract", [file]);
now it seems to get the class
but now i get IO_exception and invalid action?
just cant make this work...... :(
Hi Neels,
DeleteI provided you the link above for the updated plugin. Refer that one. You seem to have using the Old one.
Thank you again for your help.
DeleteI did install the new version again and i still get the class not found
what should be in the config.xml?
DeleteHello Vishal, i am using codova-2.5.0, do i need to make any changes ?
ReplyDeletei am not able to make it work i am getting many errors in ExtracZipFilePlugin.java
Best Regards
Hi Yama,
ReplyDeleteI hope you have downloaded the latest plugin..I will also check this with 2.5.0
Below is the link for recent plugin..
https://github.com/vishalrajpal/phonegap-plugins/tree/master/Android/ExtractZipFile
Hello Vishal,
DeleteI'm using Cordova 2.5.0 too and your latest version (22-01-2013), I get a "Class not found" error :(
What should I change ?
Kind regards
Hi,
DeleteSorry but I will have to look into it, will revert back to you soon
Hello,
DeleteThis worked for me:
replace this:
<plugin name="ZipPlugin" value="com.phonegap.plugin.ExtractZipFile.ExtractZipFilePlugin" />
with this:
<plugin name="ExtractZipFilePlugin" value="com.phonegap.plugin.ExtractZipFile.ExtractZipFilePlugin" />
Not "Class not found" anymore but IO_EXCEPTION instead. But this error is produced by the plugin itself, while "Class not found" is Cordova. I am not sure if it's correct, but that's how I understand that.
Solved IO_Exception. It doesn't create directory prior writing the file. Fortunately my project doesn't require folder structure in data. But I hope it helps you finding errors.
DeleteCheers
Hey Vit, thank you i can solved the "Class not found".. but as you said, i got "IO_Exception" but i dont understand how you solved, could you please guide me a little? Thanks!
DeleteI can't import com.phonegap.api.Plugin; My project does not contain it. Please help me!
ReplyDeleteHi Nguyen,
DeleteUse the latest one from the below link
https://github.com/vishalrajpal/PhoneGap-ZipFile-Plugin-2.3.0
I need to use your plugin with Phonegap 2.8.0.
ReplyDeleteThe configuration used in the documentation doesn't work!
I had to change the ZipFile.js file and the plugin xml node like that:
var ExtractZipFilePlugin=function(){
};
/*cordova.addConstructor(function()
{
cordova.addPlugin('ExtractZipFilePlugin', new ExtractZipFilePlugin());
});*/
if(!window.plugins) {
window.plugins = {};
}
if (!window.plugins.extractZipFilePlugin) {
window.plugins.extractZipFilePlugin = new ExtractZipFilePlugin();
}
ExtractZipFilePlugin.prototype.extractFile = function(file, successCallback, errorCallback)
{
return cordova.exec(successCallback, errorCallback, "ExtractZipFilePlugin", "extract", [file]);
};
When I try to unzip a file now I get the error "invalid action"! What should I do? I download a zip file in the sdcard root then I try to unzip it. Can I set the unzip destination folder?
I need your help as soon as possible.
Thanks
Hi,
ReplyDeleteI also have a problem with your plugin (I'm using phonegap 2.7.0).
According to this article: http://ambrusmartin.wordpress.com/2012/09/17/cordova-2-0-broken-vs-resolved/ this part:
cordova.addConstructor(function()
{
cordova.addPlugin('ExtractZipFilePlugin', new ExtractZipFilePlugin());
});
ExtractZipFilePlugin.prototype.extractFile = function(file, successCallback, errorCallback)
{
return cordova.exec(successCallback, errorCallback, "ExtractZipFilePlugin", "extract", [file]);
};
should be changed to something like:
var ExtractZipFilePlugin = {
extractFile: function(file, successCallback, errorCallback){
cordova.exec(successCallback, errorCallback, "ExtractZipFilePlugin", "extract", [file]);
}
}
But it still doesn't work for me (Error: object is not a function).
Thanks in advance for any help.