标签:个数 代码实现 case switch str 信息 ima observer selector
1、在文件APPDelegate.m里,实现方法“- (void)remoteControlReceivedWithEvent:(UIEvent *)event”的重写,用来接收控制中心的事件。
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里就设置这些。
2、在音频播放界面
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 }
上面这些实现了控制中心和播放界面的交互。此时,控制中心还没有显示当前播放的音频信息(嗯,我还没有设置)。如下:
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 }
这时,锁屏界面已经可以显示音频对应的信息了。
还有最后一步设置(动态设置控制中心的按钮状态),如:当前播放的音频是播放列表最后一条,设置控制中心的下一个按钮不可点击。。。
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 }
标签:个数 代码实现 case switch str 信息 ima observer selector
原文地址:https://www.cnblogs.com/mustard22/p/11091309.html