java 中断应用_应用程序处于后台时,在中断后恢复执行代码

开发者遇到一个iOS应用在后台时,即使处理了中断和恢复,仍无法在中断后执行代码(除了AVAudioPlayer继续播放)。创建了一个简单的项目来测试这个问题,发现计时器在后台中断后不会触发,而音频播放器持续播放。寻求解决方案。
摘要由CSDN通过智能技术生成

我花了几天时间研究SO和其他网站的答案,但没有任何运气 .

从本质上讲,我为自己设定的挑战是为iOS创建一个闹钟应用程序,无论用户身在何处(前景或背景)都会发出声音 . 我已经通过使用AVAudioPlayer实例并在用户设置警报时开始播放空声音文件以使应用程序在后台继续运行 . 当闹钟响起时(即当NSTimer被解雇时),已经启动并准备播放的第二个播放器开始播放用户醒来的铃声 .

此外,我通过实现AVAudioSessionDelegate方法beginInterruption和endInterruptionWithFlags设法通过电话,系统计时器或闹钟来处理中断 . 它适用于后台和前台模式,但最奇怪的事情发生在:

当中断结束时,AVAudioPlayer继续播放但是我无法在我的应用程序中执行任何其他代码,除非我再次将应用程序带到前台 .

为了深究这一点,我尝试了一个更简单的项目,我将在下面发布 . 这个应用程序的作用是,一旦你进入应用程序,AVAudioPlayer类的一个实例开始循环某个声音 . 然后当你把它带到后台时,播放器继续循环播放声音 . 当中断发生时我暂停播放器,当它结束时我使用一个调度等待几秒钟才调用两个方法,即(void)playPlayer,一个包含恢复播放文件的代码的方法和(void)测试器,一种包含计时器的方法,该计时器设置为在中断后5秒钟停止播放器(或准确地说是7秒) . 两个方法都被调用,如我在其中放入的NSLog所指示的那样,但是计时器永远不会被触发,玩家将继续无限期地播放 .

这是.h文件的代码:

#import

#import

#import

@interface InterruptionTest3ViewController : UIViewController

{

AVAudioSession *mySession;

AVAudioPlayer *myPlayer;

}

-(void) playPlayer;

-(void) pausePlayer;

-(void) tester;

@end

这是.m文件的代码:

#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.

所以,这就是人们 . 同样,为什么在应用程序处于后台时中断后计时器没有被触发?我是否需要在applicationDidEnterBackground方法中设置一些内容?

非常感谢你提前!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值