Загрузка параметров и изображений через HttpURLConnection на сервер PHP (Android)

Сценарий: я пытаюсь отправить некоторые данные POST через HttpURLConnection в службу (с обновлением прогресса). Я хватаю изображение из галереи, а затем отправляю его на php-сервер с двумя параметрами; Invnum и пароль.

Примечание. Если я делаю это методом HttpClient, параметры и изображение отправляются и принимаются на сервере, но я не могу отслеживать ход загрузки. Я видел несколько кодов, связанных с настраиваемой многочастной сущностью, насколько это возможно, я бы хотел избежать ссылки на библиотеку

Я рассмотрел много связанных вопросов в SO, но не могу найти решение. Ниже приведены текущие коды, которые у меня есть в моем сервисе.

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(); } } 

При запуске приложения прогресс отображается хорошо, но при проверке на моем сервере файлы вообще не загружаются. Фактически никакие данные не отправляются или не принимаются сервером. Кто-нибудь знает, что может вызвать эту проблему? Ниже приведен код сервера.

 $pass = $_POST['pass']; $invnum = $_POST['invnum']; $image = $_POST['image']; if ($pass == 'password') { //do something } 

Обновления: для начала я получаю ошибку 404 от HTTPURLConnection. Мой url выглядит примерно так: « http://www.xyz.com/upload.php ». Обновите предыдущее предложение, удалив «setChunkedStreamingMode», я могу успешно загрузить параметры на сервер, но не изображение! Я рядом!

Наконец, он получил работу …

Строка «connection.setChunkedStreamingMode (1024);» Вызывает проблему. После этого удалите параметры и файл. Остается одна второстепенная проблема, ход загрузки неточен. Достигнутый прогресс – это фактически заполненный буфер, который почти мгновен даже для 3 МБ изображения. Файл все еще загружается в фоновом режиме после того, как прогресс достигнет 100. Угадайте, что это будет другой вопрос в другое время.

В методе android HttpClient лучше, чем HttpUrlConnection. Я показываю только способ exceute post с HttpClient. Я использовал этот сборщик;

 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);