【问题标题】:Android Image Upload ServiceAndroid 图片上传服务
【发布时间】: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


    【解决方案1】:

    您可以尝试使用一些库来组织多个任务,例如 goro( https://github.com/stanfy/goro)

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

    对不起我的英语不好

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-05
      • 1970-01-01
      • 2014-07-18
      • 1970-01-01
      • 2017-05-04
      • 2021-11-29
      • 2012-04-16
      相关资源
      最近更新 更多