MediaPlayer 在播放路径中带有# 的文件时是否有问题?

Does MediaPlayer have problems with playing files with # in their paths?

最近发现自己开发的音频播放器突然停止播放了

原来MediaPlayer.prepare()抛出了一个异常:

"Prepare failed.: status=0x1"

文件名包含#符号。我去掉#后,就可以播放了。我刚刚删除了# 符号。文件路径本身很长并且包含空格 [ 等

final Uri uri = Uri.parse("/storage/sdcard1/audio/Die Toten Hosen/03 - Boxed Set/2007 - Die DTH Jubiläumsedition [17 CD Boxed Set Remasted]/CD 1 - Opel-Gang/18. Radio Argentina #1.mp3");
mediaPlayer.reset();
mediaPlayer.setDataSource(context, uri);

问题是为什么当我使用

将文件传输到我的 phone 时
adb push /tmp/ /storage/sdcard1/audio/

其中一些包含 ?符号,然后它们被跳过(或 errors/warning 发生。记不清了),但名称中包含 # 的文件已成功复制。如果有一些转义规则,那么问题应该与包含 ?和包含 #.

的文件

因为我看不出发生的事情有任何逻辑。似乎没有一个中心位置来定义应该转义什么以及如何转义。

因为您将 Uri 传递给 audioplayer,所以 #? 是特殊字符。在 Uri 中,散列 # 被称为 Fragment Identifier,例如自动将网页跳到某个锚标记,或将 plaback 跳到给定的开始时间。 Uri 中的问号 ? 允许查询参数,即任何使用 Uri 的对象都可以使用的额外参数。

由于这些是 Uri 上下文中的特殊字符,这就是播放最初失败的原因,并且在文件重命名后可以正常播放。您可以使用 URLEncoder.encode()

转义这些特殊字符

public static String encode(String s, String enc) throws UnsupportedEncodingException

Translates a string into application/x-www-form-urlencoded format using a specific encoding scheme. This method uses the supplied encoding scheme to obtain the bytes for unsafe characters. Note: The World Wide Web Consortium Recommendation states that UTF-8 should be used. Not doing so may introduce incompatibilites.

Parameters:

  • s - String to be translated.

  • enc - The name of a supported character encoding.

Returns: the translated String.

所以在你的情况下:

final String encoded = URLEncoder.encode("/storage/sdcard1/audio/Die Toten Hosen/03 - Boxed Set/2007 - Die DTH Jubiläumsedition [17 CD Boxed Set Remasted]/CD 1 Opel-Gang/18. Radio Argentina #1.mp3", "UTF-8");
final Uri uri = Uri.parse(encoded);
mediaPlayer.reset();
mediaPlayer.setDataSource(context, uri);

解决方案是使用:

MediaPlayer.setDataSource(String);

显然它可以处理路径名中的 # 符号。

mediaPlayer.setDataSource("/storage/sdcard1/audio/Die Toten Hosen/03 - Boxed Set/2007 - Die DTH Jubiläumsedition [17 CD Boxed Set Remasted]/CD 1 - Opel-Gang/18. Radio Argentina #1.mp3");