您的位置:首页 > 移动开发 > Android开发

Android文件上传,PHP端接收

2015-08-17 20:23 393 查看
最近项目中要用优化文件上传操作,因此对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的上传方式速度也很理想,主要是用起来简单。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: