我正在用Android(API 29)编写一个铃声应用程序,我想通过WhatsApp分享以MP3格式存储在/res/raw/
文件夹中的声音。我正在使用此代码:
Intent share = new Intent(Intent.ACTION_SEND);
Uri path = Uri.parse("android.resource://"+ getPackageName() + "/" + R.raw.yeah);
share.setPackage("com.whatsapp");
share.setType("audio/mp3");
share.putExtra(Intent.EXTRA_STREAM, path);
startActivity(Intent.createChooser(share, "Share"));
但是每次我选择聊天发送音频文件时,我都会收到WhatsApp错误,告诉我无法共享文件。我见过其他应用程序在不请求外部存储写入权限的情况下实现我想要的功能。有什么线索吗?
但是每次我选择聊天发送音频文件时,我都会收到WhatsApp错误消息,告诉我无法共享该文件
很少有应用程序支持晦涩难懂的android。资源方案非常好。此外,EXTRA_流被记录为获取内容,而不是android。资源Uri。
有什么线索吗?
将原始资源复制到内部存储上的文件中,例如在
getCacheDir()
中。您可以使用从调用getResources()
aContext
中获得的Resources
对象来访问原始资源(使用openRawResource()
)。然后,配置FileProvider
从那里提供服务,并使用FileProvider.getUriForFile()
获取Uri
以与ACTION_SEND
一起使用。请务必在Intent
上添加FLAG_GRANT_READ_URI_PERMISSION
。
这个示例Java应用程序(及其Kotlin等效程序)演示了基本技术。在我的例子中,我将PDF存储为一项资产,而不是将MP3存储为原始资源,因此这部分需要进行一些小的调整。
或者,您可以从头开始编写自己的内容提供者来提供原始资源,然后在您的意图中使用该提供者支持的Uri。
最后,我通过混合使用Commonware答案、这个答案和这个答案来解决这个问题。提前感谢大家!
逐步解决方案:
首先,让我们从一些XML开始。
中添加以下行
AndroidManifest.xml
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
当我使用API 29时,我使用的是AndroidX库。如果您也想使用它,请考虑通过单击重构来运行AndroidX迁移向导
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="my_sounds" path="/"/>
</paths>
请注意
my_sounds
名称是任意的。path
字段中的/
是您的文件将存储在缓存路径中的位置。为了方便起见,我只是这样做。如果您不想使用缓存路径,这里是您可以使用的可用标签的完整列表。
现在我们将返回Java并开始编写处理共享的方法。首先,我们需要将资源文件夹中的文件复制到
File
对象。但是,这个File
需要指向我们在XML部分配置的文件提供程序创建的路径。让我们划分任务:
用文件的数据创建一个输入流,并用辅助过程填充一个文件
公共空句柄MediaACK(int位置)
File sound;
try {
InputStream inputStream = getResources().openRawResource(sounds.get(position).getSound()); // equivalent to R.raw.yoursound
sound = File.createTempFile("sound", ".mp3");
copyFile(inputStream, new FileOutputStream(sound));
} catch (IOException e) {
throw new RuntimeException("Can't create temp file", e);
}
辅助程序:
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1)
out.write(buffer, 0, read);
}
现在您的资源已成功传输到内部存储中的缓存目录(使用调试器查看是哪个)。
final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";
Uri uri = getUriForFile(getApplicationContext(), AUTHORITY, sound);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("audio/mp3"); // or whatever.
share.putExtra(Intent.EXTRA_STREAM, uri);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(share, "Share"));
把所有这些放在一起,我们最终会得到这个方法:
完整方法
public void handleMediaSend(int position) { // Depends on your implementation.
File sound;
try {
InputStream inputStream = getResources().openRawResource(sounds.get(position).getSound()); // equivalent to R.raw.yoursound
sound = File.createTempFile("sound", ".mp3");
copyFile(inputStream, new FileOutputStream(sound));
} catch (IOException e) {
throw new RuntimeException("Can't create temp file", e);
}
final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";
Uri uri = getUriForFile(getApplicationContext(), AUTHORITY, sound);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("audio/mp3"); // or whatever.
share.putExtra(Intent.EXTRA_STREAM, uri);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(share, "Share"));
}
我是相当新的Android应用程序开发,我试图从 /res/raw文件夹中播放一个随机的. mp3。 到目前为止,我已经修复了这个问题,但我遇到了一个FileNotFoundException。 修正了只在第一次点击时播放一个随机声音,之后它是相同的声音,除非重新打开应用程序。 新问题现在播放随机声音,但当我多次单击按钮时,声音同时开始播放,并且仍然在日志中收到“start()mUri is nu
我的应用程序在MediaPlayer中使用MP3文件,我想制作一个按钮,然后将MP3文件共享到Whatsapp。 我的代码是这样的: 但是不working.why不行?我怎么解决这个问题?
我正在尝试共享RES/RAW文件夹中的音频文件。到目前为止我所做的是: 例如,当我选择在GMail上分享它时,它会说“无法附加空文件”之类的话。看来我没有得到正确的文件路径,所以我基本上没有共享任何东西。我做错了什么? 任何帮助都将不胜感激。
我是Android的新手。 我已经尝试了这个论坛的所有帖子。但未能取得成功。我正在尝试将mp3文件从asset文件夹共享到whatsapp。 下面是我的代码。 这是我在主活动中的代码: ContentProvider中的代码: 清单文件:
以下是从mp3文件中提取内容和元数据的程序 - import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.apache.tika.exception.TikaException; import org.apache.tika.metadata.Metadata; impor
我正在研究我的高中顶点。这是一个程序,用户可以从互联网下载歌曲并以有组织的方式存储它们并播放它们。我的程序必须包含一个功能,用户只需按一个按钮即可删除指定的.mp3文件。我已经在媒体播放器上尝试了.dispose()方法,然后尝试删除似乎不起作用的文件。它会产生一个错误,指出.mp3文件仍在使用中。如何阻止 Javafx 访问该文件?我在网上搜索了答案,但没有一个答案适合我的需求。如果有人能为我提