Thursday, March 8, 2012

PhoneGap - Download and open a file (pdf, zip, image...)

In the last week I was looking for a solution to show a pdf using phonegap on android and iPhone. Searching on internet I figured out that a possible solution would be the Phonegap ChildBrowser plugin. This plugin basically open the WebView native component and show the address. After some modification (because i needed to use POST request and https protocol) of this plugin I managed to make it work on iPhone. So I did the same modification to the Android code but this time I was not so lucky. I started to find in the network and I came across the Giovesoft Blog post.

The idea was to download the file trough an http/s connection, saving it to the sdcard and opening it. Here is my version of his code. For the installation you can refere to the Giovesoft Blog post.
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import javax.net.ssl.HttpsURLConnection;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
public class DownloadAndOpen extends Plugin {
@Override
public PluginResult execute(String action, JSONArray args, String callbackId) {
if (action.equals("downloadFile")) {
try {
return this.downloadAndOpen(args.getString(0), args.getString(1), args.getString(2),
args.getString(3), args.getString(4), args.getString(5), args.getString(6),
args.getString(7));
} catch (JSONException e) {
return new PluginResult(PluginResult.Status.ERROR, "Param errrors");
}
} else {
return new PluginResult(PluginResult.Status.INVALID_ACTION);
}
}
private PluginResult downloadAndOpen(String fileUrl, String jsonPar, String isPost,
String isHttps, String dirName, String fileName, String mimeType, String overwrite) {
try {
// address can be passed aldo in the json parameter with property name "address"
// building parameters and address
JSONObject jObject = new JSONObject(jsonPar);
Iterator keys = jObject.keys();
String dataToPost = "";
String address = "";
if (fileUrl != null || !(fileUrl.equals("")))
address = fileUrl;
while (keys.hasNext()) {
String key = (String) keys.next();
if (key.equals("address") && (fileUrl == null || fileUrl.equals("")))
address = jObject.getString(key);
else {
if (dataToPost.length() > 0)
dataToPost += "&";
dataToPost += key;
dataToPost += "=" + jObject.getString(key).replace("=", "%3D").replace("/", "%2F");
}
}
if (address.equals(""))
return new PluginResult(PluginResult.Status.ERROR, "Error: Url Address not found");
// saving file on the sdcard
// creating the directory if does not exists
String finalDir = "";
if (dirName == null)
finalDir = Environment.getExternalStorageDirectory() + "/download/";
else
finalDir = Environment.getExternalStorageDirectory() + dirName;
File dir = new File(finalDir);
if (!dir.exists()) {
dir.mkdirs();
}
// creating file
String finalFile = "";
if (fileName == null)
finalFile = "tempfile";
else
finalFile = fileName;
File file = new File(finalDir + finalFile);
if (overwrite.equals("false") && file.exists()) {
Log.d("DownloaderPlugin", "File already exist");
return new PluginResult(PluginResult.Status.OK, "exist");
} else {
boolean isNewFileCreated = file.createNewFile();
if (isNewFileCreated == false) {
file.delete();
file.createNewFile();
}
}
// sending the request
URL url = new URL(address);
InputStream is;
String requestMethod = "GET";
if (isPost.equals("true"))
requestMethod = "POST";
if (isHttps.equals("true")) {
HttpsURLConnection ucon = (HttpsURLConnection) url.openConnection();
ucon.setRequestMethod(requestMethod);
ucon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
ucon.setRequestProperty("Content-Length", Integer.toString(dataToPost.getBytes().length));
ucon.setDoOutput(true);
ucon.connect();
DataOutputStream wr = new DataOutputStream(ucon.getOutputStream());
wr.writeBytes(dataToPost);
wr.flush();
wr.close();
is = ucon.getInputStream();
} else {
HttpURLConnection ucon = (HttpsURLConnection) url.openConnection();
ucon.setRequestMethod(requestMethod);
ucon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
ucon.setRequestProperty("Content-Length", Integer.toString(dataToPost.getBytes().length));
ucon.setDoOutput(true);
ucon.connect();
DataOutputStream wr = new DataOutputStream(ucon.getOutputStream());
wr.writeBytes(dataToPost);
wr.flush();
wr.close();
is = ucon.getInputStream();
}
// processing the response
byte[] buffer = new byte[1024];
int len1 = 0;
FileOutputStream fos = new FileOutputStream(file);
while ((len1 = is.read(buffer)) > 0) {
fos.write(buffer, 0, len1);
}
fos.close();
// opening the file
Uri path = Uri.fromFile(file);
// retriving mime type
String finalMimeType = "";
if (mimeType == null || mimeType.equals(""))
finalMimeType = mimeType;
else {
// most frequent mime types
int lastIndexOfPoint = finalFile.lastIndexOf('.');
String fileExt = finalFile.substring(lastIndexOfPoint + 1);
if (fileExt.equals("zip"))
finalMimeType = "application/x-compressed";
else if (fileExt.equals("txt"))
finalMimeType = "text/plain";
else if (fileExt.equals("jpg") || fileExt.equals("jpeg") || fileExt.equals("jpe"))
finalMimeType = "image/jpeg";
else if (fileExt.equals("png"))
finalMimeType = "image/png";
else if (fileExt.equals("gif"))
finalMimeType = "image/gif";
else if (fileExt.equals("pdf"))
finalMimeType = "application/pdf";
// add more here if necessary...
else
finalMimeType = "text/plain";
}
// opening file
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, finalMimeType);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.ctx.startActivity(intent);
} catch (IOException e) {
return new PluginResult(PluginResult.Status.ERROR, "Error: " + e);
} catch (JSONException e) {
return new PluginResult(PluginResult.Status.ERROR, "Error: " + e);
}
return new PluginResult(PluginResult.Status.OK, fileName);
}
}

function DownloadAndOpen() {
}
DownloadAndOpen.prototype.downloadAndOpen = function(fileUrl, jsonPar, isPost, isHttps, dirName, fileName, mimeType, overwrite, win, fail) {
if (overwrite == false)
overwrite = "false";
else
overwrite = "true";
PhoneGap.exec(win, fail, "DownloadAndOpen", "downloadAndOpen", [fileUrl, jsonPar, isPost, isHttps, dirName, fileName, mimeType, overwrite]);
};
PhoneGap.addConstructor(function() {
PhoneGap.addPlugin("downloader", new DownloadAndOpen());
PluginManager.addService("DownloadAndOpen", "com.phonegap.plugins.downloader.DownloadAndOpen");
});

Looking forward for you comments! Ciao

No comments: