如何在Android移动设备上使用http将文件发送到服务器?

72
在安卓中,我如何使用HTTP从移动设备向服务器发送文件(数据)?

13
这个请求的服务器端代码会是什么样子? - user677614
6个回答

85

很简单,您可以使用Post请求并将文件以二进制形式(字节数组)提交。

String url = "http://yourserver";
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),
        "yourfile");
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) {
    // show error
}

2
服务器接收文件的参数名称是什么? - sanrodari
1
@sanrodari:你可以在 $_FILES 数组中获取文件。 - toni
2
我的 $_FILES 为空,我看到很多其他帖子使用 MultipartEntity。我需要用那个代替吗? - RvdK
4
请问您能否提供与上述代码片段相关的ASP.NET服务器端代码的参考资料? - Sreekanth Karumanaghat
1
如果我想在请求体中发送一些数据,该怎么办?即发送文件并且请求体也要发送? - SamFast
显示剩余7条评论

16

可以通过向服务器发送HTTP Post请求来完成此操作:

HttpClient http = AndroidHttpClient.newInstance("MyApp");
HttpPost method = new HttpPost("http://url-to-server");

method.setEntity(new FileEntity(new File("path-to-file"), "application/octet-stream"));

HttpResponse response = http.execute(method);

2
在我的情况下,它抛出了一个错误,“IllegalStateException AndroidHttpClient was never closed”,我不知道如何规避它。 - Vaibhav Mishra
你的结果可能会有所不同,但对我来说,在服务器端返回了一个空的 $_FILES 集合。使用 MultiPart 解决了这个问题。https://dev59.com/J3NA5IYBdhLWcg3wKai3 - Chris Rae
1
如果您没有设置文件名,$_FILES['file'] 的默认名称是什么?它只是 basename($_FILES['file']['tmp_name']) 吗? - Brandon

10

最有效的方法是使用android-async-http

您可以使用此代码上传文件:

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

// send request
AsyncHttpClient client = new AsyncHttpClient();
client.post(url, params, new AsyncHttpResponseHandler() {
    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] bytes) {
        // handle success response
    }

    @Override
    public void onFailure(int statusCode, Header[] headers, byte[] bytes, Throwable throwable) {
        // handle failure response
    }
});

请注意,您可以直接将此代码放入主活动中,无需显式创建后台任务。 AsyncHttp 将替您处理此操作!


如何使用此功能上传多个文件?请注意,必须等待响应返回后才能上传下一个文件。我尝试在for循环中使用此功能,但是for循环没有等待响应返回... - mostafa hashim

9

将所有内容封装在异步任务中,以避免线程错误。

public class AsyncHttpPostTask extends AsyncTask<File, Void, String> {

    private static final String TAG = AsyncHttpPostTask.class.getSimpleName();
    private String server;

    public AsyncHttpPostTask(final String server) {
        this.server = server;
    }

    @Override
    protected String doInBackground(File... params) {
        Log.d(TAG, "doInBackground");
        HttpClient http = AndroidHttpClient.newInstance("MyApp");
        HttpPost method = new HttpPost(this.server);
        method.setEntity(new FileEntity(params[0], "text/plain"));
        try {
            HttpResponse response = http.execute(method);
            BufferedReader rd = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));
            final StringBuilder out = new StringBuilder();
            String line;
            try {
                while ((line = rd.readLine()) != null) {
                    out.append(line);
                }
            } catch (Exception e) {}
            // wr.close();
            try {
                rd.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // final String serverResponse = slurp(is);
            Log.d(TAG, "serverResponse: " + out.toString());
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

可以使用以下代码调用:new AsyncHttpPostTask("http://myserver").execute(new File("myfile")); - Chris Rae

4

最有效的方法是使用org.apache.http.entity.mime.MultipartEntity;

可以从链接中查看这段代码,使用org.apache.http.entity.mime.MultipartEntity;

public class SimplePostRequestTest3 {

  /**
   * @param args
   */
  public static void main(String[] args) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://localhost:8080/HTTP_TEST_APP/index.jsp");

    try {
      FileBody bin = new FileBody(new File("C:/ABC.txt"));
      StringBody comment = new StringBody("BETHECODER HttpClient Tutorials");

      MultipartEntity reqEntity = new MultipartEntity();
      reqEntity.addPart("fileup0", bin);
      reqEntity.addPart("fileup1", comment);

      reqEntity.addPart("ONE", new StringBody("11111111"));
      reqEntity.addPart("TWO", new StringBody("222222222"));
      httppost.setEntity(reqEntity);

      System.out.println("Requesting : " + httppost.getRequestLine());
      ResponseHandler<String> responseHandler = new BasicResponseHandler();
      String responseBody = httpclient.execute(httppost, responseHandler);

      System.out.println("responseBody : " + responseBody);

    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      httpclient.getConnectionManager().shutdown();
    }
  }

}

新增:

示例链接


(该链接为IT技术相关内容)

2

如果您仍在尝试,可以尝试使用retrofit2 此链接


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