Android HTTP上传文件到服务器

在Android开发中,有时我们需要将文件上传到服务器,以备后续处理或存储。本文将介绍如何使用HTTP协议,通过POST请求将文件上传到服务器,并提供相应的代码示例。

准备工作

在开始之前,我们需要确保以下几点:

  1. 确定服务器端已经准备好接收文件的API接口,并了解该接口所需的请求参数和格式。
  2. 确保App具有Internet权限,以便发送网络请求。

开始上传文件

我们使用Android原生的HttpClient库来进行文件上传。首先,我们需要创建一个HttpClient实例,并设置文件上传的URL地址。

// 创建HttpClient实例
HttpClient httpClient = new DefaultHttpClient();
// 设置上传文件的URL
String url = "
HttpPost httpPost = new HttpPost(url);

接下来,我们需要创建一个MultipartEntity实例,用于包装需要上传的文件和其他相关参数。MultipartEntity允许我们同时上传多个文件和多个参数。

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
// 添加文件参数
File file = new File("path/to/file");
builder.addBinaryBody("file", file, ContentType.DEFAULT_BINARY, "filename.ext");
// 添加其他参数
builder.addTextBody("key1", "value1");
builder.addTextBody("key2", "value2");
// 设置请求实体
httpPost.setEntity(builder.build());

在上面的代码示例中,我们通过addBinaryBody方法添加了一个文件参数。第一个参数是参数名,第二个参数是文件对象,第三个参数是文件的MIME类型,第四个参数是文件的名称。我们还可以使用addTextBody方法添加其他普通的文本参数。

最后,我们发送请求并获取服务器的响应。

HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
    // 文件上传成功
    String result = EntityUtils.toString(response.getEntity());
    Log.d("Upload", "Result: " + result);
} else {
    // 文件上传失败
    Log.e("Upload", "Error: " + statusCode);
}

这里我们通过httpClient.execute方法发送POST请求,并获取响应对象。通过判断响应的状态码,我们可以判断文件上传是否成功。

完整代码示例

import android.util.Log;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;

public class FileUploader {

    public static void uploadFile(String url, File file) throws IOException {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addBinaryBody("file", file, ContentType.DEFAULT_BINARY, "filename.ext");
        httpPost.setEntity(builder.build());

        HttpResponse response = httpClient.execute(httpPost);
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_OK) {
            String result = EntityUtils.toString(response.getEntity());
            Log.d("Upload", "Result: " + result);
        } else {
            Log.e("Upload", "Error: " + statusCode);
        }
    }
}

示例应用

下面是一个使用上述代码的示例应用。该应用提供了一个文件选择按钮和一个上传按钮。用户可以选择本地文件并将其上传到服务器。

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.File;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_PICK_FILE = 1;
    private static final int REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE = 2;

    private Button pickFileButton;
    private Button uploadButton;
    private File selectedFile;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        pickFileButton = findViewById(R.id.pickFileButton);
        uploadButton = findViewById(R.id.uploadButton);

        pickFileButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 请求读取外部存储器的权限
                requestPermission();
            }
        });

        uploadButton.setOnClickListener(new View.OnClickListener