一、错误描述
刚用MediaPlayer播放Music的时候,看到Log打印台总是会打印一条错误日志,MediaPlayer: Should have subtitle controller already set
,虽然程序运行不会出问题,但是看起来红色的日志很显眼,因此决定修改这个bug。具体的错误日志如下所示:
01-04 17:46:21.752 9395-9395/com.netease.xtc.cloudmusic I/CloudMusicPlayService: >>>>>>>>>>>>>>> mediaPlayer onBufferingUpdate
01-04 17:46:21.752 9395-9395/com.netease.xtc.cloudmusic D/MediaPlayer: handleMessage msg:(1, 0, 0)
01-04 17:46:21.753 9395-9395/com.netease.xtc.cloudmusic E/MediaPlayer: Should have subtitle controller already set
01-04 17:46:21.753 9395-9395/com.netease.xtc.cloudmusic I/CloudMusicPlayService: >>>>>>>>>>>>>>> mediaPlayer onPrepared
01-04 17:46:21.756 9395-9395/com.netease.xtc.cloudmusic I/CloudMusicPlayService: >>>>>>>>>>>>>>> startPlay
二、错误解决
通过google,在*网站上搜索到了答案,相关链接如下所示:
http://*.com/questions/20087804/should-have-subtitle-controller-already-set-mediaplayer-error-android
解决方法一
忽略此警告Log,因为并不影响程序正常运行。
正如*网站上的答案说说的
A developer recently added subtitle support to VideoView.
When the MediaPlayer starts playing a music (or other source), it checks if there is a SubtitleController and shows this message if it’s not set. It doesn’t seem to care about if the source you want to play is a music or video. Not sure why he did that.
Short answer: Don’t care about this “Exception”.
解决方法二
如果MediaPlayer仅仅是用于播放音频文件,并且你真的想消除这些错误log的打印,则参考下面的代码来获取MediaPlayer。
/**
* 博客地址: http://blog.csdn.net/ouyang_peng/
* 获取MediaPlayer 修复bug ( MediaPlayer: Should have subtitle controller already set )
* </br><a href = "http://*.com/questions/20087804/should-have-subtitle-controller-already-set-mediaplayer-error-android/20149754#20149754">
* 参考链接</a>
*
* </br> This code is trying to do the following from the hidden API
* <p>
* </br> SubtitleController sc = new SubtitleController(context, null, null);
* </br> sc.mHandler = new Handler();
* </br> mediaplayer.setSubtitleAnchor(sc, null)</p>
*/
private MediaPlayer getMediaPlayer(Context context) {
MediaPlayer mediaplayer = new MediaPlayer();
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
return mediaplayer;
}
try {
Class<?> cMediaTimeProvider = Class.forName("android.media.MediaTimeProvider");
Class<?> cSubtitleController = Class.forName("android.media.SubtitleController");
Class<?> iSubtitleControllerAnchor = Class.forName("android.media.SubtitleController$Anchor");
Class<?> iSubtitleControllerListener = Class.forName("android.media.SubtitleController$Listener");
Constructor constructor = cSubtitleController.getConstructor(
new Class[]{Context.class, cMediaTimeProvider, iSubtitleControllerListener});
Object subtitleInstance = constructor.newInstance(context, null, null);
Field f = cSubtitleController.getDeclaredField("mHandler");
f.setAccessible(true);
try {
f.set(subtitleInstance, new Handler());
} catch (IllegalAccessException e) {
return mediaplayer;
} finally {
f.setAccessible(false);
}
Method setsubtitleanchor = mediaplayer.getClass().getMethod("setSubtitleAnchor",
cSubtitleController, iSubtitleControllerAnchor);
setsubtitleanchor.invoke(mediaplayer, subtitleInstance, null);
} catch (Exception e) {
LogUtil.d(TAG,"getMediaPlayer crash ,exception = "+e);
}
return mediaplayer;
}
上面代码的作用是做类似于下面隐藏API的工作:
SubtitleController sc = new SubtitleController(context, null, null);
sc.mHandler = new Handler();
mediaplayer.setSubtitleAnchor(sc, null)
然后将初始化MediaPlayer的代码由:
MediaPlayer mediaPlayer = new MediaPlayer();
改为:
MediaPlayer mediaPlayer = getMediaPlayer(this);
然后重新运行APP之后就不会再出现之前的红色警告log MediaPlayer: Should have subtitle controller already set
了。
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:
http://blog.csdn.net/ouyang_peng/article/details/54023240