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");
最近发现自己开发的音频播放器突然停止播放了
原来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");