最近在弄一个项目,需要用到android拍照图片上传到LAMP服务器中去,网上找了很多代码,都不能实现上传文件,原因是当时使用的租用虚拟主机空间,文章是这么说的:

写道 通过前一篇转载的博文,已经可以实现上传图片、文件等。不过当时是在本地服务器,当我将PHP代码放到租用的虚拟主机的时候,就出现问题了。我POST请求在服务器那边获取不到任何数据。也就是说 $_POST 和 &_FILES 都是空的。而测试POST到本地的服务器,又很正常。这就很奇怪了。
为了确实是什么问题,我是这么做的:
我写了一个HTML的form表单,提交到远程服务器上,没问题。
然后用Fiddler抓包软件,抓取HTML的表单请求包和Android发送的请求包,对比。看看有什么不一样。
最后发现,在请求包里有Transfer-Encoding: chunked的时候,服务器就获取不到参数。
当没有Transfer-Encoding: chunked而有Content-Length: xxx的时候就没问题然后回头看看Android的代码,将
//这句注释掉。并记录整个请求包的大小,设置一下
//httpURLConnection.setChunkedStreamingMode(128 * 1024);
httpURLConnection.setRequestProperty("Content-Length", ""+Data.length);就好了。
不知道为什么租用的虚拟主机不支持,害得我调试了好久。还有之前的RSA生成、长链接的实现,都受虚拟主机限制的影响。
Transfer-Encoding: chunked 表示使用分块传输编码这一机制,只在 HTTP1.1里才有。
可以不事先确定整个Request包的大小,而是将数据分块发送。
在Body中就是 一个十六进制的数字表示接下来的包的长度,然后包的内容
Request的结束就是当分块包的长度为0。比如:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
3
con
8
sequence
0
(转发请注明转自:学PHP)

贴上代码:

package com.uploaddemo.control;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import org.apache.http.HttpStatus;import org.apache.http.ProtocolException;import android.content.Context;import android.util.Log;public class UploadHelper  {private static final String TAG = "salesman";private Context context = null;private String serverUrl = null;private String param1 = null;private String param2 = null;private String filePath = null;private String fileName = null;private static final int DEFAULT_BUFF_SIZE = 8192;private static final int READ_TIMEOUT = 15000;private static final int CONNECTION_TIMEOUT = 15000;private UploadListener uploadListener = null;public UploadHelper(Context context, String url, String param1, String param2, String filePath, String fileName) {this.context = context;this.serverUrl = url;this.param1 = param1;this.param2 = param2;this.filePath = filePath;this.fileName = fileName;}public void setUploadListener(UploadListener listener) {this.uploadListener = listener;}public void uploadFile() throws MalformedURLException, ProtocolException, FileNotFoundException, IOException {String lineEnd = "\r\n";String twoHyphens = "--";String boundary = "--------------et567z";// 各个参数的间隔符,可自定义,但不能与发送内容有重复部分if (context == null || serverUrl == null || param1 == null || param2 == null || filePath == null || fileName == null) {return;}URL url = new URL(serverUrl);HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();// 设置每次传输的流大小,可以有效防止手机因为内存不足崩溃// 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。// 租用的服务器空间这里必须去掉否则服务器接收不了任何参数//httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K//httpURLConnection.setRequestProperty("Content-Length", ""+ 1024 * 1024);// 允许输入输出流httpURLConnection.setDoInput(true);httpURLConnection.setDoOutput(true);httpURLConnection.setUseCaches(false);// 超时时间设置httpURLConnection.setReadTimeout(READ_TIMEOUT);httpURLConnection.setConnectTimeout(CONNECTION_TIMEOUT);// 使用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());// 发送jsonStrdos.writeBytes(twoHyphens + boundary + lineEnd);dos.writeBytes("Content-Disposition: form-data; name=\"param1\"" + lineEnd);dos.writeBytes(lineEnd);dos.writeBytes(param1);dos.writeBytes(lineEnd);// 发送acriondos.writeBytes(twoHyphens + boundary + lineEnd);dos.writeBytes("Content-Disposition: form-data; name=\"param2\"" + lineEnd);dos.writeBytes(lineEnd);dos.writeBytes(param2);dos.writeBytes(lineEnd);// 发送文件dos.writeBytes(twoHyphens + boundary + lineEnd);dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"" + fileName + "\"" + lineEnd);dos.writeBytes(lineEnd);//dos.writeBytes("Content-Type: image/*\r\n\r\n");String srcPath = filePath + fileName;FileInputStream fis = new FileInputStream(srcPath);byte[] buffer = new byte[DEFAULT_BUFF_SIZE]; // 8kint counter = 0;int count = 0;// 读取文件while ((count = fis.read(buffer)) != -1) {dos.write(buffer, 0, count);counter += count;if (uploadListener != null) {uploadListener.onUploadProcess(counter);}}fis.close();dos.writeBytes(lineEnd);dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);// 最后多出"--"作为结束dos.flush();if (httpURLConnection.getResponseCode() == HttpStatus.SC_OK) {BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()), 8192);// 8kStringBuilder sb = new StringBuilder();String line = null;try {while ((line = reader.readLine()) != null) {sb.append(line + "\n");}} catch (IOException e) {e.printStackTrace();}if (uploadListener != null) {uploadListener.onUploadFinished(sb.toString());}Log.e("salesman", "show.........");} else {Log.e(TAG, "Http request failed!");if (uploadListener != null) {uploadListener.onUploadFinished("Http request failed!");}}if (httpURLConnection != null) {httpURLConnection.disconnect();}}}

package com.uploaddemo.control;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.net.MalformedURLException;import java.net.ProtocolException;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;import android.widget.Toast;public class UploadDemoActivity extends Activity {    private TextView txtVServerUrl = null;private TextView txtVFilePath = null;private Button btnUpload = null;private ProgressBar progressBar = null;private String filePath = Environment.getExternalStorageDirectory() + "/salesman/";private String fileName = "test.jpg";private String serverUrl = "http://www.bocn.com/upload.php";private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {if (msg.what == 0) {progressBar.setProgress(msg.arg1);} else if (msg.what == 1) {Bundle b = msg.getData();if (b == null) {return;}String str = b.getString("msg");Toast.makeText(UploadDemoActivity.this, str, Toast.LENGTH_LONG).show();}}};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);txtVServerUrl = (TextView) findViewById(R.id.ID_TxtV_ServerUrl);txtVServerUrl.setText("serverUrl:" + serverUrl);txtVFilePath = (TextView) findViewById(R.id.ID_TxtV_FilePath);txtVFilePath.setText("filePath:" + filePath + fileName);progressBar = (ProgressBar) findViewById(R.id.ID_PBar);File file = new File(filePath, fileName);progressBar.setMax((int) file.length());btnUpload = (Button) findViewById(R.id.ID_Btn_Upload);btnUpload.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {final UploadHelper UploadHelper = new UploadHelper(UploadDemoActivity.this, serverUrl, "heihei", "haha", filePath, fileName);UploadHelper.setUploadListener(new UploadListener() {@Overridepublic void onUploadProcess(int size) {Message msg = new Message();msg.what = 0;msg.arg1 = size;handler.sendMessage(msg);}@Overridepublic void onUploadFinished(String msg) {Message msg1 = new Message();msg1.what = 1;Bundle b = new Bundle();b.putString("msg", msg);msg1.setData(b);handler.sendMessage(msg1);}});new Thread() {@Overridepublic void run() {try {UploadHelper.uploadFile();} catch (MalformedURLException e) {e.printStackTrace();} catch (ProtocolException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (org.apache.http.ProtocolException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}.start();}});}}

package com.uploaddemo.control;public interface UploadListener {public void onUploadProcess(int size);public void onUploadFinished(String msg);}

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    ><TextView  android:id="@+id/ID_TxtV_FilePath"    android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:text="@string/hello"    /><TextView android:text="TextView" android:id="@+id/ID_TxtV_ServerUrl" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView><ProgressBar android:id="@+id/ID_PBar" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal" android:layout_width="259dp"></ProgressBar><Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ID_Btn_Upload" android:text="上传"></Button></LinearLayout>

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.uploaddemo.control"      android:versionCode="1"      android:versionName="1.0">    <uses-sdk android:minSdkVersion="9" />    <application android:icon="@drawable/icon" android:label="@string/app_name">        <activity android:name=".UploadDemoActivity"                  android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>        <uses-permission android:name="android.permission.VIBRATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.RESTART_PACKAGES" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.READ_LOGS" /><uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /></manifest>

<?php  echo "param1=".$_POST['param1'].chr(13).chr(10);echo "param2=".$_POST['param2'].chr(13).chr(10);$target_path  = "./upload/";//接收文件目录  $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";  }  else{     echo "There was an error uploading the file, please try again!" . $_FILES['uploadedfile']['error'];  }  ?> 

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. 万字长文带你了解最常用的开源 Squid 代理服务器
  3. Nginx系列教程(一)| 手把手教你在Linux环境下搭建Nginx服务
  4. Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
  5. Android——控件跟随手指移动
  6. kotlin 实现一个简单 Android(安卓)路由(2)---》rxbus 代替intent
  7. 大约Android远程监控APP源代码
  8. android如何利用基于Http 协议的WebService服务来获取远程数据库
  9. Android(安卓)OpenGL ES 应用(一)

随机推荐

  1. Android通知栏消息(基本文字通知)
  2. Android中通过浏览器打开一个网页
  3. MTK Android(安卓)Driver :camera
  4. API指南----application
  5. Android字体闪烁动画(线程)
  6. Android获取本机信息(随时更新)
  7. Android客户端GPS定位
  8. 写信息的界面
  9. Android(安卓)入门笔记 之 网址
  10. 初步了解Android