IOS 通知 alarm 记录

本文介绍了一种iOS应用保持后台运行的方法,通过设置音频后台请求并利用定时播放空MP3来延长后台存活时间。文章详细解释了不同状态下的应用行为,并提供了实现代码示例。

所有的内容融为一体,去除某一个项不知道结果如何。

最主要的前提:APP 会长期保留在后台

1.在info.plist 文件里面,加入 audio 后台请求

2.当APP 点击home进入后台之后,请求一个background handler,当handler快到期的时候,播放一个空mp3,再请求一个新的handler(不知道这样是否合适)

3. APP 分为“Alive”状态下 

   3.1 点击”通知“进入,会依次启动  didReceiveLocalNotification跟  applicationWillEnterForeground函数。其中applicationWillEnterForeground函数在第一次APP启动的时候是不会进入的。

   3.2 点击”ICON“ 进入,会启动 applicationWillEnterForeground 函数,并不会启动didReceiveLocalNotification函数。

4.APP被结束后台状态下

  4.1 点击”通知“进入,会启动  didFinishLaunchingWithOptions函数,并且有通知进入。其中applicationWillEnterForeground函数不会进入(3.1讲过了)

  4.2 点击”ICON“ 进入,会启动 didFinishLaunchingWithOptions 函数,但是没有通知进入。

 

相关代码:

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification

{

    /*

    {

        UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"dddddd" message:notification.soundName delegate:nil cancelButtonTitle:@"" otherButtonTitles:@"", nil];

        [alert show];

    }

     */

    

    

    NSLog(@"收到通知-开启闹钟");

    

    [AlarmOpt setAlarmFromNoti];

    

    [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(handleNotifiction:) userInfo:notification repeats:NO];

 

}

 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch

    

    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];

    

    mainVC = [[MainViewController alloc]initWithNibName:@"MainViewController" bundle:nil];

    self.window.rootViewController = mainVC;

    

    {

        //VoiceViewController * vc = [[VoiceViewController alloc]initWithNibName:@"VoiceViewController" bundle:nil];

        //NumViewController * vc = [[NumViewController alloc]initWithNibName:@"NumViewController" bundle:nil];

        

        //BIHuaViewController * vc = [[BIHuaViewController alloc]initWithNibName:@"BIHuaViewController" bundle:nil];

        //self.window.rootViewController = vc;

        

        //[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(gotoNumViewB) userInfo:nil repeats:NO];

        

    }

    //

    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])

    {

        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];

    }

    

    UILocalNotification * localNotif=[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

    

    if( !localNotif )

    {

        /*

        {

            UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"ggggggg" message:@"" delegate:nil cancelButtonTitle:@"" otherButtonTitles:@"", nil];

            [alert show];

        }

         */

     

        UILocalNotification * curNot = [AlarmOpt getCurrentNot];

        

        if(curNot )

        {

            NSLog(@"进入前台-开启闹钟");

            

            [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(handleNotifiction:) userInfo:curNot repeats:NO];

        }

        else

        {

            [AlarmOpt startAlarm];

            //

            [RFRateMe showRateAlertAfterTimesOpened:5];

 

        }

    }

    else

    {

        /*

        {

            UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"hhhhhhh" message:localNotif.soundName delegate:nil cancelButtonTitle:@"" otherButtonTitles:@"", nil];

            [alert show];

        }

         */

        

        NSLog(@"开机启动-开启闹钟");

        

        [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(handleNotifiction:) userInfo:localNotif repeats:NO];

    }

    //

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

    [[AVAudioSession sharedInstance] setActive: YES error: nil];

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

    

    //

    [self.window makeKeyAndVisible];

    

    return YES;

}

 

- (void)applicationWillResignActive:(UIApplication *)application {

    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

}

 

- (void)applicationDidEnterBackground:(UIApplication *)application {

    

    [tickTimer invalidate];

    tickTimer = nil;

    

    tickTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(tick) userInfo:nil repeats:YES];

    

    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void){

        

        NSLog(@"over 1");

        

    }];

}

 

 

- (void)applicationWillEnterForeground:(UIApplication *)application {

    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.

    

    NSLog(@"进入前台");

    

    [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(delayEnterFor) userInfo:nil repeats:NO];

    

}

 

-(void)delayEnterFor

{

    UILocalNotification * curNot = [AlarmOpt getCurrentNot];

    

    if(curNot )

    {

        NSLog(@"进入前台-开启闹钟");

        

        [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(handleNotifiction:) userInfo:curNot repeats:NO];

    }

}

 

 

 

- (void)applicationDidBecomeActive:(UIApplication *)application {

    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

}

 

- (void)applicationWillTerminate:(UIApplication *)application {

    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

}

 

-(void)gotoShakeView:(UILocalNotification*)noti

{

    //ShakeViewController * shakeVC = nil;

    

    shakeVC = nil;

    

    shakeVC = [[ShakeViewController alloc]initWithNibName:@"ShakeViewController" bundle:nil];

    

    shakeVC.locationNoti = noti;

    shakeVC.view.frame = [UIScreen mainScreen].bounds;

    [self.window.rootViewController.view addSubview:shakeVC.view];

}

 

 

-(void)gotoNumView:(UILocalNotification*)noti

{

    //NumViewController * numVC = nil;

    

    numVC = nil;

    

    numVC = [[NumViewController alloc]initWithNibName:@"NumViewController" bundle:nil];

 

    numVC.locationNoti = noti;

    numVC.view.frame = [UIScreen mainScreen].bounds;

    [self.window.rootViewController.view addSubview:numVC.view];

}

 

-(void)gotoBiHuaView:(UILocalNotification*)noti

{

    //BIHuaViewController * biVC = nil;

    

    biVC = nil;

    

    biVC = [[BIHuaViewController alloc]initWithNibName:@"BIHuaViewController" bundle:nil];

    

    biVC.locationNoti = noti;

    biVC.view.frame = [UIScreen mainScreen].bounds;

    [self.window.rootViewController.view addSubview:biVC.view];

}

 

-(void)gotoVoiceView:(UILocalNotification*)noti

{

    //VoiceViewController * voiVC = nil;

    voiVC = nil;

    voiVC = [[VoiceViewController alloc]initWithNibName:@"VoiceViewController" bundle:nil];

    voiVC.locationNoti = noti;

    voiVC.view.frame = [UIScreen mainScreen].bounds;

    [self.window.rootViewController.view addSubview:voiVC.view];

}

 

-(void)handleNotifiction:(NSTimer*)timer

{

    UILocalNotification * noti = [timer userInfo];

    

    if( !noti  || _bInCloseAlarm )

    {

        return;

    }

    

    NSData * data = [noti.userInfo objectForKey:ALARM_INFO_KEY];

    AlarmInfo * info  = [NSKeyedUnarchiver unarchiveObjectWithData:data];

    if( info )

    {

        _bInCloseAlarm = YES;

        

        NSLog(@"======接到通知了=========");

        

        if( [info.stopType isEqualToString:ALARM_STOP_TYPE_SHAKE])

        {

            [self gotoShakeView:noti];

        }

        else if( [info.stopType isEqualToString:ALARM_STOP_TYPE_NUM])

        {

            [self gotoNumView:noti];

        }

        else if( [info.stopType isEqualToString:ALARM_STOP_TYPE_BIHUA])

        {

            [self gotoBiHuaView:noti];

        }

        else if( [info.stopType isEqualToString:ALARM_STOP_TYPE_BLOW])

        {

            [self gotoVoiceView:noti];

        }

    }

 

}

 

 

- (void)tick

{

    NSLog(@"tick:%f",[[UIApplication sharedApplication] backgroundTimeRemaining]);

    

    //

    if ([[UIApplication sharedApplication] backgroundTimeRemaining] < 61.0)

    {

        //

 

        if( !audioPlayer )

        {

            NSError *error = nil;

            NSString * str = [[NSBundle mainBundle]pathForResource:@"empty" ofType:@"mp3"];

            NSURL * url = [NSURL fileURLWithPath:str];

 

            

            audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];

            [audioPlayer prepareToPlay] ;

        }

        

        [audioPlayer play];

        

        [NSThread sleepForTimeInterval:1];

        

        [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void){

            

            NSLog(@"over 2");

            

        }];

        

    }

    

}

 

 

转载于:https://www.cnblogs.com/rollrock/p/4936423.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值