This repository has been archived by the owner on Apr 29, 2021. It is now read-only.
forked from purplecabbage/phonegap-plugins
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Matt Kane
committed
Nov 5, 2010
1 parent
ae67c7d
commit 3cc7031
Showing
3 changed files
with
383 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,245 @@ | ||
/** | ||
* | ||
*/ | ||
package com.beetight; | ||
|
||
import java.io.DataOutputStream; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.FileNotFoundException; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.net.HttpURLConnection; | ||
import java.net.MalformedURLException; | ||
import android.net.Uri; | ||
import java.net.URL; | ||
import java.util.Iterator; | ||
|
||
import org.json.JSONArray; | ||
import org.json.JSONException; | ||
import org.json.JSONObject; | ||
|
||
import android.util.Log; | ||
import android.webkit.CookieManager; | ||
|
||
import com.phonegap.api.Plugin; | ||
import com.phonegap.api.PluginResult; | ||
|
||
/** | ||
* @author matt | ||
* | ||
*/ | ||
public class FileUploader extends Plugin { | ||
|
||
/* (non-Javadoc) | ||
* @see com.phonegap.api.Plugin#execute(java.lang.String, org.json.JSONArray, java.lang.String) | ||
*/ | ||
@Override | ||
public PluginResult execute(String action, JSONArray args, String callbackId) { | ||
|
||
try { | ||
String server = args.getString(0); | ||
String file = args.getString(1); | ||
JSONObject params = args.getJSONObject(2); | ||
|
||
String fileKey = "file"; | ||
String fileName = "image.jpg"; | ||
String mimeType = "image/jpeg"; | ||
if(args.length() > 3) { | ||
fileKey = args.getString(3); | ||
} | ||
if(args.length() > 4) { | ||
fileName = args.getString(4); | ||
} | ||
if(args.length() > 5) { | ||
mimeType = args.getString(5); | ||
} | ||
|
||
if (action.equals("upload")) { | ||
upload(file, server, params, fileKey, fileName, mimeType, callbackId); | ||
} else if (action.equals("uploadByUri")) { | ||
Uri uri = Uri.parse(file); | ||
upload(uri, server, params, fileKey, fileName, mimeType, callbackId); | ||
} else { | ||
return new PluginResult(PluginResult.Status.INVALID_ACTION); | ||
} | ||
PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT); | ||
r.setKeepCallback(true); | ||
return r; | ||
} catch (JSONException e) { | ||
e.printStackTrace(); | ||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION); | ||
} | ||
|
||
} | ||
|
||
public void upload(Uri uri, String server, JSONObject params, final String fileKey, final String fileName, final String mimeType, String callbackId) { | ||
try { | ||
InputStream fileInputStream=this.ctx.getContentResolver().openInputStream(uri); | ||
upload(fileInputStream, server, params, fileKey, fileName, mimeType, callbackId); | ||
} catch (FileNotFoundException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
} | ||
} | ||
|
||
public void upload(String filename, String server, JSONObject params, final String fileKey, final String fileName, final String mimeType, String callbackId) { | ||
File uploadFile = new File(filename); | ||
try { | ||
FileInputStream fileInputStream = new FileInputStream(uploadFile); | ||
upload(fileInputStream, server, params, fileKey, fileName, mimeType, callbackId); | ||
} catch (FileNotFoundException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
} | ||
|
||
} | ||
|
||
|
||
public void upload(InputStream fileInputStream, String server, JSONObject params, final String fileKey, final String fileName, final String mimeType, final String callbackId) { | ||
try { | ||
|
||
String lineEnd = "\r\n"; | ||
String td = "--"; | ||
String boundary = "*****com.beetight.formBoundary"; | ||
|
||
URL url = new URL(server); | ||
HttpURLConnection conn = (HttpURLConnection)url.openConnection(); | ||
|
||
// Get cookies that have been set in our webview | ||
CookieManager cm = CookieManager.getInstance(); | ||
String cookie = cm.getCookie(server); | ||
|
||
// allow inputs | ||
conn.setDoInput(true); | ||
// allow outputs | ||
conn.setDoOutput(true); | ||
// don't use a cached copy | ||
conn.setUseCaches(false); | ||
// use a post method | ||
conn.setRequestMethod("POST"); | ||
// set post headers | ||
conn.setRequestProperty("Connection","Keep-Alive"); | ||
conn.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary); | ||
conn.setRequestProperty("Cookie", cookie); | ||
// open data output stream | ||
DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); | ||
|
||
try { | ||
for (Iterator iter = params.keys(); iter.hasNext();) { | ||
Object key = iter.next(); | ||
dos.writeBytes(td + boundary + lineEnd); | ||
dos.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"); "); | ||
dos.writeBytes(lineEnd + lineEnd); | ||
dos.writeBytes(params.getString(key.toString())); | ||
dos.writeBytes(lineEnd); | ||
} | ||
} catch (JSONException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
} | ||
|
||
|
||
dos.writeBytes(td + boundary + lineEnd); | ||
dos.writeBytes("Content-Disposition: form-data; name=\"" + fileKey + "\";filename=\"" + fileName + "\"" + lineEnd); | ||
dos.writeBytes("Content-Type: " + mimeType + lineEnd); | ||
|
||
dos.writeBytes(lineEnd); | ||
// create a buffer of maximum size | ||
int bytesAvailable = fileInputStream.available(); | ||
final int total = bytesAvailable; | ||
Log.e("PhoneGapLog", "available: " + bytesAvailable); | ||
|
||
int maxBufferSize = 1024; | ||
int bufferSize = Math.min(bytesAvailable, maxBufferSize); | ||
byte[] buffer = new byte[bufferSize]; | ||
// read file and write it into form... | ||
int bytesRead = fileInputStream.read(buffer, 0, bufferSize); | ||
int progress = bytesRead; | ||
int send = 0; | ||
while (bytesRead > 0) | ||
{ | ||
dos.write(buffer, 0, bufferSize); | ||
bytesAvailable = fileInputStream.available(); | ||
bufferSize = Math.min(bytesAvailable, maxBufferSize); | ||
bytesRead = fileInputStream.read(buffer, 0, bufferSize); | ||
progress += bytesRead; | ||
final int prog = progress; | ||
Log.e("PhoneGapLog", "read " + progress + " of " + total); | ||
|
||
// Sending every progress event is overkill | ||
if (send++ % 20 == 0) { | ||
ctx.runOnUiThread(new Runnable () { | ||
public void run() { | ||
try { | ||
JSONObject result = new JSONObject(); | ||
result.put("status", FileUploader.Status.PROGRESS); | ||
result.put("progress", prog); | ||
result.put("total", total); | ||
PluginResult progressResult = new PluginResult(PluginResult.Status.OK, result); | ||
progressResult.setKeepCallback(true); | ||
success(progressResult, callbackId); | ||
} catch (JSONException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
} | ||
} | ||
}); | ||
// Give a chance for the progress to be sent to javascript | ||
Thread.sleep(100); | ||
} | ||
} | ||
// send multipart form data necessary after file data... | ||
dos.writeBytes(lineEnd); | ||
dos.writeBytes(td + boundary + td + lineEnd); | ||
|
||
// close streams | ||
fileInputStream.close(); | ||
dos.flush(); | ||
InputStream is = conn.getInputStream(); | ||
int ch; | ||
StringBuffer b =new StringBuffer(); | ||
while( ( ch = is.read() ) != -1 ) { | ||
b.append( (char)ch ); | ||
} | ||
String s=b.toString(); | ||
dos.close(); | ||
JSONObject result = new JSONObject(); | ||
result.put("status", FileUploader.Status.COMPLETE); | ||
|
||
result.put("progress", progress); | ||
result.put("total", total); | ||
result.put("result", s); | ||
PluginResult progressResult = new PluginResult(PluginResult.Status.OK, result); | ||
progressResult.setKeepCallback(true); | ||
success(progressResult, callbackId); | ||
|
||
} | ||
catch (MalformedURLException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
PluginResult result = new PluginResult(PluginResult.Status.MALFORMED_URL_EXCEPTION, e.getMessage()); | ||
error(result, callbackId); | ||
} | ||
catch (FileNotFoundException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, e.getMessage()); | ||
error(result, callbackId); | ||
} | ||
catch (IOException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
PluginResult result = new PluginResult(PluginResult.Status.IO_EXCEPTION, e.getMessage()); | ||
error(result, callbackId); | ||
} catch (InterruptedException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, e.getMessage()); | ||
error(result, callbackId); | ||
} catch (JSONException e) { | ||
Log.e("PhoneGapLog", "error: " + e.getMessage(), e); | ||
PluginResult result = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage()); | ||
error(result, callbackId); | ||
} | ||
} | ||
|
||
public enum Status { | ||
PROGRESS, | ||
COMPLETE | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# File Uploader plugin for Phonegap # | ||
By Matt Kane | ||
|
||
## Adding the Plugin to your project ## | ||
|
||
1. To install the plugin, move fileuploader.js to your project's www folder and include a reference to it | ||
in your html files. | ||
2. Create a folder called "beetight" within your project's src/com/ folder and move the java file into it. | ||
|
||
## Using the plugin ## | ||
The plugin creates the object `window.plugins.fileUploader` with two methods, `upload` and `uploadByUri`. | ||
These are identical except for the format of the reference to the file to upload. `upload` takes an | ||
absolute path, e.g. `/sdcard/media/images/image.jpg`, while `uploadByUri` takes a content:// Uri, | ||
e.g. `content://media/external/images/media/5`. | ||
The full params are as follows: | ||
|
||
* server URL of the server that will receive the file | ||
* file Path or uri of the file to upload | ||
* fileKey Object with key: value params to send to the server | ||
* params Parameter name of the file | ||
* fileName Filename to send to the server. Defaults to image.jpg | ||
* mimeType Mimetype of the uploaded file. Defaults to image/jpeg | ||
* callback Success callback. Also receives progress messages during upload. | ||
* fail Error callback | ||
|
||
Note that the success callback isn't just called when the upload is complete, but also gets progress | ||
events while the file is uploaded. It's passed an object of the form: | ||
|
||
{ | ||
status: 'PROGRESS', //Either FileUploader.Status.PROGRESS or FileUploader.Status.COMPLETE, | ||
progress: 0, //The number of bytes uploaded so far. | ||
total: 1000, //The total number of bytes to upload. | ||
result: "OK" //The string returned from the server. Only sent when status = complete. | ||
} | ||
|
||
This is under development, and the API is likely to change. | ||
|
||
|
||
## BUGS AND CONTRIBUTIONS ## | ||
The latest bleeding-edge version is available [on GitHub](http://github.com/ascorbic/phonegap-plugins/tree/master/Android/) | ||
If you have a patch, fork my repo baby and send me a pull request. Submit bug reports on GitHub, please. | ||
|
||
## Licence ## | ||
|
||
The MIT License | ||
|
||
Copyright (c) 2010 Matt Kane | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* Phonegap File Upload plugin | ||
* Copyright (c) Matt Kane 2010 | ||
* | ||
*/ | ||
var FileUploader = function() { | ||
|
||
} | ||
|
||
|
||
/** | ||
* Given a content:// uri, uploads the file to the server as a multipart/mime request | ||
* | ||
* @param server URL of the server that will receive the file | ||
* @param file content:// uri of the file to upload | ||
* @param fileKey Object with key: value params to send to the server | ||
* @param params Parameter name of the file | ||
* @param fileName Filename to send to the server. Defaults to image.jpg | ||
* @param mimeType Mimetype of the uploaded file. Defaults to image/jpeg | ||
* @param callback Success callback. Also receives progress messages during upload. | ||
* @param fail Error callback | ||
*/ | ||
FileUploader.prototype.uploadByUri = function(server, file, params, fileKey, fileName, mimeType, callback, fail) { | ||
|
||
return PhoneGap.exec(function(args) { | ||
callback(args); | ||
}, function(args) { | ||
if(typeof fail == 'function') { | ||
fail(args); | ||
} | ||
}, 'FileUploader', 'uploadByUri', [server, file, params, fileKey, fileName, mimeType]); | ||
}; | ||
|
||
/** | ||
* Given absolute path, uploads the file to the server as a multipart/mime request | ||
* | ||
* @param server URL of the server that will receive the file | ||
* @param file Absolute path of the file to upload | ||
* @param fileKey Object with key: value params to send to the server | ||
* @param params Parameter name of the file | ||
* @param fileName Filename to send to the server. Defaults to image.jpg | ||
* @param mimeType Mimetype of the uploaded file. Defaults to image/jpeg | ||
* @param callback Success callback. Also receives progress messages during upload. | ||
* @param fail Error callback | ||
*/ | ||
FileUploader.prototype.upload = function(server, file, params, fileKey, fileName, mimeType, callback, fail) { | ||
|
||
return PhoneGap.exec(function(args) { | ||
if(typeof callback == 'function') { | ||
callback(args); | ||
} | ||
}, function(args) { | ||
if(typeof fail == 'function') { | ||
fail(args); | ||
} | ||
}, 'FileUploader', 'upload', [server, file, params, fileKey, fileName, mimeType]); | ||
}; | ||
|
||
|
||
FileUploader.Status = { | ||
PROGRESS: "PROGRESS", | ||
COMPLETE: "COMPLETE" | ||
} | ||
|
||
PhoneGap.addConstructor(function() { | ||
PhoneGap.addPlugin('fileUploader', new FileUploader()); | ||
PluginManager.addService("FileUploader","com.beetight.FileUploader"); | ||
}); |