【问题标题】:ios lock/unlocks count when device is background mode设备处于后台模式时的 ios 锁定/解锁计数
【发布时间】:2015-06-03 11:30:02
【问题描述】:

我正在执行一项任务,即锁定/解锁计数。当应用程序在前台时工作正常,但在后台不工作。请帮助我

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    [[NSUserDefaults standardUserDefaults]setInteger:0 forKey:@"COUNT"];
    [[NSUserDefaults standardUserDefaults]synchronize];

    isVAlue=0;
    //[self registerAppforDetectLockState];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kDisplayStatusLocked"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    MainViewController *mainCtrl=[[MainViewController alloc]initWithNibName:@"MainViewController" bundle:nil];
    self.window.rootViewController=mainCtrl;
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

-(void)registerAppforDetectLockState {

    int notify_token,countval;
    NSString *task=[[NSUserDefaults standardUserDefaults]valueForKey:@"STATE"];


    notify_register_dispatch("com.apple.springboard.lockstate", &notify_token,dispatch_get_main_queue(), ^(int token)
    {

        uint64_t state = UINT64_MAX;

        notify_get_state(token, &state);

        NSLog(@"notify_token %d",token);

        if (isVAlue)
        {
           // notify_cancel(token);
        }


        if(state == 0) {

            isVAlue=YES;
            taskName=@"Unlock";
            [[NSUserDefaults standardUserDefaults]setValue:taskName forKey:@"STATE"];
            [[NSUserDefaults standardUserDefaults]synchronize];

            int value=[[[NSUserDefaults standardUserDefaults] valueForKey:@"COUNT"]intValue];
            value=value+1;

            [[NSUserDefaults standardUserDefaults]setInteger:value  forKey:@"COUNT"];
            [[NSUserDefaults standardUserDefaults]synchronize];
            NSLog(@"value %d",value);

            NSLog(@"unlock device");
            NSDictionary *incrementVal=@{@"incrementVal":[NSNumber numberWithInt:value]};
            [[NSNotificationCenter defaultCenter] postNotificationName:@"HiEverybody" object:self userInfo:incrementVal];




        } else {

            taskName=@"Lock";
            [[NSUserDefaults standardUserDefaults]setValue:taskName forKey:@"STATE"];
            [[NSUserDefaults standardUserDefaults]synchronize];


            NSLog(@"lock device");
            isVAlue=NO;

        }


    });
}



- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.


    UIApplicationState state = [[UIApplication sharedApplication] applicationState];
    if (state == UIApplicationStateInactive) {
        NSLog(@"Sent to background by locking screen");
        [self backgroundTask];

    } else if (state == UIApplicationStateBackground) {
        if (![[NSUserDefaults standardUserDefaults] boolForKey:@"kDisplayStatusLocked"]) {
            NSLog(@"Sent to background by home button/switching to other app");
        } else {

            NSLog(@"Sent to background by locking screen");
            [self backgroundTask];

        }
    }




}

- (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.
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"kDisplayStatusLocked"];
    [[NSUserDefaults standardUserDefaults] synchronize];

    //[self registerAppforDetectLockState];
}

- (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)backgroundTask
{
    UIApplication*    application = [UIApplication sharedApplication];

    __block UIBackgroundTaskIdentifier background_task;
    //Registered a background task, telling the system we need to borrow some events to the system
    background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
        //[self registerAppforDetectLockState];
        //Whether or not complete, the end of background_task task
        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [self registerAppforDetectLockState];

        if (TRUE)
        {
            NSLog(@"running");
        }

        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    });
}

请帮助如何在后台模式下连续运行应用程序。 谢谢 德罗纳瓦利

【问题讨论】:

    标签: ios ios7 ios5 ios6


    【解决方案1】:

    请帮助如何在后台模式下连续运行应用程序。

    这是不可能的。您无法确保您的应用始终运行。

    如果用户启动了你,if你还没有被杀死,if用户有锁码,您可以实现UIApplicationDelegate 方法applicationProtectedDataWillBecomeUnavailable:applicationProtectedDataWillBecomeAvailable: 来找出何时打开和关闭数据保护,这是您所说的代理。但这不太可能与您所描述的内容非常吻合。

    如上所述,您的应用程序无法实现。应用程序不是 iOS 中的操作系统服务。您需要将注意力集中在实际需要上。

    【讨论】:

    • 应用在后台时会调用这个代理吗?
    • 可以,只要你真的在跑步。 WillBecomeUnavailable 确实在您处于后台时才会发生(因为当您积极使用该应用程序时手机不会锁定)。
    • 即使我的应用程序是由操作系统使用重要的位置更新启动的,我也可以期待这种方法的回调?
    • 是的,但我怀疑您对此的想法有误。此方法在钥匙串被锁定或解锁时调用,这不太可能在您可能在位置更新后运行的几分之一秒内发生。如果您想知道受保护的数据是否当前可用,请使用UIApplication.isProtectedDataAvailable
    【解决方案2】:

    查看 Apple 文档的“实施长期运行的后台任务”部分。 来自 Apple 的文档:Declaring Your App's Supported Background Tasks 对某些类型的后台执行的支持必须由使用它们的应用程序提前声明。应用程序使用其 Info.plist 文件声明对服务的支持。将 UIBackgroundModes 键添加到 Info.plist 文件中,并将其值设置为包含以下一个或多个字符串的数组:(请参阅上述链接中的 Apple 文档。)

    【讨论】:

      猜你喜欢
      • 2015-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 2012-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多