Я ищу способ хорошо работающей службы загрузки для обработки нескольких запросов на загрузку. Целью должно быть отображение уведомления о фактическом ходе всех загрузок вместе.
С тех пор я получил работу с вызовом AsyncTask для каждого запроса, но таким образом я не получаю одно уведомление для всех из них, только по одному для каждого.
Я читал об использовании служб, но не смог найти ничего о получении службы (также может быть IntentService), обрабатывающей более одного запроса. Просто чтобы указать на это еще раз: пользователь должен иметь возможность начать загрузку в любое время и должен иметь возможность «добавить» новую загрузку в любое время, но загрузка должна выполняться в фоновом режиме, потому что то, что будет загружено являются изображениями переменного размера, это означает, что они могут стать довольно большими. Также важна возможность добавления настраиваемых сущностей String, например, отмеченных в коде как «дополнительные ...», ...
Вот фактический код моей 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);
}
}
}
Было бы очень здорово, если бы кто-нибудь мог направить меня на верный путь. Большое спасибо!