You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Java应用向ESP32 Web服务器上传.bin文件失败问题求助

解决Android上传.bin文件到ESP32 Web服务器的问题

我来帮你排查这个上传难题——既然浏览器能成功上传,说明ESP32服务器端逻辑没问题,问题肯定出在Android端的请求构造上,咱们一步步拆解修复:

一、先揪出核心错误点

你目前遇到的Connection reset和服务器500错误,主要是这几个问题导致的:

  1. ContentType用错了:你给二进制文件用了text/plain,这会让OkHttp把二进制内容当成纯文本编码,ESP32解析时直接出错,返回500甚至断开连接。二进制文件必须用application/octet-stream类型。
  2. 表单字段名错误:你的OkHttp代码里把文件名test-1.fw当成了表单字段名,而ESP32服务器应该是期望接收名为file的字段(和你最初HttpClient代码里的一致),服务器找不到对应字段自然报错。
  3. 主线程网络请求(隐性问题):如果你的代码是在主线程执行的,Android 9+会直接抛出异常,导致崩溃或无响应。
  4. 请求路径可能有误:你写的/upload/file.bin和浏览器测试的/upload/不一致,要和浏览器上传的路径保持完全一致。

二、修正后的OkHttp代码示例

我把所有问题都修复了,你可以直接用这个版本测试:

// 全局初始化OkHttpClient,建议放在Application类里
private OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS) // 给ESP32足够的处理时间
        .writeTimeout(60, TimeUnit.SECONDS)   // 大文件上传需要更长写入超时
        .readTimeout(30, TimeUnit.SECONDS)
        .build();

public void uploadBinFile() {
    File file = new File("/storage/emulated/0/Download/test-1.fw");
    if (!file.exists()) {
        Log.d("UploadDebug", "目标文件不存在");
        return;
    }

    // 二进制文件正确的MediaType
    final MediaType binaryType = MediaType.parse("application/octet-stream");
    
    // 注意第一个参数是服务器期望的表单字段名(必须和ESP32接收逻辑一致,这里用你最初的"file")
    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("file", file.getName(), RequestBody.create(file, binaryType))
            .build();

    Request request = new Request.Builder()
            .url("http://10.10.2.0/upload/") // 和浏览器测试的路径保持一致
            .post(requestBody)
            .build();

    // 用异步请求,避免阻塞主线程触发异常
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            Log.e("UploadError", "上传失败", e);
        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            if (response.isSuccessful()) {
                Log.d("UploadSuccess", "上传成功:" + response.body().string());
            } else {
                Log.e("UploadError", "服务器返回错误:" + response.code() + ",详情:" + response.body().string());
            }
        }
    });
}

三、额外排查步骤

如果还是有问题,试试这几个方向:

  • 确认ESP32的表单字段名:打开浏览器开发者工具(F12),上传时看Network面板的Form Data,里面文件对应的字段名是什么,必须和代码里的addFormDataPart第一个参数完全一致。
  • 测试小文件:先传一个几KB的.bin文件,排除ESP32内存不足导致的连接重置。
  • 检查存储权限:Android 10+的MANAGE_EXTERNAL_STORAGE需要用户手动到设置里授权,你可以加一段权限检查代码:
if (!Environment.isExternalStorageManager()) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
    Uri uri = Uri.fromParts("package", getPackageName(), null);
    intent.setData(uri);
    startActivity(intent);
}
  • 查看ESP32串口日志:服务器返回500时,ESP32的串口肯定会输出错误详情(比如表单解析失败、文件大小超限),这是定位问题最快的方式。

内容的提问来源于stack exchange,提问作者Brendon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 02:07:48