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

Android使用Retrofit2上传MP3音频文件无响应,求助排查

排查Retrofit2上传MP3无响应问题

嘿,我来帮你一步步排查这个Retrofit2上传MP3无响应的问题!从你贴的代码和截图来看,有几个常见的坑可能导致请求卡住或者没反馈,咱们逐个解决:

1. 接口参数格式错误

你的接口里直接用@Part("api_token") String api_token这种写法是有问题的——Retrofit的@Part注解对于非文件类型的参数,需要封装成RequestBody(或者用@PartMap批量处理),不然Retrofit无法正确生成Multipart请求的表单字段。

修改后的接口示例

@Multipart
@POST("comments")
Call<Wallet> setComment(
    @Part("voice") RequestBody song,
    @Part("api_token") RequestBody apiToken,
    @Part("product") RequestBody productId,
    @Part("body") RequestBody body
);

// 或者用@PartMap更简洁(推荐):
@Multipart
@POST("comments")
Call<Wallet> setComment(
    @Part("voice") RequestBody song,
    @PartMap Map<String, RequestBody> params
);

2. 文件MediaType不够精确

你用"audio/*"作为文件的MediaType,部分服务器可能无法识别具体的音频格式,导致拒绝处理请求。MP3文件应该明确指定为"audio/mpeg"。

3. 文件路径与权限问题

  • Android版本适配:Environment.getExternalStorageDirectory()在Android Q(API 29)及以上已经废弃,直接用这个路径可能无法访问文件,导致请求体为空。建议改用应用私有外部存储路径。
  • 动态权限:Android 6.0+需要动态申请READ_EXTERNAL_STORAGE权限,没有权限的话根本读不到文件,请求自然发不出去。

4. 回调未添加日志排查

你的onResponse和onFailure只调用了关闭弹窗的方法,完全没有打印任何日志,根本不知道请求是成功、失败还是卡在了某个环节。一定要添加日志输出,才能定位问题。

修改后的完整调用代码

// 第一步:检查并申请动态权限
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions((Activity) getContext(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
    return;
}

// 第二步:适配Android版本的文件路径
File audioFile;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    // 应用私有外部存储,无需额外权限
    audioFile = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_MUSIC), "NAMEAudioRecording.mp3");
} else {
    audioFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "NAME" + "AudioRecording.mp3");
}

// 第三步:检查文件是否存在且可读
if (!audioFile.exists() || !audioFile.canRead()) {
    Log.e("UploadError", "音频文件不存在或无法读取");
    appStore.CloseDilag();
    return;
}

// 第四步:创建正确的RequestBody
// 音频文件用精确的MediaType
RequestBody requestFile = RequestBody.create(MediaType.parse("audio/mpeg"), audioFile);
// 非文件参数封装为RequestBody
RequestBody apiToken = RequestBody.create(MediaType.parse("text/plain"), new AppStore(getContext()).LoadMyShereKES(AppStore.Keys_TOKEN));
RequestBody product = RequestBody.create(MediaType.parse("text/plain"), AppStore.ID_BACHGROUD);
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), Ediet.getText().toString());

// 第五步:发起请求并添加日志
MyInterFace myInterFace = MyServices.createService(MyInterFace.class);
Call<Wallet> calling = myInterFace.setComment(requestFile, apiToken, product, body);

calling.enqueue(new Callback<Wallet>() {
    @Override
    public void onResponse(Call<Wallet> call, Response<Wallet> response) {
        appStore.CloseDilag();
        // 打印状态码和响应内容
        Log.d("RetrofitInfo", "请求状态码:" + response.code());
        if (response.isSuccessful()) {
            Log.d("UploadSuccess", "服务器返回数据:" + response.body().toString());
        } else {
            // 打印错误响应的具体内容(非常重要)
            try {
                Log.e("UploadError", "错误响应:" + response.errorBody().string());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onFailure(Call<Wallet> call, Throwable t) {
        appStore.CloseDilag();
        // 打印失败原因
        Log.e("UploadFailure", "请求失败:" + t.getMessage());
        t.printStackTrace();
    }
});

额外排查建议

  1. 添加Retrofit日志拦截器:在Retrofit初始化时添加HttpLoggingInterceptor,可以看到完整的请求和响应详情,方便定位问题:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(logging)
    .build();

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(你的服务器地址)
    .client(client)
    .addConverterFactory(GsonConverterFactory.create())
    .build();
  1. 抓包验证请求:用Charles或Fiddler抓包,确认请求是否真的发送到了服务器,以及请求体的参数是否正确。
  2. 检查服务器配置:确认服务器端的接口支持Multipart/form-data请求,且参数名(比如voice、api_token)和客户端完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:22:49