Android-我想向用户显示文件上传进度

Android-我想向用户显示文件上传进度,android,Android,我通过Android SDK中的默认HttpClient将照片上传到服务器。我想在用户界面上显示进度,有没有办法知道上传了多少?HttpUrlConnection可以吗?我没有使用该API,但请注意HttpClient不是特定于android的: org.apache.http.client.HttpClient 因此,如果你在谷歌上搜索“HttpClient progress”,有许多帖子可能是有用的 也可以考虑, 或使用AcyCtaskTo进行文件上传的实际过程,并使用PrimeCudio

我通过Android SDK中的默认HttpClient将照片上传到服务器。我想在用户界面上显示进度,有没有办法知道上传了多少?HttpUrlConnection可以吗?

我没有使用该API,但请注意HttpClient不是特定于android的:

org.apache.http.client.HttpClient
因此,如果你在谷歌上搜索“HttpClient progress”,有许多帖子可能是有用的


也可以考虑,

或使用AcyCtaskTo进行文件上传的实际过程,并使用PrimeCudio启动和停止进程。 您可以看到这段代码,我编写它是为了通过HTTP加载JSON数据,并使用process dialog

守则的主要部分是:

 private class LoadStoresTask extends AsyncTask<String, Void, List<Store>> {

@Override
protected List<Store> doInBackground(String... params) {
return WsiStoresClient.connect(params[0]);
}

@Override
protected void onPostExecute(List<Store> result) {
dismissDialog(BUSY_DIALOG_KEY);
}

}
私有类LoadStoresTask扩展异步任务{
@凌驾
受保护列表doInBackground(字符串…参数){
返回wsistoreclient.connect(参数[0]);
}
@凌驾
受保护的void onPostExecute(列表结果){
dismissDialog(忙对话框键);
}
}

我没有使用httpclient,但我已经使用
异步任务做了一些您想要的事情

    private class DownloadImageTask extends AsyncTask<String, Void,Bitmap>{
            protected Bitmap doInBackground(String... urls) {

              while (myProgress<length){
                       myProgress=myProgress+1;  
                       myProgressBar.setProgress(myProgress);

                }
                 return decodeImage(urls[0]);
            }


           protected void onPostExecute(Bitmap result) {
                //dialog.dismiss();
                imView.setImageBitmap(result);
            }   

            protected void onPreExecute() {
                /* Things to be done while execution of long running operation is 
                 in progress. For example updating ProgressDialog */

               dialog = ProgressDialog.show(BusinessCardActivity.this,
                      "Loading.........","Wait For Few Second", true);          
                }
             }
私有类下载ImageTask扩展异步任务{
受保护位图doInBackground(字符串…URL){

而(myProgress对于我来说,HTTPClient不起作用。在flush调用之后,部分缓冲并作为总计发送的字节。起作用的是在套接字级别发送它

您可以为此使用HttpMultipartClient(2011年10月30日更新的链接):

指定每个部分的字节数,并更新while循环中的progressbar:

而((line=reader.readLine())!=null&&!headersEnd)

调用HttpMultipartClient,如下所示:

HttpMultipartClient httpMultipartClient = new HttpMultipartClient("bluppr.com", "/api/order/create", 80);

FileInputStream fis = new FileInputStream(path + fileName);
httpMultipartClient.addFile(fileName, fis, fis.available());
httpMultipartClient.setRequestMethod("POST");
httpMultipartClient.send();
在服务器端使用:

<?php

$target_path = "uploads/";

$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    echo "The file ".  basename( $_FILES['uploadedfile']['name'])." has been uploaded " .$_POST["order"]. " post";
} else{
    echo "There was an error uploading the file, please try again!";
}

?>

我用它制作Bluppr明信片,效果很好。如果您需要更多信息,请告诉我。

1)请确保使用自己的线程在服务中执行上载

2) 要获得进度:将InputStream包装在这个类中,并使用一个对HttpClient具有多部分支持的httpime.jar库。我使用了一个线程来检查进度并更新通知中的progressbar

package com.hyves.android.service.upload;

import java.io.IOException;
import java.io.InputStream;

/**
 * This outputstream wraps an existing outputstream and provides 
 * callbacks after certain amount of bytes to a HttpCallback
 * 
 * @author tjerk
 */
public class ProgressNotifyingInputStream extends InputStream {
    private InputStream wrappedStream;
    private int count = 0;
    private int totalSize;

    /**
     * Creates a new notifying outputstream which wraps an existing one.
     * When you write to this stream the callback will be notified each time when
     * updateAfterNumberBytes is written.
     * 
     * @param stream the outputstream to be wrapped
     * @param totalSize the totalsize that will get written to the stream
     */
    public ProgressNotifyingInputStream(InputStream stream, int totalSize) {
        if(stream==null) {
            throw new NullPointerException();
        }
        if(totalSize == 0) {
            throw new IllegalArgumentException("totalSize argument cannot be zero");
        }
        this.wrappedStream = stream;
        this.totalSize = totalSize;
    }


    @Override
    public int read() throws IOException {
        count++;
        return wrappedStream.read();
    }

    /**
     * Get progress from 0 to 100
     * @return
     */
    public int getProgress() {
        return count * 100 / totalSize;
    }

}
@Override
protected void onPostExecute(String result) {

    String resultString = null;
    if (MainActivity.isDebugMode){
        Log.d(TAG, "Async result: "+result);
    }

    boolean successful = false;
    String[] errorMessages = null;
    try {
        JSONObject mainObject = new JSONObject(result);
        String resultJsonString = mainObject.getString("result");
        JSONArray messagesJsonArray = mainObject.getJSONArray("messages");
        if (resultJsonString != null){
            if (resultJsonString.equalsIgnoreCase("success")){
                successful = true;
            } else {
                Log.e(TAG, "result was: "+resultJsonString);
            }
        }
        errorMessages = new String[messagesJsonArray.length()];
        for (int i = 0; i < messagesJsonArray.length(); i++){
            errorMessages[i]= (String)messagesJsonArray.get(i);
        }
    } catch (JSONException e){
        Log.e(TAG, "JSON Exception -- The string that I tried to parse was:\n"+result);
        e.printStackTrace();
    }

    if (successful) {
        Toast.makeText(this.activity, "Upload completed successfully!", Toast.LENGTH_SHORT).show();
        resultString = "Upload complete.";
    } else {
        String eMessages;
        if (errorMessages != null && errorMessages.length > 0){
            eMessages = TextUtils.join(", ", errorMessages);
            resultString = "Image upload failed:\n"+eMessages;
        } else {
            resultString = "Image upload failed!";
        }
    }
    ((ImageUploadActivity) activity).updateProgress(null);
    ((ImageUploadActivity) activity).setPostResult(resultString);
}

我写了一个具体的例子来说明如何做到这一点->

我需要图像的上传进度,但由于实现问题(无法通过渐变和依赖错误获取包),我没有使用HttpMultipartClient。 我遇到的另一个问题是获取我想要上传的图像的实际文件大小

我的要求还包括在通知区上载。以下是我的解决方案:

获取图像大小
AsyncHttpPostTask#doInBackground
正如我前面提到的,我没有使用
HttpMultipartClient
,所以我必须实现我自己的

AsyncHttpPostTask#onPostExecute
在这里,我解析服务器的JSON响应,查看上传是否能够成功处理,然后向控制通知的活动返回一条消息

package com.hyves.android.service.upload;

import java.io.IOException;
import java.io.InputStream;

/**
 * This outputstream wraps an existing outputstream and provides 
 * callbacks after certain amount of bytes to a HttpCallback
 * 
 * @author tjerk
 */
public class ProgressNotifyingInputStream extends InputStream {
    private InputStream wrappedStream;
    private int count = 0;
    private int totalSize;

    /**
     * Creates a new notifying outputstream which wraps an existing one.
     * When you write to this stream the callback will be notified each time when
     * updateAfterNumberBytes is written.
     * 
     * @param stream the outputstream to be wrapped
     * @param totalSize the totalsize that will get written to the stream
     */
    public ProgressNotifyingInputStream(InputStream stream, int totalSize) {
        if(stream==null) {
            throw new NullPointerException();
        }
        if(totalSize == 0) {
            throw new IllegalArgumentException("totalSize argument cannot be zero");
        }
        this.wrappedStream = stream;
        this.totalSize = totalSize;
    }


    @Override
    public int read() throws IOException {
        count++;
        return wrappedStream.read();
    }

    /**
     * Get progress from 0 to 100
     * @return
     */
    public int getProgress() {
        return count * 100 / totalSize;
    }

}
@Override
protected void onPostExecute(String result) {

    String resultString = null;
    if (MainActivity.isDebugMode){
        Log.d(TAG, "Async result: "+result);
    }

    boolean successful = false;
    String[] errorMessages = null;
    try {
        JSONObject mainObject = new JSONObject(result);
        String resultJsonString = mainObject.getString("result");
        JSONArray messagesJsonArray = mainObject.getJSONArray("messages");
        if (resultJsonString != null){
            if (resultJsonString.equalsIgnoreCase("success")){
                successful = true;
            } else {
                Log.e(TAG, "result was: "+resultJsonString);
            }
        }
        errorMessages = new String[messagesJsonArray.length()];
        for (int i = 0; i < messagesJsonArray.length(); i++){
            errorMessages[i]= (String)messagesJsonArray.get(i);
        }
    } catch (JSONException e){
        Log.e(TAG, "JSON Exception -- The string that I tried to parse was:\n"+result);
        e.printStackTrace();
    }

    if (successful) {
        Toast.makeText(this.activity, "Upload completed successfully!", Toast.LENGTH_SHORT).show();
        resultString = "Upload complete.";
    } else {
        String eMessages;
        if (errorMessages != null && errorMessages.length > 0){
            eMessages = TextUtils.join(", ", errorMessages);
            resultString = "Image upload failed:\n"+eMessages;
        } else {
            resultString = "Image upload failed!";
        }
    }
    ((ImageUploadActivity) activity).updateProgress(null);
    ((ImageUploadActivity) activity).setPostResult(resultString);
}
ImageUploadActivity#updateProgress 此方法将进度刷新到通知以及活动中包含的UI

public void updateProgress(Integer progress){
    this.currentProgress = progress;
    if (uploadStatusTV != null && this.currentProgress != null){
        currentStatus = "uploading image: "+this.currentProgress+"%";
        uploadStatusTV.setText("uploading image: "+this.currentProgress+"%");

        if (mBuilder == null){
            buildNotify();
        }
        // Sets the progress indicator to a max value, the
        // current completion percentage, and "determinate" state
        mBuilder.setProgress(100, currentProgress, false);
        // Displays the progress bar for the first time.
        mNotifyManager.notify(notify_id, mBuilder.build());

    } else if (uploadStatusTV != null){
        return;
    } else {
        Log.e(TAG, "You should never see this message.");
        finish();
    }
}

这将显示一组图像的进度…而不是单个图像。我刚刚发现另一个博客对此进行了解释:上面指向HttpMultipartClient的链接已无效。它也位于此处:这似乎与HttpUrlConnection文档相关:为了获得最佳性能,您应该调用setFixedLengthStreamingMode(int)当正文长度事先已知时,或当正文长度未知时,设置ChunkedStreamingMode(int)。否则,HttpURLConnection将被迫在传输前将完整的请求正文缓冲在内存中,从而造成浪费(可能会耗尽)堆和增加延迟。不幸的是,Gingerbread之前的Android上存在一个错误,这意味着setFixedLengthStreamingMode无法按文档所述工作,导致所有连接都被缓冲。请检查以下答案,它可能会有所帮助:[[1]:
private void buildNotify(){
    Intent resultIntent = new Intent(this, ImageUploadActivity.class);
    // Because clicking the notification opens a new ("special") activity, there's
    // no need to create an artificial back stack.
    PendingIntent resultPendingIntent =
            PendingIntent.getActivity(
                    this,
                    0,
                    resultIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT
            );

    mNotifyManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    mBuilder = new NotificationCompat.Builder(this);
    mBuilder.setContentIntent(resultPendingIntent);
    mBuilder.setContentTitle("Image Upload")
            .setContentText("Image upload in progress")
            .setSmallIcon(android.R.drawable.ic_menu_upload);

}
public void updateProgress(Integer progress){
    this.currentProgress = progress;
    if (uploadStatusTV != null && this.currentProgress != null){
        currentStatus = "uploading image: "+this.currentProgress+"%";
        uploadStatusTV.setText("uploading image: "+this.currentProgress+"%");

        if (mBuilder == null){
            buildNotify();
        }
        // Sets the progress indicator to a max value, the
        // current completion percentage, and "determinate" state
        mBuilder.setProgress(100, currentProgress, false);
        // Displays the progress bar for the first time.
        mNotifyManager.notify(notify_id, mBuilder.build());

    } else if (uploadStatusTV != null){
        return;
    } else {
        Log.e(TAG, "You should never see this message.");
        finish();
    }
}