当前位置:首页 > 行业动态 > 正文

安卓传文件给服务器

通过OkHttp或Retrofit库构建Multipart请求,添加文件至RequestBody并设置Content-Type,异步执行POST上传,需动态申请存储权限,捕获IO异常并处理服务器响应状态码

安卓文件上传至服务器实现方案

权限配置

在AndroidManifest.xml中声明必要权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

注:Android 10+需动态申请存储权限,建议使用Scoped Storage模式

文件传输方式选择

传输方式 适用场景 优点 缺点
HTTP POST/PUT 常规文件上传 简单易用,广泛支持 文件传输效率低
FTP协议 局域网传输 支持断点续传 需要服务器配置FTP服务
WebSocket 实时传输 双向通信 实现复杂度高

HTTP文件上传实现(以Retrofit为例)

  1. 依赖配置

    安卓传文件给服务器  第1张

    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.okhttp3:okhttp:4.9.0'
  2. 创建Retrofit实例

    OkHttpClient client = new OkHttpClient.Builder()
     .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
     .build();

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(“https://yourserver.com/api/”)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();

安卓传文件给服务器  第2张


3. 定义API接口:
```java
public interface FileUploadService {
    @Multipart
    @POST("upload")
    Call<UploadResponse> uploadFile(@Part MultipartBody.Part filePart);
}
  1. 构建请求体
    // 获取文件路径
    File file = new File(Environment.getExternalStorageDirectory(), "test.txt");

// 创建请求体
RequestBody requestBody = RequestBody.create(MediaType.parse(“multipart/form-data”), file);
MultipartBody.Part filePart = MultipartBody.Part.createFormData(“file”, file.getName(), requestBody);


5. 执行上传:
```java
FileUploadService service = retrofit.create(FileUploadService.class);
Call<UploadResponse> call = service.uploadFile(filePart);
// 异步请求
call.enqueue(new Callback<UploadResponse>() {
    @Override
    public void onResponse(Call<UploadResponse> call, Response<UploadResponse> response) {
        if(response.isSuccessful()){
            // 处理成功逻辑
        } else {
            // 处理错误响应
        }
    }
    @Override
    public void onFailure(Call<UploadResponse> call, Throwable t) {
        // 网络错误处理
    }
});

进度监听实现

// 创建带进度的RequestBody
ProgressRequestBody body = new ProgressRequestBody(requestBody, new ProgressListener() {
    @Override
    public void onProgress(long currentBytes, long totalBytes) {
        double progress = (double)currentBytes/totalBytes100;
        // 更新UI进度条
    }
});
// 替换原始请求体
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), body);

常见问题解决方案

问题现象 解决方案
文件过大导致OOM 使用RequestBody流式传输,避免一次性加载
权限被拒绝 Android 6.0+动态申请运行时权限
跨域问题 服务器端配置CORS头
SSL证书验证失败 配置证书信任管理器或禁用验证(测试环境)

服务器端接收示例(Node.js)

const express = require('express');
const multer = require('multer');
const app = express();
const upload = multer({ dest: 'uploads/' });
app.post('/upload', upload.single('file'), (req, res) => {
  // 文件已保存到uploads目录
  res.json({ success: true, filename: req.file.filename });
});

相关问题与解答

Q1:如何实现文件分片上传?
A1:将文件分割为多个小块(如每块1MB),按顺序上传并记录已上传块数,服务器端需提供校验接口,全部上传完成后进行文件合并,可使用RandomAccessFile进行文件分块读取。

安卓传文件给服务器  第3张

Q2:如何支持多文件同时上传?
A2:使用MultipartBody.Part数组构建请求:

MultipartBody.Part[] parts = {filePart1, filePart2, filePart3};
Call<UploadResponse> call = service.uploadMultipleFiles(parts); // 需在接口定义@PartMap或@Part注解数组

服务器端需处理数组类型的文件参数,如使用multerarray()方法

0