我使用以下代码通过MultipartEntityBuilder将照片上传到我的服务器。在最后的某个地方它说// FIXME Put your progress bar stuff here!
。我不知道是不是应该把整个函数放到Asynctask中,或者在文件上传时我应该怎么做才能显示进度。
我查了Upload a file through an HTTP form, via MultipartEntityBuilder, with a progress bar,但它并没有真正帮助。
public String postFile(String fileName) throws Exception {
fileName = "/mnt/sdcard/DCIM/100MEDIA/IMAG0309.jpg";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://www.mywebsite.com/upload_file.php");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
final File file = new File(fileName);
FileBody fb = new FileBody(file);
builder.addPart("file",fb);
String userid = session_userid;
builder.addTextBody("userID", userid);
final HttpEntity yourEntity = builder.build();
class ProgressiveEntity implements HttpEntity {
@Override
public void consumeContent() throws IOException {
yourEntity.consumeContent();
}
@Override
public InputStream getContent() throws IOException,
IllegalStateException {
return yourEntity.getContent();
}
@Override
public Header getContentEncoding() {
return yourEntity.getContentEncoding();
}
@Override
public long getContentLength() {
return yourEntity.getContentLength();
}
@Override
public Header getContentType() {
return yourEntity.getContentType();
}
@Override
public boolean isChunked() {
return yourEntity.isChunked();
}
@Override
public boolean isRepeatable() {
return yourEntity.isRepeatable();
}
@Override
public boolean isStreaming() {
return yourEntity.isStreaming();
} // CONSIDER put a _real_ delegator into here!
@Override
public void writeTo(OutputStream outstream) throws IOException {
class ProxyOutputStream extends FilterOutputStream {
public ProxyOutputStream(OutputStream proxy) {
super(proxy);
}
public void write(int idx) throws IOException {
out.write(idx);
}
public void write(byte[] bts) throws IOException {
out.write(bts);
}
public void write(byte[] bts, int st, int end) throws IOException {
out.write(bts, st, end);
}
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
out.close();
}
}
class ProgressiveOutputStream extends ProxyOutputStream {
int totalSent;
public ProgressiveOutputStream(OutputStream proxy) {
super(proxy);
}
public void write(byte[] bts, int st, int end) throws IOException {
// FIXME Put your progress bar stuff here!
out.write(bts, st, end);
}
}
yourEntity.writeTo(new ProgressiveOutputStream(outstream));
}
};
ProgressiveEntity myEntity = new ProgressiveEntity();
post.setEntity(myEntity);
HttpResponse response = client.execute(post);
return getContent(response);
}
这是我的所作所为,但我仍需要你们完成它:
@Override
protected String doInBackground(HttpResponse... arg0)
{
String fileName = "/mnt/sdcard/DCIM/100MEDIA/IMAG0309.jpg";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://www.mywebsite.com/upload_file.php");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
final File file = new File(fileName);
FileBody fb = new FileBody(file);
builder.addPart("file",fb);
String userid = session_userid;
builder.addTextBody("userID", userid);
final HttpEntity yourEntity = builder.build();
class ProgressiveEntity implements HttpEntity {
@Override
public void consumeContent() throws IOException {
yourEntity.consumeContent();
}
@Override
public InputStream getContent() throws IOException,
IllegalStateException {
return yourEntity.getContent();
}
@Override
public Header getContentEncoding() {
return yourEntity.getContentEncoding();
}
@Override
public long getContentLength() {
return yourEntity.getContentLength();
}
@Override
public Header getContentType() {
return yourEntity.getContentType();
}
@Override
public boolean isChunked() {
return yourEntity.isChunked();
}
@Override
public boolean isRepeatable() {
return yourEntity.isRepeatable();
}
@Override
public boolean isStreaming() {
return yourEntity.isStreaming();
} // CONSIDER put a _real_ delegator into here!
@Override
public void writeTo(OutputStream outstream) throws IOException {
class ProxyOutputStream extends FilterOutputStream {
public ProxyOutputStream(OutputStream proxy) {
super(proxy);
}
public void write(int idx) throws IOException {
out.write(idx);
}
public void write(byte[] bts) throws IOException {
out.write(bts);
}
public void write(byte[] bts, int st, int end) throws IOException {
out.write(bts, st, end);
}
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
out.close();
}
}
class ProgressiveOutputStream extends ProxyOutputStream {
public ProgressiveOutputStream(OutputStream proxy) {
super(proxy);
int totalSent = 0;
}
public void write(byte[] bts, int st, int end) throws IOException {
// FIXME Put your progress bar stuff here!
//what's totalSize?
publishProgress((int) ((end / (float) totalSize) * 100));
out.write(bts, st, end);
}
}
yourEntity.writeTo(new ProgressiveOutputStream(outstream));
}
};
ProgressiveEntity myEntity = new ProgressiveEntity();
post.setEntity(myEntity);
HttpResponse response = client.execute(post);
return getContent(response);
//Here it says I should put this into a try catch but then I get an error on
// the doInBackground line saying it needs to return a string
}
protected void onProgressUpdate(Integer... progress) {
pd.setProgress((int) (progress[0]));
}
@SuppressWarnings("deprecation")
@Override
protected void onPostExecute(String file_url) {
pd.dismiss();
connection.disconnect();
Toast.makeText(getApplicationContext(), "Ready.", Toast.LENGTH_LONG).show();
}
}
答案 0 :(得分:3)
我试图实现类似的功能(我使用ProgressDialog
代替ProgressBar
)。您必须使用AsyncTask
,因此主线程不会等待您的上传完成(上传必须是异步的)。
为HttpEntityWrapped
创建扩展程序(信用:here):
public class MyHttpEntity extends HttpEntityWrapper {
private ProgressListener progressListener;
public MyHttpEntity(final HttpEntity entity, final ProgressListener progressListener) {
super(entity);
this.progressListener = progressListener;
}
@Override
public void writeTo(OutputStream outStream) throws IOException {
this.wrappedEntity.writeTo(outStream instanceof ProgressOutputStream ? outStream :
new ProgressOutputStream(outStream, this.progressListener,
this.getContentLength()));
}
public static interface ProgressListener {
void transferred(float progress);
}
public static class ProgressOutputStream extends FilterOutputStream {
private final ProgressListener progressListener;
private long transferred;
private long total;
public ProgressOutputStream(final OutputStream outputStream,
final ProgressListener progressListener,
long total) {
super(outputStream);
this.progressListener = progressListener;
this.transferred = 0;
this.total = total;
}
@Override
public void write(byte[] buffer, int offset, int length) throws IOException {
out.write(buffer, offset, length);
this.transferred += length;
this.progressListener.transferred(this._getCurrentProgress());
}
@Override
public void write(byte[] buffer) throws IOException {
out.write(buffer);
this.transferred++;
this.progressListener.transferred(this._getCurrentProgress());
}
private float _getCurrentProgress() {
return ((float) this.transferred / this.total) * 100;
}
}
}
我创建了一个在AsyncTask
中扩展Activity
的私有类。在doInBackground
中,您使用MultipartEntityBuilder
添加您的文件和任何您想要的内容。如果上传成功(代码== 200,这是我的自定义json响应),将调用onPostExecute
。
私有类UploadAsyncTask扩展了AsyncTask {
private Context context;
private Exception exception;
private ProgressDialog progressDialog;
private UploadAsyncTask(Context context) {
this.context = context;
}
@Override
protected Boolean doInBackground(String... params) {
String uploadUrl = URL + "upload";
HttpResponse response = null;
try {
HttpPost post = new HttpPost(uploadUrl);
// Entity
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
// Add your file
multipartEntityBuilder.addPart("file", new FileBody(new File(params[0])));
// Progress listener - updates task's progress
MyHttpEntity.ProgressListener progressListener =
new MyHttpEntity.ProgressListener() {
@Override
public void transferred(float progress) {
UploadAsyncTask.this.publishProgress((int) progress);
}
};
// POST
post.setEntity(new MyHttpEntity(multipartEntityBuilder.build(),
progressListener));
// Handle response
GsonBuilder builder = new GsonBuilder();
LinkedTreeMap object = builder.create().fromJson(
EntityUtils.toString(client.execute(post).getEntity()),
LinkedTreeMap.class);
if ((double) object.get("code") == 200.0) {
return true;
}
} catch (UnsupportedEncodingException | JsonSyntaxException | ClientProtocolException e) {
e.printStackTrace();
Log.e("UPLOAD", e.getMessage());
this.exception = e;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
@Override
protected void onPreExecute() {
// Init and show dialog
this.progressDialog = new ProgressDialog(this.context);
this.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
this.progressDialog.show();
}
@Override
protected void onPostExecute(Boolean result) {
// Close dialog
this.progressDialog.dismiss();
if (result) {
Toast.makeText(getApplicationContext(),
R.string.upload_success, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
R.string.upload_failure, Toast.LENGTH_LONG).show();
}
}
@Override
protected void onProgressUpdate(Integer... progress) {
// Update process
this.progressDialog.setProgress((int) progress[0]);
}
}
在Acitvity
:
private void _upload(){
UploadAsyncTask task = new UploadAsyncTask(this);
task.execute();
}