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

Android Studio实现WhatsApp音频发送失败问题排查求助

Android 11下WhatsApp分享音频失败问题解决指南

问题概述

开发应用时实现WhatsApp音频分享功能,出现以下异常:

  • 音频文件可正常生成并保存到外部存储
  • WhatsApp可正常唤起并选择聊天对象
  • 点击发送后弹出Failed to share. Please try again提示

错误截图

WhatsApp分享失败提示

现有代码

按钮点击事件

btn1.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View view) {
        try {
            String mediaPath = copyFiletoExternalStorage(R.raw.audio1, "audio1.mp3");
            File myFile = new File(mediaPath);
            Uri newUri = getUriForFile(wspActivity.this, "com.restart.shareaudiofiles.fileprovider", myFile);
            Intent compartirAudio = new Intent(android.content.Intent.ACTION_SEND);
            compartirAudio.setType("com.whatsapp");
            compartirAudio.setType("audio/mp3");
            compartirAudio.putExtra(Intent.EXTRA_STREAM,newUri);
            startActivity(Intent.createChooser(compartirAudio, "Compartir vía"));
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), "Whatsapp no se encuentra instalado", Toast.LENGTH_LONG).show();
        }
    }
});

文件复制辅助函数

private String copyFiletoExternalStorage(int resourceId, String resourceName){
    String pathi= Environment.getExternalStorageDirectory() + "/Android/data/myProject/";
    boolean exists = (new File(pathi)).exists();
    if (!exists) {
        new File(pathi).mkdirs();
    }
    String pathSDCard = Environment.getExternalStorageDirectory() + "/Android/data/TeLoResumoBotonera/" + resourceName;
    try{
        InputStream in = getResources().openRawResource(resourceId);
        FileOutputStream out = null;
        out = new FileOutputStream(pathSDCard);
        byte[] buff = new byte[1024];
        int read = 0;
        try {
            while ((read = in.read(buff)) > 0) {
                out.write(buff, 0, read);
            }
        } finally {
            in.close();
            out.close();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return  pathSDCard;
}

Manifest配置

<queries>
    <package android:name="com.whatsapp" />
    <package android:name="com.whatsapp.w4b" />
</queries>

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.restart.shareaudiofiles.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths" />
</provider>

排查与修复方案

1. 修正Intent配置逻辑

连续两次调用setType()会覆盖MIME类型,且通过createChooser可能导致权限传递问题。正确做法是指定MIME类型后直接绑定WhatsApp包名,并添加权限标记:

Intent compartirAudio = new Intent(Intent.ACTION_SEND);
compartirAudio.setType("audio/mp3");
// 指定仅WhatsApp处理,避免Chooser干扰
compartirAudio.setPackage("com.whatsapp");
compartirAudio.putExtra(Intent.EXTRA_STREAM, newUri);
// 授予临时读写权限
compartirAudio.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(compartirAudio);

2. 修复存储路径拼写错误

辅助函数中目录路径存在拼写不一致:pathi变量使用myProject,但实际保存路径用TeLoResumoBotonera,导致目录创建无效,音频可能未正确写入。修正后:

private String copyFiletoExternalStorage(int resourceId, String resourceName){
    String appDir = Environment.getExternalStorageDirectory() + "/Android/data/TeLoResumoBotonera/";
    File dir = new File(appDir);
    if (!dir.exists()) {
        dir.mkdirs();
    }
    String pathSDCard = appDir + resourceName;
    // 剩余流读写逻辑不变
    ...
    return pathSDCard;
}

3. 检查FileProvider路径配置

确保res/xml/provider_paths.xml正确指向音频存储目录:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path 
        name="external_files" 
        path="Android/data/TeLoResumoBotonera/" />
</paths>

同时确认Manifest中FileProvider的authorities与代码中getUriForFile的第二个参数完全一致(当前为com.restart.shareaudiofiles.fileprovider)。

4. 验证音频文件完整性

手动检查生成的音频文件:

  • 通过文件管理器找到/Android/data/TeLoResumoBotonera/audio1.mp3
  • 尝试手动用WhatsApp分享该文件,如果仍失败,说明文件复制过程存在损坏,需检查流读写逻辑(比如是否完整关闭流,是否复制了全部字节)。

5. 适配Android 11+存储规则

Android 11及以上的Scoped Storage机制下,/Android/data/[包名]/属于应用私有外部目录,无需申请READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限,但需确保目录创建逻辑正确。

额外建议

  • 如需支持WhatsApp Business,可先判断包是否存在,再动态设置setPackage("com.whatsapp.w4b")
  • 在辅助函数末尾添加日志,打印文件路径和文件大小,确认文件已正确生成:
    Log.d("AudioShare", "文件路径:" + pathSDCard + ",大小:" + new File(pathSDCard).length() + "字节");
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 20:15:29