Android使用HttpClient實現文件上傳到PHP服務器,並監控進度條


服務器端PHP
代碼如下 :

<?php $target_path = "./tmp/";//接收文件目錄  $target_path = $target_path.($_FILES['file']['name']); $target_path = iconv("UTF-8","gb2312", $target_path); if(move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) { echo "The file ".( $_FILES['file']['name'])." has been uploaded."; }else{ echo "There was an error uploading the file, please try again! Error Code: ".$_FILES['file']['error']; } ?>

監控進度實現
首先定義監聽器接口,如下所示:

//進度監聽器接口
public interface ProgressListener {
    public void transferred(long transferedBytes);
}

實現監控進度的關鍵部分就在於記錄已傳輸字節數,所以我們需重載FilterOutputStream,重寫其中的關鍵方法,實現進度監聽的功能,如下所示,本例中首先重載的是HttpEntityWrapper,顧名思義,就是將需發送的HttpEntity打包,以便計算總字節數,
代碼:

 // ProgressOutHttpEntity:輸出流(OutputStream)時記錄已發送
    public class ProgressOutHttpEntity extends HttpEntityWrapper {
    private final ProgressListener listener;
    public ProgressOutHttpEntity(final HttpEntity entity,
            final ProgressListener listener) {
        super(entity);
        this.listener = listener;
    }

    public static class CountingOutputStream extends FilterOutputStream {

        private final ProgressListener listener;
        private long transferred;

        CountingOutputStream(final OutputStream out,
                final ProgressListener listener) {
            super(out);
            this.listener = listener;
            this.transferred = 0;
        }

        @Override
        public void write(final byte[] b, final int off, final int len)
                throws IOException {
            // NO, double-counting, as super.write(byte[], int, int)
            // delegates to write(int).
            // super.write(b, off, len);
            out.write(b, off, len);
            this.transferred += len;
            this.listener.transferred(this.transferred);
        }

        @Override
        public void write(final int b) throws IOException {
            out.write(b);
            this.transferred++;
            this.listener.transferred(this.transferred);
        }

    }

    @Override
    public void writeTo(final OutputStream out) throws IOException {
        this.wrappedEntity.writeTo(out instanceof CountingOutputStream ? out
                : new CountingOutputStream(out, this.listener));
    }
    }

實現的類和Httpclient進行上傳並顯示進度的功能,非常簡單,代碼如下,使用AsyncTask異步上傳。

public class FileUploadAsyncTask extends AsyncTask<File, Integer, String> {

    private String url = "http://192.168.83.213/receive_file.php";
    private Context context;
    private ProgressDialog pd;
    private long totalSize;

    public FileUploadAsyncTask(Context context) {
        this.context = context;
    }

    @Override
    protected void onPreExecute() {
        pd = new ProgressDialog(context);
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pd.setMessage("上傳中....");
        pd.setCancelable(false);
        pd.show();
    }

    @Override
    protected String doInBackground(File... params) {
        // 保存需上傳文件信息
        MultipartEntityBuilder entitys = MultipartEntityBuilder.create();
        entitys.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entitys.setCharset(Charset.forName(HTTP.UTF_8));

        File file = params[0];
        entitys.addPart("file", new FileBody(file));
        HttpEntity httpEntity = entitys.build();
        totalSize = httpEntity.getContentLength();
        ProgressOutHttpEntity progressHttpEntity = new ProgressOutHttpEntity(
                httpEntity, new ProgressListener() {
                    @Override
                    public void transferred(long transferedBytes) {
                        publishProgress((int) (100 * transferedBytes / totalSize));
                    }
                });
        return uploadFile(url, progressHttpEntity);
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        pd.setProgress((int) (progress[0]));
    }

    @Override
    protected void onPostExecute(String result) {
        pd.dismiss();
        Toast.makeText(context, result, Toast.LENGTH_SHORT).show();
    }

//上傳文件到服務器
//服務器地址
//文件

 public static String uploadFile(String url, ProgressOutHttpEntity entity) {
        HttpClient httpClient = new DefaultHttpClient();
        httpClient.getParams().setParameter(
                CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        // 設置連接超時時間
        httpClient.getParams().setParameter(
                CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(entity);
        try {
            HttpResponse httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                return "文件上傳成功";
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ConnectTimeoutException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (httpClient != null && httpClient.getConnectionManager() != null) {
                httpClient.getConnectionManager().shutdown();
            }
        }
        return "文件上傳失敗";
    }

}

轉載請注明:安度博客 » Android使用HttpClient實現文件上傳到PHP服務器,並監控進度條

備份下載地址:http://download.csdn.net/detail/jdsjlzx/8486479


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com