我花了几天时间在SO和其他网站上研究,以回答这一问题,但没有任何uck。
基本上,我为自己确定的挑战是,为SOS制造一个警钟,不管用户(理由或背景)在哪里,都不会听从。 我已经完成这项工作,使用了AVAudioPlayer案,并在用户发出警报时开始使用空洞的声音,以便用户能够保持这种背景。 当警报要走的时候(例如当发射国家安全局时),已经启动并准备起作用的第二角色就开始迎来用户的警钟。
此外,我通过实施AVAudioSessionDelegate方法,通过电话、系统时间或警钟处理中断问题。 它既在背景上又在地缘上运作,但最奇怪的是:
当中断结束时,AVAudioPlayer继续玩.BUT I,除非我再次把 app子带到地下。
To get to the bottom of this, I have experimented with a much simpler project which I am posting below. What this app does is, as soon as you enter the app, an instance of the AVAudioPlayer class starts looping a certain sound. Then when you bring it to the background, the player continues to loop the sound. When an interruption occurs I pause the player and when it ends I use a dispatch to wait a couple of seconds before it calls two methods, ie (void)playPlayer, a method that contains the code to resume playing the file and (void)tester, a method that contains a timer, which is set to stop the player 5 seconds after the interruption (or 7 seconds to be exact) has ended. Both the methods get called as indicated by the NSLogs I have put in both of them, but the timer never gets fired and the player continues to play indefinitely.
The Code for the .h file:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
@interface InterruptionTest3ViewController : UIViewController <AVAudioSessionDelegate, AVAudioPlayerDelegate>
{
AVAudioSession *mySession;
AVAudioPlayer *myPlayer;
}
-(void) playPlayer;
-(void) pausePlayer;
-(void) tester;
@end
这里是:
#import "InterruptionTest3ViewController.h"
@interface InterruptionTest3ViewController ()
@end
@implementation InterruptionTest3ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
mySession = [AVAudioSession sharedInstance];
NSError *setActiveError = nil;
[mySession setActive:YES withFlags:AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation error:&setActiveError];
if (setActiveError) {
NSLog(@"Session failed to activate within viewDidLoad");
}
else {
NSLog(@"Session was activated within viewDidLoad");
}
NSError *setCategoryError = nil;
[mySession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
if (setCategoryError) {
NSLog(@"Category failed to be set");
}
else {
NSLog(@"Category has been set");
}
[mySession setDelegate:self];
NSString *path = [[NSBundle mainBundle] pathForResource:@"headspin" ofType:@"wav"];
NSError *initMyPlayerError = nil;
myPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&initMyPlayerError];
if (initMyPlayerError) {
NSLog(@"myPlayer failed to initiate");
}
else {
NSLog(@"myPlayer has been initiated");
}
[myPlayer prepareToPlay];
[self playPlayer];
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty (
kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof (allowMixing),
&allowMixing
);
[myPlayer setNumberOfLoops:-1];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
-(void) beginInterruption
{
[myPlayer pause];
}
-(void) endInterruptionWithFlags:(NSUInteger)flags
{
if (flags) {
if (AVAudioSessionInterruptionFlags_ShouldResume)
{
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC),dispatch_get_main_queue(), ^{
[self playPlayer];
[self tester];
});
}
}
}
}
-(void) tester
{
[NSTimer timerWithTimeInterval:5.0 target:self selector:@selector(pausePlayer) userInfo:nil repeats:NO];
NSLog(@"tester method has been called");
}
-(void) playPlayer
{
[NSTimer timerWithTimeInterval:5.0 target:myPlayer selector:@selector(stop) userInfo:nil repeats:NO];
[myPlayer play];
NSLog(@"playPlayer method has been called");
}
-(void) pausePlayer
{
[myPlayer pause];
}
//viewDidUnload etc not listed.
因此,这是民俗。 同样,为什么在机车身为背景时,停工时间没有被发射? 我是否需要在应用DidEnterBackground方法中找到一些东西?
非常感谢你们。