通过HttpURLConnection将参数和图像上传到PHP服务器(Android)
场景: 我正在尝试通过服务中的HttpURLConnection发送一些POST数据(带有进度更新)。 我从图库中抓取一个图像,然后用2个参数将其发送到php服务器;invnum和密码 注意: 如果我使用HttpClient方法,那么参数和图像将在服务器中发送和接收,但我无法跟踪上传进度。我看到了一些与自定义多部分实体相关的代码,我希望尽可能避免引用库 我在SO中研究了很多相关问题,但似乎找不到解决方案。以下是我服务中的当前代码通过HttpURLConnection将参数和图像上传到PHP服务器(Android),php,android,service,httpclient,httpurlconnection,Php,Android,Service,Httpclient,Httpurlconnection,场景: 我正在尝试通过服务中的HttpURLConnection发送一些POST数据(带有进度更新)。 我从图库中抓取一个图像,然后用2个参数将其发送到php服务器;invnum和密码 注意: 如果我使用HttpClient方法,那么参数和图像将在服务器中发送和接收,但我无法跟踪上传进度。我看到了一些与自定义多部分实体相关的代码,我希望尽可能避免引用库 我在SO中研究了很多相关问题,但似乎找不到解决方案。以下是我服务中的当前代码 protected void onHandleIntent(Int
protected void onHandleIntent(Intent intent) {
String invnum = intent.getStringExtra("invnum");
String uploadURL = intent.getStringExtra("uploadURL");
String imageURI = intent.getStringExtra("imageURI");
uri = Uri.parse(imageURI);
String pass = "password";
//get the actual path of the image residing in the phone
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri,filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
cursor.close();
ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
//check url
try {
File file = new File(picturePath);
FileInputStream fileInputStream = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
fileInputStream.read(bytes);
fileInputStream.close();
String fileName = file.getName();
URL url = new URL(uploadURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setChunkedStreamingMode(1024);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)");
connection.setRequestProperty("image", fileName);
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
//send multipart form data (required) for file
outputStream.writeBytes("Content-Disposition: form-data; name=\"image\";filename=\"" + fileName + "\"" + lineEnd);
outputStream.writeBytes("Content-Type: image/jpeg" + lineEnd);
//outputStream.writeBytes("Content-Type: " + URLConnection.guessContentTypeFromName(fileName) + lineEnd);
//outputStream.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
//outputStream.writeBytes("Content-Type: application/octet-stream" + lineEnd);
outputStream.writeBytes("Content-Length: " + file.length() + lineEnd);
outputStream.writeBytes(lineEnd);
int bufferLength = 1024;
for (int i = 0; i < bytes.length; i += bufferLength) {
// publishing the progress....
Bundle resultData = new Bundle();
resultData.putInt("progress" ,(int)((i / (float) bytes.length) * 100));
receiver.send(UPDATE_PROGRESS, resultData);
if (bytes.length - i >= bufferLength) {
outputStream.write(bytes, i, bufferLength);
} else {
outputStream.write(bytes, i, bytes.length - i);
}
}
//end output
outputStream.writeBytes(lineEnd);
//write more parameters other than the file
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
//outputStream.writeBytes(twoHyphens + boundary + lineEnd); //less twohyphens
outputStream.writeBytes("Content-Disposition: form-data; name=\"invnum\"" + lineEnd);
//outputStream.writeBytes("Content-Type: text/plain; charset=UTF-8" + lineEnd);
//outputStream.writeBytes("Content-Length: " + invnum.length() + lineEnd);
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(invnum + lineEnd);
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"pass\"" + lineEnd);
//outputStream.writeBytes("Content-Type: text/plain; charset=UTF-8" + lineEnd);
//outputStream.writeBytes("Content-Length: " + pass.length() + lineEnd);
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(pass + lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// publishing the progress....
Bundle resultData = new Bundle();
resultData.putInt("progress", 100);
receiver.send(UPDATE_PROGRESS, resultData);
outputStream.flush();
outputStream.close();
//input ignored for now
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
更新:
首先,我从HTTPURLConnection得到一个404错误。我的url看起来像“”。
更新前一句,通过删除“setChunkedStreamingMode”,我能够成功地将参数上传到服务器,但不能上传到图像!我快到了 在android HttpClient方法中优于HttpUrlConnection。我只展示了如何使用HttpClient实现post方法。我用了这个同样的结构
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(<n>);// you have pass, invnum and image
nameValuePairs.add(new BasicNameValuePair("image", "<filName>"));
post.setEntity( new UrlEncodedFormEntity(nameValuePairs));
client.execute(post);
HttpClient=newdefaulthttpclient();
HttpPost=新的HttpPost();
List nameValuePairs=新的ArrayList();//您有pass、invnum和image
添加(新的BasicNameValuePair(“图像”和“”);
setEntity(新的UrlEncodedFormEntity(nameValuePairs));
客户。执行(post);
终于让它开始工作了
行“connection.setChunkedStreamingMode(1024);”导致了该问题。删除后,参数和文件的上载成功。还有一个小问题,上传的进度不准确。返回的进度实际上是正在填充的缓冲区,这几乎是即时的,即使对于3MB图像也是如此。进度达到100后,文件仍在后台上传。我想这将是另一个问题。这种方法有效,但不是我想要的,我无法使用HttpClient跟踪上传进度。也许你会检查一下你对android HttpClient方法的看法是否错误。一般来说,对于较新版本的android,httpurlconnection得到了更多的改进。在这里阅读更多:你有没有想过如何解决这个问题?我也在尝试做同样的事情,但每个人似乎都认为他们在跟踪上传进度,而实际上他们只是在跟踪对黄油的写入(如你所说)。非常感谢,伙计..一周来我一直对这个问题感到恼火。终于完成了你的回答…真的非常感谢。。。
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(<n>);// you have pass, invnum and image
nameValuePairs.add(new BasicNameValuePair("image", "<filName>"));
post.setEntity( new UrlEncodedFormEntity(nameValuePairs));
client.execute(post);