一、在文件APPDelegate.m裏,實現方法「- (void)remoteControlReceivedWithEvent:(UIEvent *)event」的重寫,用來接收控制中心的事件。session
1 // 在APPDelegate.m中聲明一個通知事件的key 2 NSString *const AppDelegateReceiveRemoteEventsNotification = @"AppDelegateReceiveRemoteEventsNotification"; 3 4 /// 鎖屏頁面的控制事件(必須在這裏重寫該方法,在播放頁面重寫不起做用) 5 - (void)remoteControlReceivedWithEvent:(UIEvent *)event { 6 if (event.type == UIEventTypeRemoteControl) { 7 // 發送通知給音頻播放界面 進行某些處理 8 [[NSNotificationCenter defaultCenter] postNotificationName:AppDelegateReceiveRemoteEventsNotification object:event]; 9 } 10 }
Appdelegate裏就設置這些。post
二、在音頻播放界面spa
1 // 設置控制中心交互須要導入 2 #import <MediaPlayer/MediaPlayer.h> 3 4 /// 註冊通知 5 - (void) registerAllNotifications { 6 // 後臺通知 7 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(apllicationWillResignActiveNotification:) name:UIApplicationWillResignActiveNotification object:nil]; 8 9 // 進入前臺通知 10 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(apllicationWillEnterForegroundNotification:) name:UIApplicationWillEnterForegroundNotification object:nil]; 11 12 // 鎖屏界面事件 13 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(AppDelegateReceiveRemoteEventsNotification:) name:AppDelegateReceiveRemoteEventsNotification object:nil]; 14 } 15 16 17 #pragma mark - 通知方法實現 18 /// 進入後臺 19 - (void) apllicationWillResignActiveNotification:(NSNotification *)n { 20 NSError *error = nil; 21 // 後臺播放代碼 22 AVAudioSession *session = [AVAudioSession sharedInstance]; 23 [session setActive:YES error:&error]; 24 if(error) { 25 // NSLog(@"ListenPlayView background error0: %@", error.description); 26 } 27 [session setCategory:AVAudioSessionCategoryPlayback error:&error]; 28 if(error) { 29 // NSLog(@"ListenPlayView background error1: %@", error.description); 30 } 31 32 /// 進後臺 設置接收遠程控制 33 [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 34 35 // 上面代碼實現後臺播放 幾分鐘後會中止播放 36 // 添加任務id 實現後臺連續播放 37 backTaskID = [self backgroundPlayerID:backTaskID]; 38 } 39 40 // 實現一下backgroundPlayerID:這個方法: 41 - (UIBackgroundTaskIdentifier)backgroundPlayerID:(UIBackgroundTaskIdentifier)backTaskId { 42 NSError *error = nil; 43 // 設置並激活音頻會話類別 44 AVAudioSession *session = [AVAudioSession sharedInstance]; 45 [session setCategory:AVAudioSessionCategoryPlayback error:nil]; 46 if(error) { 47 NSLog(@"ListenPlayView background error2: %@", error.description); 48 } 49 [session setActive:YES error:nil]; 50 if(error) { 51 NSLog(@"ListenPlayView background error3: %@", error.description); 52 } 53 54 // 設置後臺任務ID 55 UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid; 56 newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]; 57 if(newTaskId != UIBackgroundTaskInvalid && backTaskId != UIBackgroundTaskInvalid) { 58 [[UIApplication sharedApplication] endBackgroundTask:backTaskId]; 59 } 60 61 return newTaskId; 62 } 63 64 65 /// 進入前臺通知 66 - (void) apllicationWillEnterForegroundNotification:(NSNotification *)n { 67 // 進前臺 設置不接受遠程控制 68 [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; 69 } 70 71 /// 遠程控制事件通知 72 - (void)AppDelegateReceiveRemoteEventsNotification:(NSNotification*)noti { 73 if (!noti) return; 74 if (!noti.object) return; 75 if (![noti.object isKindOfClass:[UIEvent class]]) return; 76 77 UIEvent *event = (UIEvent *)noti.object; 78 if (event.type == UIEventTypeRemoteControl) { 79 // 根據遠程控制事件類型,在播放界面設置播放、暫停、下一個、上一個 80 switch (event.subtype) { 81 case UIEventSubtypeRemoteControlPlay: 82 // play 83 break; 84 case UIEventSubtypeRemoteControlPause: 85 // pause 86 break; 87 case UIEventSubtypeRemoteControlNextTrack: 88 // next 89 break; 90 case UIEventSubtypeRemoteControlPreviousTrack: 91 // last 92 break; 93 default: break; 94 } 95 } 96 } 97 98 /// 移除全部通知 99 - (void)removeAllNotifications { 100 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil]; 101 102 [[NSNotificationCenter defaultCenter] removeObserver:self name:AppDelegateReceiveRemoteEventsNotification object:nil]; 103 104 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]; 105 }
上面這些實現了控制中心和播放界面的交互。此時,控制中心尚未顯示當前播放的音頻信息(嗯,我尚未設置)。以下:code
1 /// 設置鎖屏界面的播放音頻的相關信息 2 /// 可在適當時機調用該方法(開始播放時、將要進入後臺、音頻切換) 3 - (void) setupNowPlayingAudioInfo { 4 /** 設置信息的類型 5 * MPMediaItemPropertyAlbumTitle : 專輯名 6 * MPMediaItemPropertyAlbumTrackCount : 專輯個數 7 * MPMediaItemPropertyAlbumTrackNumber : 當前播放的專輯位置 8 * MPMediaItemPropertyArtist : 藝術家 9 * MPMediaItemPropertyArtwork : 封面 10 * MPMediaItemPropertyComposer : 做曲家 11 * MPMediaItemPropertyDiscCount : 迪斯科 數量 12 * MPMediaItemPropertyDiscNumber : 當前位置 13 * MPMediaItemPropertyGenre : 流派 14 * MPMediaItemPropertyPersistentID : ID 15 * MPMediaItemPropertyPlaybackDuration : 後臺播放時長 16 * MPMediaItemPropertyTitle : 標題 17 */ 18 19 NSMutableDictionary *songDict = [NSMutableDictionary dictionary]; 20 21 // 音頻名字 22 [songDict setObject:@"她來聽個人演唱會" forKey:MPMediaItemPropertyTitle]; 23 24 // 歌手 25 [songDict setObject:@"張學友" forKey:MPMediaItemPropertyArtist]; 26 27 // 歌曲的總時間 28 [songDict setObject:@(200) forKeyedSubscript:MPMediaItemPropertyPlaybackDuration]; 29 30 // 當前時間 31 [songDict setObject:@(30) forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; 32 33 // 播放速率 34 [songDict setObject:@(1.0) forKey:MPNowPlayingInfoPropertyPlaybackRate]; 35 36 // 鎖屏音頻封面 37 MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"封面.png"]]; 38 [songDict setObject:artwork forKey:MPMediaItemPropertyArtwork]; 39 40 // 設置控制中心歌曲信息 41 [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songDict]; 42 }
這時,鎖屏界面已經能夠顯示音頻對應的信息了。server
還有最後一步設置(動態設置控制中心的按鈕狀態),如:當前播放的音頻是播放列表最後一條,設置控制中心的下一個按鈕不可點擊。。。blog
1 /// 設置控制中心的按鈕狀態(保持與播放界面對應按鈕狀態一致) 2 /// 調用時機(如切換音頻時,設置鎖屏界面音頻信息時) 3 - (void) setupRemoteControlButtonStatus { 4 // 只有設置了target 才能設置控制中心(鎖屏界面)的按鈕狀態 5 6 // 設置控制中心下一個按鈕 和播放頁面的下一個按鈕狀態同步 7 MPRemoteCommand *next = [MPRemoteCommandCenter sharedCommandCenter].nextTrackCommand; 8 next.enabled = self.nextButton.enabled; 9 [next addTarget:self action:@selector(remoteCommandAction:)]; 10 11 // 設置控制中心上一個按鈕 和播放頁面的上一個按鈕狀態同步 12 MPRemoteCommand *last = [MPRemoteCommandCenter sharedCommandCenter].previousTrackCommand; 13 last.enabled = self.theLastButton.enabled; 14 [last addTarget:self action:@selector(remoteCommandAction:)]; 15 16 // 設置控制中心播放|暫停按鈕 和 播放頁面的播放|暫停按鈕狀態同步 17 MPRemoteCommand *play = [MPRemoteCommandCenter sharedCommandCenter].playCommand; 18 play.enabled = self.playButton.enabled; 19 [play addTarget:self action:@selector(remoteCommandAction:)]; 20 21 MPRemoteCommand *pause = [MPRemoteCommandCenter sharedCommandCenter].pauseCommand; 22 pause.enabled = self.playButton.enabled; 23 [pause addTarget:self action:@selector(remoteCommandAction:)]; 24 } 25 26 /// 實現target action 27 - (void)remoteCommandAction:(MPRemoteCommand *)com { 28 // 這裏不用具體作些什麼 do nothing.. 29 // 控制中心的事件已經在通知AppDelegateReceiveRemoteEventsNotification裏實現了 30 }