一般问题/申请背景/目的:
我有一个Timer应用程序,当App处于 BACKGROUND状态并且收到UILocalNotification时,我想播放自定义声音。
我利用 UILocalNotification 来触发计时器(这是应用程序无法在后台运行超过10分钟的过程的唯一方法。)
的问题:
这是我发送UILocalNotification时设置声音的方式:
_localNotif.soundName = UILocalNotificationDefaultSoundName;
然后我创建通知并发布。应用收到后,我会按以下方法处理(请阅读代码注释以获取更多信息):
- (void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification {
NSLog(@"received notification");
// Here I try to play a custom sound created in a custom object
// however the sound does NOT get played when the APP is in BACKGROUND mode (but I still see the NSLog message in console "received notification"
SoundManager* audio = [SoundManager sharedInstance];
[audio playSound:Standard];
}
答案 0 :(得分:0)
尝试更改行
_localNotif.soundName = UILocalNotificationDefaultSoundName;
对于这样的事情:
_localNotif.soundName = "customSoundFileName.customSoundFileExtension";
正如它在official docs中所述,您必须在应用程序的主包中指定声音资源的文件名。 我有一个工作示例,如果您需要,我可以与您分享。 祝你好运!
答案 1 :(得分:0)
在您触发本地通知的视图控制器中:
.h
#import <AVFoundation/AVFoundation.h>
@interface ViewController : UIViewController <AVAudioPlayerDelegate>
@property (nonatomic, strong) AVAudioPlayer *notificationSound;
如果本地通知在应用代理中进入后台,则您不必触发本地通知,无论是否在后台,本地通知都会触发。当应用有效时,didReceiveLocalNotification
是您处理它的方式:来自docs here:
当正在运行的应用收到本地通知时发送给代理。
.m
-(void)startTimer {
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runTimerTasks:) userInfo:nil repeats:YES];
[self fireLocalNotification];
}
-(void)fireLocalNotification {
UILocalNotification *timerDoneNotification = [[UILocalNotification alloc] init];
timerDoneNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:secondsLeft];
timerDoneNotification.alertBody = @"Time Up!";
timerDoneNotification.alertAction = @"OK";
timerDoneNotification.timeZone = [NSTimeZone defaultTimeZone];
timerDoneNotification.soundName = @"alarm.aif";
[[UIApplication sharedApplication] scheduleLocalNotification:timerDoneNotification];
}
然后,如果你只是想在其他地方播放/停止声音,就像当应用处于活动状态时,secondsLeft为0,你可以按如下方式调用它:
[self playAlarm];
-(void)playAlarm {
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:@"alarm" ofType:@"aif"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSError *error = nil;
self.notificationSound = [[AVAudioPlayer alloc] initWithData:fileData error:&error];
self.notificationSound.numberOfLoops = -1;
[self.notificationSound play];
}
并阻止它:
[self.notificationSound stop];
对此不利的是UILocalNotification声音不能超过30秒,但它回答了手头的问题。
兴趣点:
当系统发送本地通知时,可能会发生一些事情,具体取决于应用程序状态和通知类型。如果应用程序不在最前面并且可见,则系统会显示警报消息,对应用程序进行标记,并播放声音 - 通知中指定的任何内容。如果通知是警报并且用户点击操作按钮(或者,如果设备被锁定,则拖动打开操作滑块),应用程序被唤醒或启动。 (如果用户点击您使用additionalActions属性指定的其中一个自定义操作,则应用程序将被唤醒或启动到后台。)在其应用程序:didFinishLaunchingWithOptions:方法中,应用程序委托可以从启动选项字典中获取UILocalNotification对象使用UIApplicationLaunchOptionsLocalNotificationKey键。委托可以检查通知的属性,如果通知在其userInfo字典中包含自定义数据,则它可以访问该数据并相应地处理它。另一方面,如果本地通知仅标记应用程序图标,并且响应中的用户启动应用程序,则调用应用程序:didFinishLaunchingWithOptions:方法,但选项字典中不包含UILocalNotification对象。当用户选择自定义操作时,app delegate的应用程序:handleActionWithIdentifier:forLocalNotification:completionHandler:方法被调用来处理操作。
如果应用程序在系统发送通知时最重要且可见,则会调用应用程序委托的应用程序:didReceiveLocalNotification:来处理通知。使用提供的UILocalNotification对象中的信息来确定要采取的操作。当应用程序已经位于最前端时,系统不会显示任何警报,标记应用程序的图标或播放任何声音。
答案 2 :(得分:0)
UILocalNotification *notification = [UILocalNotification new];
notification.fireDate = [NSDate date]; //
notification.alertBody = @"This is custom alarm";
notification.soundName = @"YourCustomAudioFile.aiff";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
BUT
您的自定义音频文件必须符合两个条件:
wav
,aiff
或caf
文件容器)所以,如果你有MP3自定义闹钟声音,你应该转换它...
以下是Apple文档(查找Preparing Custom Alert Sounds
部分)link