iOS:在某些设备上多次调用MPMusicPlayerControllerPlaybackStateDidChangeNotification

我有一个播放音乐的应用程序。

我正在使用以下代码来监听MPMusicPlayerController的播放状态更改以更新UI。 更确切地说,我在播放和暂停之间切换播放button的外观。

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver: self selector: @selector (handle_NowPlayingItemChanged:) name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification object: self.musicPlayer]; [notificationCenter addObserver: self selector: @selector (handle_PlaybackStateChanged:) name: MPMusicPlayerControllerPlaybackStateDidChangeNotification object: self.musicPlayer]; [self.musicPlayer beginGeneratingPlaybackNotifications]; 

这在iPod Touch(iOS 5)iPhone 3GS(iOS 5)上效果很好。 每当播放状态改变,我得到以下callback:

 [JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 1 

其中1表示MPMusicPlaybackStatePlaying

但是,如果我在iPad 1(iOS 5)iPad 2(iOS 5)iPad 3(iOS 6)上运行相同的程序,我将得到以下顺序,而不是一个单一的callback:

 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 1 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 2 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 1 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 2 

其中2表示MPMusicPlaybackStatePaused并导致我的应用程序在UI中显示错误状态,因为歌曲实际上正在播放。

有趣的是,有一段时间,序列是

 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 1 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 2 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 1 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 2 -[JBMediaPlayer handle_PlaybackStateChanged:] :: playbackState: 1 

其中1 MPMusicPlaybackStatePlaying正确结束,但仍然没有任何意义,callback被调用5次,交替的值。

任何想法如何解决这个或build议还有什么我可以testing缩小问题?


由于到目前为止我还没有收到答案,所以我也把这个问题交给了苹果开发者论坛 : https : //devforums.apple.com/thread/158426

我认为这是在这里报告的同样的错误:

在ios 5 MP音乐播放器控制器中出现错误的播放状态

我在这个问题上发布了一个解决方法。

您可以使用currentPlaybackRate属性来检查实际播放状态。 MPMusicPlaybackStatePaused必须匹配率0.0。 下面显示了一个如何实现的例子。

 - (void)musicPlayerControllerPlaybackStateDidChangeNotification:(NSNotification *)notification { float playbackRate = [((MPMusicPlayerController *)notification.object) currentPlaybackRate]; MPMusicPlaybackState playbackState = (MPMusicPlaybackState)[notification.userInfo[@"MPMusicPlayerControllerPlaybackStateKey"] integerValue]; switch (playbackState) { case MPMusicPlaybackStatePaused: if (playbackRate <= .0f) { self.playbackState = playbackState; } break; default: self.playbackState = playbackState; break; } } 

因此可以切断假暂停通知。