【发布时间】:2015-11-04 08:53:47
【问题描述】:
我正在寻找一种工作良好的上传服务来处理多个上传请求。目的应该是显示所有上传的实际进度的通知。
从现在开始,我开始为每个请求调用 AsyncTask,但这样我就不会收到所有请求的通知,每个请求只会收到一个通知。
我阅读了有关使用服务的信息,但找不到任何有关让服务(也可能是 IntentService)处理多个请求的信息。再次指出:用户应该能够随时开始上传,并且应该能够随时“添加”新的上传,但上传应该在后台运行,因为要上传的内容是大小可变的图像,这意味着它们可能会变得很大。同样重要的是添加自定义字符串实体的能力,例如在代码中标记为“附加...”,...
这里是我的 AsyncTask 的实际代码:
import java.io.File;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.app.NotificationManager;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log;
public class ImageUploader extends AsyncTask<String, Integer, String> {
private Context context;
private String name = null;
private String filePath = null;
private NotificationManager mNotifyManager;
private Builder mBuilder;
public void setContext(Context context, String name){
this.context = context;
this.name = name;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle(name)
.setContentText("Image is being uploaded")
.setSmallIcon(android.R.drawable.ic_menu_upload);
mBuilder.setProgress(100, 0, false);
mNotifyManager.notify(1, mBuilder.build());
}
@Override
protected void onProgressUpdate(Integer... progress) {
mBuilder.setProgress(100, progress[0], false);
mNotifyManager.notify(1, mBuilder.build());
super.onProgressUpdate(progress);
}
@Override
protected String doInBackground(String... params) {
filePath = params[0];
return uploadFile();
}
private String uploadFile() {
String responseString = null;
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(SERVER_PHP_URL);
httpclient.getCredentialsProvider().setCredentials(new AuthScope(SERVER_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials(SERVER_USER, SERVER_PASSWORD));
try {
AndroidMultiPartEntity entity = new AndroidMultiPartEntity(
new ProgressListener() {
@Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
});
File sourceFile = new File(filePath);
entity.addPart("image", new FileBody(sourceFile));
entity.addPart("additional...", new StringBody("anything"));
entity.addPart("additional2...", new StringBody("anything"));
totalSize = entity.getContentLength();
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
responseString = EntityUtils.toString(r_entity);
} else {
responseString = "Error occurred! Http Status Code: "
+ statusCode;
}
} catch (ClientProtocolException e) {
responseString = e.toString();
} catch (IOException e) {
responseString = e.toString();
}
return responseString;
}
@Override
protected void onPostExecute(String result) {
mBuilder.setContentText("Image uploaded successfully");
mBuilder.setProgress(0, 0, false);
mNotifyManager.notify(1, mBuilder.build());
super.onPostExecute(result);
}
}
自定义的MultipartEntity如下:
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
public class AndroidMultiPartEntity extends MultipartEntity {
private final ProgressListener listener;
public AndroidMultiPartEntity(final ProgressListener listener) {
super();
this.listener = listener;
}
public AndroidMultiPartEntity(final HttpMultipartMode mode,
final ProgressListener listener) {
super(mode);
this.listener = listener;
}
public AndroidMultiPartEntity(HttpMultipartMode mode, final String boundary, final Charset charset, final ProgressListener listener) {
super(mode, boundary, charset);
this.listener = listener;
}
@Override
public void writeTo(final OutputStream outstream) throws IOException {
super.writeTo(new CountingOutputStream(outstream, this.listener));
}
public static interface ProgressListener {
void transferred(long num);
}
public static class CountingOutputStream extends FilterOutputStream {
private final ProgressListener listener;
private long transferred;
public CountingOutputStream(final OutputStream out,
final ProgressListener listener) {
super(out);
this.listener = listener;
this.transferred = 0;
}
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
this.transferred += len;
this.listener.transferred(this.transferred);
}
public void write(int b) throws IOException {
out.write(b);
this.transferred++;
this.listener.transferred(this.transferred);
}
}
}
如果有人能让我走上正轨,那就太好了。非常感谢!
【问题讨论】:
标签: android file-upload android-asynctask android-service androidhttpclient