Nimrod Shai
Nimrod Shai

Reputation: 1179

Detecting phone calls when the app is asleep

What i'm trying to do is an app that runs a code when a call is incoming. I know I cannot get any details of the caller and that is fine.

My issue so far is that it's only working when the app is in foreground.

This is my code:

#import <CoreTelephony/CoreTelephonyDefines.h>
#import <CoreTelephony/CTCallCenter.h>
#import <CoreTelephony/CTCall.h>

CTCallCenter *callCenter = [[CTCallCenter alloc] init];

[callCenter setCallEventHandler:^(CTCall *call) {
    ONLog(@"Event handler called");
    if ([call.callState isEqualToString: CTCallStateConnected]) {
        ONLog(@"Connected");
    } else if ([call.callState isEqualToString: CTCallStateDialing]) {
        ONLog(@"Dialing");
    } else if ([call.callState isEqualToString: CTCallStateDisconnected]) {
        ONLog(@"Disconnected");
    } else if ([call.callState isEqualToString: CTCallStateIncoming]) {
        ONLog(@"Incomming");
    }
}];

Can someone help me with making this run as a background task?

EDIT:

I used Richas' code like this:

    __block UIBackgroundTaskIdentifier yourBackgroundTaskName;
    yourBackgroundTaskName = [application beginBackgroundTaskWithExpirationHandler:^{

        // CODE FOR EXPIRATION HANDLER BLOCK
        [application endBackgroundTask: yourBackgroundTaskName];
        yourBackgroundTaskName = UIBackgroundTaskInvalid;

    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // DO YOUR STUFF HERE. START OF BACKGROUND TASK.
        NSLog(@"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]);

        self.callCenter = [[CTCallCenter alloc] init];

        [self.callCenter setCallEventHandler:^(CTCall *call) {
            ONLog(@"Event handler called");
            if ([call.callState isEqualToString: CTCallStateConnected]) {
                ONLog(@"Connected");
            } else if ([call.callState isEqualToString: CTCallStateDialing]) {
                ONLog(@"Dialing");
            } else if ([call.callState isEqualToString: CTCallStateDisconnected]) {
                ONLog(@"Disconnected");
            } else if ([call.callState isEqualToString: CTCallStateIncoming]) {
                ONLog(@"Incomming");
            }
        }];


        //WHEN YOU ARE DONE WITH YOUR TASK, TELL THAT TO SYSTEM
        [application endBackgroundTask: yourBackgroundTaskName];
        yourBackgroundTaskName = UIBackgroundTaskInvalid;
    });
  1. It only buys me 180 seconds of background running...
  2. It's not working :) The call is not detected

Upvotes: 0

Views: 410

Answers (1)

Anon
Anon

Reputation: 623

You should check for following two methods for your problem:

- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithName:(NSString *)taskName expirationHandler:(void (^)(void))handler`

- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler

You can implement any of them in applicationDidEnterBackground & that can buy you some time (5-10 minutes). Code might be something like following:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UIBackgroundTaskIdentifier yourBackgroundTaskName;
    yourBackgroundTaskName = [application beginBackgroundTaskWithExpirationHandler:^{

          // CODE FOR EXPIRATION HANDLER BLOCK
          [application endBackgroundTask: yourBackgroundTaskName];
          yourBackgroundTaskName = UIBackgroundTaskInvalid;

    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

         // DO YOUR STUFF HERE. START OF BACKGROUND TASK.

         //WHEN YOU ARE DONE WITH YOUR TASK, TELL THAT TO SYSTEM
         [application endBackgroundTask: yourBackgroundTaskName];
         yourBackgroundTaskName = UIBackgroundTaskInvalid;
    });
}

Hope, this should at least get you started.

Upvotes: 2

Related Questions