ios nstimer 在后台运行以检查警报时间是不是等于当前时间并播放音频

Posted

技术标签:

【中文标题】ios nstimer 在后台运行以检查警报时间是不是等于当前时间并播放音频【英文标题】:ios nstimer run in background for check alarm time is equal to current time and play audioios nstimer 在后台运行以检查警报时间是否等于当前时间并播放音频 【发布时间】:2014-08-20 13:39:08 【问题描述】:

我用谷歌搜索了几个小时,但是如果有任何方法可以在应用程序在后台运行时保持正在运行的 NSTimer 处于活动状态,但找不到任何信息?请帮我 , 当应用程序进入后台然后运行一个功能并且每秒检查警报时间等于当前时间,然后播放音频并打开关闭警报页面 如果有人知道警报应用程序开源及其在后台运行,请与我分享 在这里我试试这个,但这不起作用

- (void)applicationDidEnterBackground:(UIApplication *)application


    inBackground=YES;
    UIApplication*    app = [UIApplication sharedApplication];

    bgTask = [app beginBackgroundTaskWithExpirationHandler:^
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    ];

    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
        while (inBackground == YES) 


            [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
                                          selector:@selector(checkAlert) userInfo:nil repeats:YES];

        


        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    );


-(void)checkAlert

    NSLog(@"Chalaaaaaa");
    NSString *checkAlarmOnOff = [defaults stringForKey:@"setAlarm"];
    // Switch Alarm From Setting page
    NSString *SwitchAlarm=[defaults stringForKey:@"setSwitchAlarm"];

    if([SwitchAlarm isEqualToString:@"ON"])
    
        if([checkAlarmOnOff isEqualToString:@"YES"])
        
            if(![alarmRun isEqualToString:@"Yes"])
            

                NSString *getAlarmTime = [defaults stringForKey:@"setAlarmTime"];
                 NSLog(@"AA-%@",getAlarmTime);
                 NSLog(@"BB-%@",globalClockTime);
                if([getAlarmTime isEqualToString:globalClockTime])
                
                    [self MusicAction];

                    [_audioPlayer play];
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alarm" message:@"Alarm On" delegate:self cancelButtonTitle:@"Off" otherButtonTitles:nil, nil];
                    [alert show];
                    alarmRun=@"Yes";

                
            

        
    



请帮帮我,

【问题讨论】:

if([getAlarmTime isEqualToString:globalClockTime]) 似乎有问题。不能保证时间会相等。尝试创建一个 if 大于关系。 【参考方案1】:

安排本地通知会如你所愿。使用日历和日期组件在今天的特定时间或其他日期的特定时间触发本地通知

NSCalendar *calendar = [NSCalendar currentCalendar];

    // Split the date into components but only take the year, month and day and leave the rest behind
    NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; // Current Date

    // Build the date formatter
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"h:mm a"];
    // Convert the string time into an NSDate
    NSDate *time = [formatter dateFromString:@"1:59 PM"]; //your hour:minutes am/pm values

    // Split this one in components as well but take the time part this time
    NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit ) fromDate:time];

    // Do some merging between the two date components
    dateComponents.hour = timeComponents.hour;
    dateComponents.minute = timeComponents.minute;

    // Extract the NSDate object again
    NSDate *fireTime = [calendar dateFromComponents:dateComponents];

    NSLog(@"Fire Time is  FireTime %@", fireTime);
     localNotification.fireDate = fireTime;

如果您在模拟器中检查它,那么它将打印 TimeZone free 日期/时间值。不用担心通知会以设备的本地时区触发。

【讨论】:

【参考方案2】:

请注意,Apple 肯定会拒绝任何滥用其后台政策的应用程序,这样做只会对个人和企业用途有用!

那么我们将如何滥用 ios 后台策略呢?我们将把我们的应用声明为背景音乐播放器,但不播放任何音乐。

1) 首先确保您的应用已在功能 -> 后台模式中打开并启用“音频和 AirPlay”。还要确保你正在导入 AVFoundation

2) 现在创建您的无声音乐文件。我用一秒钟的静音 MP3 文件取得了成功。音频文件不一定非要静音,但为什么要用随机的音频文件吓唬用户呢?将此添加到“支持文件”类别中。

3) 向 View Controller 添加一个属性,用于保存静音音频播放器。

Swift:   
   var player = AVPlayer()

Obj-c:
   @property (nonatomic, strong) AVPlayer *player;

4) 现在,您应该设置音频会话。我选择在演示应用中的单个视图的视图控制器的 viewDidLoad 中执行此操作。

Swift:
   do 
      try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: .MixWithOthers)
      try AVAudioSession.sharedInstance().setActive(true)
    catch 
      print(error)
   

Obj-c:
   NSError *sessionError = nil;
   [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&sessionError];

类别 AVAudioSessionCategoryPlayback 是少数允许背景的类别之一。选项 AVAudioSessionCategoryOptionMixWithOthers 将确保您的静音音频不会停止任何当前正在播放的背景音频,并确保当用户将来播放音乐时,它不会启动您的后台任务。好的开发者也会检查返回值和sessionError,但我不是好的开发者。

5) 现在为您的无声音频文件创建实际的播放器项目。如果您以不同的方式嵌入音频文件,请随意调整它。这里没有诡计。

Swift:
   let path = NSBundle.mainBundle().pathForResource("30sec", ofType: "mp3")
   let item = AVPlayerItem(URL: NSURL(fileURLWithPath: path!))
   player = AVPlayer(playerItem: item)

Obj-c:
   AVPlayerItem *item = [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@”silence” withExtension:@”mp3″]];
   [self setPlayer:[[AVPlayer alloc] initWithPlayerItem:item]];

6) 这是诀窍!这可确保音频播放器在播放您的声音文件后保持活动状态。另一种方法是继续循环一个静音轨道,但为什么要浪费更多的 CPU 周期(和电池)?

Swift:
   player.actionAtItemEnd = .None

Obj-c:
   [[self player] setActionAtItemEnd:AVPlayerActionAtItemEndNone];

7) 现在,只要您希望将应用程序保持在后台,只需调用

Swift:
   player.play()

Obj-c:
   [[self player] play];

即使在用户切换应用后,您的应用也会继续运行。

【讨论】:

【参考方案3】:

NSTimer 不会在后台运行。并且使用 beginBackgroundTaskWithExpirationHandler 不会解决您的问题。使用后台任务,您的应用最多可以运行 10 分钟,然后就会被杀死

你应该使用UILocalNotification

UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = dateTime;
localNotification.alertBody = [NSString stringWithFormat:@"Alert Fired at %@", dateTime];
localNotification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

使用 NSCalendar 计算时间并添加以下行:

localNotification.repeatInterval = NSDayCalendarUnit;

【讨论】:

谢谢你,但一个问题是,在我的应用程序中,我只有时间玩闹铃,没有日期,我该怎么办,请帮帮我。

以上是关于ios nstimer 在后台运行以检查警报时间是不是等于当前时间并播放音频的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 7 中超过 180 秒的后台运行 NSTimer?

NSTimer 在后台模式下使用 locationManager 委托(“作弊方式”)SWIFT

在后台运行 NSTimer 方法

进入后台状态时是不是可以在 iOS 4 设备上运行 NSThread 或 NSTimer?

当应用程序后台运行时,NSTimer 是不是会触发?

当 ios 应用程序在后台并且有人选择它时调用警报声音,使用核心运动