Android点击分享按钮报错Invalid path 分享res/raw目录MP3文件失败
问题根因
你遇到的Invalid path错误由两个核心问题导致:
- 自行拼接raw资源Uri的规则不符合Android系统规范,路径格式错误导致系统无法识别对应资源
- 第三方分享目标应用没有权限读取你应用内部的私有
res/raw资源,直接传入内部资源Uri会被对方判定为无效路径
修复方案
1. 优先使用FileProvider实现分享(适配全版本Android)
Android 7.0及以上版本禁止直接向外部应用传递内部私有路径,需要通过FileProvider给第三方应用临时授权访问权限。
步骤1:配置FileProvider
在AndroidManifest.xml的<application>标签中添加如下配置:
<provider android:name="androidx.core.content.FileProvider" <!-- 若使用support库,替换为android:name="android.support.v4.content.FileProvider" --> android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
在res/xml目录下新建file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="shared_audio" path="audio/" /> </paths>
步骤2:添加raw资源转缓存文件的工具方法
private File copyRawToCache(int rawResId, String fileName) throws IOException { File audioCacheDir = new File(getCacheDir(), "audio"); if (!audioCacheDir.exists()) { audioCacheDir.mkdirs(); } File targetFile = new File(audioCacheDir, fileName); InputStream ins = getResources().openRawResource(rawResId); FileOutputStream fos = new FileOutputStream(targetFile); byte[] buffer = new byte[1024]; int len; while ((len = ins.read(buffer)) > 0) { fos.write(buffer, 0, len); } ins.close(); fos.close(); return targetFile; }
步骤3:修改分享逻辑
btn_shareaudio.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { // R.raw.sound1对应raw目录下sound1.mp3的资源ID,不需要带文件后缀 File audioFile = copyRawToCache(R.raw.sound1, "sound1.mp3"); Uri shareUri = FileProvider.getUriForFile( YourActivity.this, getPackageName() + ".fileprovider", audioFile ); Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("audio/*"); shareIntent.putExtra(Intent.EXTRA_STREAM, shareUri); // 给目标应用授予临时读取权限 shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(Intent.createChooser(shareIntent, "Condividi attraverso:")); } catch (IOException e) { e.printStackTrace(); } } });
2. 临时修复Uri构造(仅适用于Android 7.0以下版本)
如果你不需要兼容高版本系统,也可以直接修正原有的Uri构造逻辑,不要自行拼接路径,使用系统规范的构造方式:
public Uri getRawUri(int rawResId) { return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/" + rawResId); }
调用时直接传入资源ID即可:Uri rawUri = getRawUri(R.raw.sound1);
内容的提问来源于stack exchange,提问作者W4R1AT
相关产品推荐
相关产品推荐

