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

最主要的前提: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");

}];

}

}

最新文章

  1. 以 Console 方式运行、调试、编译 .Net 编写的 Windows 服务
  2. IE 11 如何设置“用户代理字符串”
  3. eclipse如何快速查找某个类
  4. 至强CPU性能排行,从X3210起,由低至高排列。
  5. PhoneCat App 教程
  6. Struts2_ValueStack,OGNL详解
  7. iOS - OC NSProcessInfo 系统进程信息
  8. 【转】Hbase shell 常用命令
  9. 《算法导论》归并排序----merge-sort
  10. CF Manthan, Codefest 16 G. Yash And Trees 线段树+bitset
  11. 解决docker主机配置了DaoCloud.io的加速后重启失败问题Failed to start Docker Application Container Engine
  12. c# 对html字符串进行编码
  13. poj 1789 每个字符串不同的字母数代表两个结点间的权值 (MST)
  14. UAC 实现原理及绕过方法-打洞专用
  15. 1、Ansible简介及简单安装、使用
  16. c++-pimer-plus-6th-chapter05
  17. flow flow-typed 定义简单demo
  18. Python学习:18.Python异常处理
  19. 《Beginning Java 7》 - 8 - Collecting Garbage 垃圾回收
  20. Unity使Text 文字逐个出现

热门文章

  1. 2013 Multi-University Training Contest 2 Balls Rearrangement
  2. spring webservice 搭建出现的异常处理。异常: NAMESPACE_ERR: An attempt is made to create or change an object in a way whi
  3. *[hackerrank]Die Hard 3
  4. HTML5入门5---HTML5控件元素
  5. linux 防火墙iptables简明教程
  6. PHP比你想象的好得多
  7. 安卓开发44:解决 INSTALL_FAILED_UID_CHANGED 等问题
  8. class_create()
  9. js中的this怎么理解
  10. poj 1191 棋盘分割(dp + 记忆化搜索)