Android文件上传,PHP端接收 – fancychendong的专栏 – 博客频道 – CSDN.NET

最近项目中要用优化文件上传操作,因此对Android端文件上传做下总结。测试服务器端就用PHP写了,比较简单,代码如下:

 

 

 

[php] view

plaincopy

 

 

 

 

 

 

<?php  

 

$base_path = “./uploads/”//接收文件目录  

 

$target_path = $base_path . basename ( $_FILES [‘uploadfile’] [‘name’] );  

 

if (move_uploaded_file ( $_FILES [‘uploadfile’] [‘tmp_name’], $target_path )) {  

 

    $array = array (“code” => “1”“message” => $_FILES [‘uploadfile’] [‘name’] );  

 

    echo json_encode ( $array );  

 

else {  

 

    $array = array (“code” => “0”“message” => “There was an error uploading the file, please try again!” . $_FILES [‘uploadfile’] [‘error’] );  

 

    echo json_encode ( $array );  

 

}  

 

?>  

 

     我主要写了三种上传:人造POST请求、httpclient4(需要httpmime-4.1.3.jar)、AsyncHttpClient(对appache的HttpClient进行了进一步封装,了解更多…),当然为了并列起来看比较方便,前两种上传我直接写在主线程了,不知道对速度测试有没有影响,老鸟看请给予批评指正,嘿嘿,下面上代码:

 

 

 

[java] view

plaincopy

 

 

 

 

 

 

package com.example.fileupload;  

 

  

 

import java.io.BufferedReader;  

 

import java.io.DataOutputStream;  

 

import java.io.File;  

 

import java.io.FileInputStream;  

 

import java.io.FileNotFoundException;  

 

import java.io.IOException;  

 

import java.io.InputStream;  

 

import java.io.InputStreamReader;  

 

import java.net.HttpURLConnection;  

 

import java.net.URL;  

 

  

 

import org.apache.http.HttpEntity;  

 

import org.apache.http.HttpResponse;  

 

import org.apache.http.HttpVersion;  

 

import org.apache.http.client.ClientProtocolException;  

 

import org.apache.http.client.HttpClient;  

 

import org.apache.http.client.methods.HttpPost;  

 

import org.apache.http.entity.mime.MultipartEntity;  

 

import org.apache.http.entity.mime.content.FileBody;  

 

import org.apache.http.impl.client.DefaultHttpClient;  

 

import org.apache.http.params.CoreProtocolPNames;  

 

import org.apache.http.util.EntityUtils;  

 

  

 

import android.app.Activity;  

 

import android.os.Bundle;  

 

import android.util.Log;  

 

import android.view.View;  

 

import android.view.View.OnClickListener;  

 

import android.widget.Button;  

 

  

 

import com.loopj.android.http.AsyncHttpClient;  

 

import com.loopj.android.http.AsyncHttpResponseHandler;  

 

import com.loopj.android.http.RequestParams;  

 

  

 

/** 

 

 *  

 

 * ClassName:UploadActivity Function: TODO 测试上传文件,PHP服务器端接收 Reason: TODO ADD 

 

 * REASON 

 

 *  

 

 * @author Jerome Song 

 

 * @version 

 

 * @since Ver 1.1 

 

 * @Date 2013 2013-4-20 上午8:53:44 

 

 *  

 

 * @see 

 

 */  

 

public class UploadActivity extends Activity implements OnClickListener {  

 

    private final String TAG = “UploadActivity”;  

 

  

 

    private static final String path = “/mnt/sdcard/Desert.jpg”;  

 

    private String uploadUrl = “http://192.168.1.102:8080/Android/testupload.php;  

 

    private Button btnAsync, btnHttpClient, btnCommonPost;  

 

    private AsyncHttpClient client;  

 

  

 

    @Override  

 

    protected void onCreate(Bundle savedInstanceState) {  

 

        super.onCreate(savedInstanceState);  

 

        setContentView(R.layout.activity_upload);  

 

        initView();  

 

        client = new AsyncHttpClient();  

 

    }  

 

  

 

    private void initView() {  

 

        btnCommonPost = (Button) findViewById(R.id.button1);  

 

        btnHttpClient = (Button) findViewById(R.id.button2);  

 

        btnAsync = (Button) findViewById(R.id.button3);  

 

        btnCommonPost.setOnClickListener(this);  

 

        btnHttpClient.setOnClickListener(this);  

 

        btnAsync.setOnClickListener(this);  

 

    }  

 

  

 

    @Override  

 

    public void onClick(View v) {  

 

        long startTime = System.currentTimeMillis();  

 

        String tag = null;  

 

        try {  

 

            switch (v.getId()) {  

 

            case R.id.button1:  

 

                upLoadByCommonPost();  

 

                tag = “CommonPost====>”;  

 

                break;  

 

            case R.id.button2:  

 

                upLoadByHttpClient4();  

 

                tag = “HttpClient====>”;  

 

                break;  

 

            case R.id.button3:  

 

                upLoadByAsyncHttpClient();  

 

                tag = “AsyncHttpClient====>”;  

 

                break;  

 

            default:  

 

                break;  

 

            }  

 

        } catch (Exception e) {  

 

            e.printStackTrace();  

 

  

 

        }  

 

        Log.i(TAG, tag + “wasteTime = “  

 

                + (System.currentTimeMillis() – startTime));  

 

    }  

 

  

 

    /** 

 

     * upLoadByAsyncHttpClient:由人造post上传 

 

     *  

 

     * @return void 

 

     * @throws IOException 

 

     * @throws 

 

     * @since CodingExample Ver 1.1 

 

     */  

 

    private void upLoadByCommonPost() throws IOException {  

 

        String end = “\r\n”;  

 

        String twoHyphens = “–“;  

 

        String boundary = “******”;  

 

        URL url = new URL(uploadUrl);  

 

        HttpURLConnection httpURLConnection = (HttpURLConnection) url  

 

                .openConnection();  

 

        httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K  

 

        // 允许输入输出流  

 

        httpURLConnection.setDoInput(true);  

 

        httpURLConnection.setDoOutput(true);  

 

        httpURLConnection.setUseCaches(false);  

 

        // 使用POST方法  

 

        httpURLConnection.setRequestMethod(“POST”);  

 

        httpURLConnection.setRequestProperty(“Connection”“Keep-Alive”);  

 

        httpURLConnection.setRequestProperty(“Charset”“UTF-8”);  

 

        httpURLConnection.setRequestProperty(“Content-Type”,  

 

                “multipart/form-data;boundary=” + boundary);  

 

  

 

        DataOutputStream dos = new DataOutputStream(  

 

                httpURLConnection.getOutputStream());  

 

        dos.writeBytes(twoHyphens + boundary + end);  

 

        dos.writeBytes(“Content-Disposition: form-data; name=\”uploadfile\”; filename=\””  

 

                + path.substring(path.lastIndexOf(“/”) + 1) + “\”” + end);  

 

        dos.writeBytes(end);  

 

  

 

        FileInputStream fis = new FileInputStream(path);  

 

        byte[] buffer = new byte[8192]; // 8k  

 

        int count = 0;  

 

        // 读取文件  

 

        while ((count = fis.read(buffer)) != –1) {  

 

            dos.write(buffer, 0, count);  

 

        }  

 

        fis.close();  

 

        dos.writeBytes(end);  

 

        dos.writeBytes(twoHyphens + boundary + twoHyphens + end);  

 

        dos.flush();  

 

        InputStream is = httpURLConnection.getInputStream();  

 

        InputStreamReader isr = new InputStreamReader(is, “utf-8”);  

 

        BufferedReader br = new BufferedReader(isr);  

 

        String result = br.readLine();  

 

        Log.i(TAG, result);  

 

        dos.close();  

 

        is.close();  

 

    }  

 

  

 

    /** 

 

     * upLoadByAsyncHttpClient:由HttpClient4上传 

 

     *  

 

     * @return void 

 

     * @throws IOException 

 

     * @throws ClientProtocolException 

 

     * @throws 

 

     * @since CodingExample Ver 1.1 

 

     */  

 

    private void upLoadByHttpClient4() throws ClientProtocolException,  

 

            IOException {  

 

        HttpClient httpclient = new DefaultHttpClient();  

 

        httpclient.getParams().setParameter(  

 

                CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);  

 

        HttpPost httppost = new HttpPost(uploadUrl);  

 

        File file = new File(path);  

 

        MultipartEntity entity = new MultipartEntity();  

 

        FileBody fileBody = new FileBody(file);  

 

        entity.addPart(“uploadfile”, fileBody);  

 

        httppost.setEntity(entity);  

 

        HttpResponse response = httpclient.execute(httppost);  

 

        HttpEntity resEntity = response.getEntity();  

 

        if (resEntity != null) {  

 

            Log.i(TAG, EntityUtils.toString(resEntity));  

 

        }  

 

        if (resEntity != null) {  

 

            resEntity.consumeContent();  

 

        }  

 

        httpclient.getConnectionManager().shutdown();  

 

    }  

 

  

 

    /** 

 

     * upLoadByAsyncHttpClient:由AsyncHttpClient框架上传 

 

     *  

 

     * @return void 

 

     * @throws FileNotFoundException 

 

     * @throws 

 

     * @since CodingExample Ver 1.1 

 

     */  

 

    private void upLoadByAsyncHttpClient() throws FileNotFoundException {  

 

        RequestParams params = new RequestParams();  

 

        params.put(“uploadfile”new File(path));  

 

        client.post(uploadUrl, params, new AsyncHttpResponseHandler() {  

 

            @Override  

 

            public void onSuccess(int arg0, String arg1) {  

 

                super.onSuccess(arg0, arg1);  

 

                Log.i(TAG, arg1);  

 

            }  

 

        });  

 

    }  

 

  

 

}  

 

 

    Andriod被我们熟知的上传就是由appache提供给的httpclient4了,毕竟比较简单,腾讯微博什么的sdk也都是这么做的,大家可以参考:

 

 

 

[java] view

plaincopy

 

 

 

 

 

 

/** 

 

     * Post方法传送文件和消息 

 

     *  

 

     * @param url  连接的URL 

 

     * @param queryString 请求参数串 

 

     * @param files 上传的文件列表 

 

     * @return 服务器返回的信息 

 

     * @throws Exception 

 

     */  

 

    public String httpPostWithFile(String url, String queryString, List<NameValuePair> files) throws Exception {  

 

  

 

        String responseData = null;  

 

  

 

        URI tmpUri=new URI(url);  

 

        URI uri = URIUtils.createURI(tmpUri.getScheme(), tmpUri.getHost(), tmpUri.getPort(), tmpUri.getPath(),   

 

                queryString, null);  

 

        Log.i(TAG, “QHttpClient httpPostWithFile [1]  uri = “+uri.toURL());  

 

          

 

          

 

        MultipartEntity mpEntity = new MultipartEntity();  

 

        HttpPost httpPost = new HttpPost(uri);  

 

        StringBody stringBody;  

 

        FileBody fileBody;  

 

        File targetFile;  

 

        String filePath;  

 

        FormBodyPart fbp;  

 

          

 

        List<NameValuePair> queryParamList=QStrOperate.getQueryParamsList(queryString);  

 

        for(NameValuePair queryParam:queryParamList){  

 

            stringBody=new StringBody(queryParam.getValue(),Charset.forName(“UTF-8”));  

 

            fbp= new FormBodyPart(queryParam.getName(), stringBody);  

 

            mpEntity.addPart(fbp);  

 

//            Log.i(TAG, “——- “+queryParam.getName()+” = “+queryParam.getValue());  

 

        }  

 

          

 

        for (NameValuePair param : files) {  

 

            filePath = param.getValue();  

 

            targetFile= new File(filePath);  

 

            fileBody = new FileBody(targetFile,“application/octet-stream”);  

 

            fbp= new FormBodyPart(param.getName(), fileBody);  

 

            mpEntity.addPart(fbp);  

 

              

 

        }  

 

  

 

//        Log.i(TAG, “———- Entity Content Type = “+mpEntity.getContentType());  

 

  

 

        httpPost.setEntity(mpEntity);  

 

          

 

        try {  

 

            HttpResponse response=httpClient.execute(httpPost);  

 

            Log.i(TAG, “QHttpClient httpPostWithFile [2] StatusLine = “+response.getStatusLine());  

 

            responseData =EntityUtils.toString(response.getEntity());  

 

        } catch (Exception e) {  

 

            e.printStackTrace();  

 

        }finally{  

 

          httpPost.abort();  

 

        }  

 

        Log.i(TAG, “QHttpClient httpPostWithFile [3] responseData = “+responseData);  

 

        return responseData;  

 

    }  

 

 

很明显,开源框架的写法最简单有效,而且为异步的,提供出Handler进行结果返回,普通人造post代码量最大,上传速度大家也可以测一下,我附一张图,我上传的图片850kb左右

    总体看来,代码量最多的写法可能上传速度好点儿,asyncHttpClient的上传方式速度也很理想,主要是用起来简单。

   有时可能还会有上传进度返回的需求,第一种流的读写方式应该很简单解决,后两种可能还得下点儿功夫研究研究,有兴趣的朋友可以一块儿交流研究。

来源URL:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c4224615143ab2f0797f54538b9638341cfc091ab1a168252a5577f1c893d60bc0b8932f2d8c22327708c31c528516fc9710659c7bc64de9de0e96b1e743e7b9a2d5c82723dd53746df0f79c2a7603cb1fb24e73&p=8c66c54ad6c042f11cb2c7710f4f92&newp=b4769a479f941cf006bd9b7e0e15c1231610db2151d4da103683ce17cd&user=baidu&fm=sc&query=android+%C9%CF%B4%AB+%B5%BDphp&qid=f3856d1700009d6d&p1=1