通过 Http POST 请求从 Android 上传文件和其他数据

16

这是一种从Android上传文件的简单方法。

String url = "http://yourserver.com/upload.php";
File file = new File("myfileuri");
try {
    HttpClient httpclient = new DefaultHttpClient();

    HttpPost httppost = new HttpPost(url);

    InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(file), -1);
    reqEntity.setContentType("binary/octet-stream");
    reqEntity.setChunked(true); // Send in multiple parts if needed
    httppost.setEntity(reqEntity);
    HttpResponse response = httpclient.execute(httppost);
    //Do something with response...

} catch (Exception e) {
    e.printStackTrace();
}  

我想做的是在我的请求中添加更多POST变量。我该怎么做?当我们在POST请求中上传普通字符串时,我们使用URLEncodedFormEntity

httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

在上传文件时,我们使用InputStreamEntity

此外,我该如何将文件特定地上传到$_FILES['myfilename']


尝试使用AsyncTask...如果您想上传不同类型的变量,可以使用HashMap。 - Akash Shah
显然我会使用AsyncTask。通常使用名称值对的哈希映射来发送多个变量。但是,String和File的实体类型是不同的。这让我感到困惑。 - shiladitya
1
使用多部分请求。 - njzk2
制作多部分并不是问题。我希望能够将普通字符串和文件同时发送到同一个PHP。 - shiladitya
4个回答

1

在花费了整整一天的时间后,我找到了loopj。你可以按照以下代码示例:

//context: Activity context, Property: Custom class, replace with your pojo
public void postProperty(Context context,Property property){
        // Creates a Async client. 
        AsyncHttpClient client = new AsyncHttpClient();
         //New File
        File files = new File(property.getImageUrl());
        RequestParams params = new RequestParams();
        try {
            //"photos" is Name of the field to identify file on server
            params.put("photos", files);
        } catch (FileNotFoundException e) {
            //TODO: Handle error
            e.printStackTrace();
        }
        //TODO: Reaming body with id "property". prepareJson converts property class to Json string. Replace this with with your own method 
        params.put("property",prepareJson(property));
        client.post(context, baseURL+"upload", params, new AsyncHttpResponseHandler() {
            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                System.out.print("Failed..");
            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                System.out.print("Success..");
            }
        });

    }

1
最有效的方法是使用android-async-http
您可以使用以下代码上传文件:
 

    File myFile = new File("/path/to/file.png");
    RequestParams params = new RequestParams();
    try {
        params.put("profile_picture", myFile);
    } catch(FileNotFoundException e) {}


我能使用这个库上传任何类型的文件而不必指定文件类型吗? - pratham kesarkar
1
是的,您可以上传任何类型的文件。 - Hoshouns
我的建议是:远离Loopj。 我用它已经很长时间了,但它在支持SSL方面并不好。这是一个已知的bug已经存在很久了,而且由于库使用的基础架构原因,显然无法修复。 相反,应该使用Volley或Retrofit/SimpleHttp。 - Iman Akbari

0
以下是几种方法:
  • 进行2个POST请求:第一个请求包含图像文件。服务器返回图像ID,然后您使用第二个请求将参数附加到此ID上。

  • 或者,您可以使用MultipartEntity请求代替“2个请求”解决方案。在这里查看更多详细信息


我不建议第一个建议。如果您发出两个请求,其中任何一个失败,都可能对您的数据造成灾难。 - chrisbjr
是的,我不建议这样做,但确实有这样的解决方案。我使用了第二个,它更好。 - validcat

0

嘿,Akash!感谢你的回答,但它仍然没有回答我的问题。如果你没有理解我的疑问,这个问题与之前完全相同。 http://stackoverflow.com/questions/11598457/android-how-to-send-song-file-to-server-throught-httppost-along-with-other-vari?rq=1 不幸的是,这个问题也没有解决 :( - shiladitya
好的,我明白了。以下是一些针对你遇到的问题的带有答案的问题:https://dev59.com/31_Va4cB1Zd3GeqPUIVihttp://stackoverflow.com/questions/8965022/android-upload-file-with-filling-out-post-body-together/9003674#9003674 - Akash Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接