Android图片上传服务

时间:2015-08-11 23:08:42

标签: android file-upload android-asynctask android-service androidhttpclient

我正在寻找一种良好的上传服务方式来处理多个上传请求。目标应该是显示所有上传的实际进度的通知。

从现在起我就开始为每个请求调用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);
        }
    }
}

如果有人能让我走上正轨,那将是非常好的。非常感谢你!

1 个答案:

答案 0 :(得分:0)

你可以尝试使用一些库来组织像goro这样的多个任务( https://github.com/stanfy/goro

此外,您可以在自己的单独服务中使用新线程,并在线程内使用类BlockingQueue或类Handler的子类。在我看来,这是更复杂的工作。

Sory因为我的英语不好