dongzi3434 2013-10-09 03:57
浏览 81

通过HttpURLConnection将参数和图像上传到PHP服务器(Android)

Scenario: I'm trying to send some POST data via HttpURLConnection in a service (with progress updates). I am grabbing an image from the gallery and then sending it to a php server with 2 parameters; invnum and password.

Note: If I'm doing it by the HttpClient method, the parameters and the image are sent and received in the server but I can't track the upload progress. I saw some codes related to custom multipart entity, as much as possible I would like to avoid referencing a library

I've looked into a lot of related questions in SO but can't seem to find a solution. Below are the current codes I have in my service.

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

When running the app, the progress is reflected nicely but when checking on my server, no files are uploaded at all. In fact no data is sent or received by the server. Does anyone have any idea what may be causing this problem? Below is my server code.

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

Updates: For a start, I'm getting a 404 error from the HTTPURLConnection. My url looks something like "http://www.xyz.com/upload.php". Update to the former sentence, by removing "setChunkedStreamingMode", I'm able to successfully upload the parameters to the server but not the image! I'm close!

  • 写回答

2条回答 默认 最新

  • dongyi2006 2013-10-09 04:51
    关注

    In android HttpClient method better than HttpUrlConnection. I only show how exceute post method with HttpClient. I used this samly structer;

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

报告相同问题?

悬赏问题

  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 MATLAB中streamslice问题
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 51单片机中C语言怎么做到下面类似的功能的函数(相关搜索:c语言)
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端