拦截电话 - iPhone(连接 CoreTelephony 的正确方法)
Posted
技术标签:
【中文标题】拦截电话 - iPhone(连接 CoreTelephony 的正确方法)【英文标题】:Intercepting phone call - iPhone (correct method to hook in CoreTelephony) 【发布时间】:2013-01-23 09:11:54 【问题描述】:我是越狱调整开发场景的新手。我正在尝试找出合适的“挂钩”方法,以便拦截来电(然后运行一些代码)。
我已经转储了 CoreTelephony 框架的头文件,但是似乎没有明显的方法可以挂钩。我试过了:
- (void)broadcastCallStateChangesIfNeededWithFailureLogMessage:(id)arg1;
- (BOOL)setUpServerConnection;
但都没有工作。我所说的工作是指 - 当 iPhone 接到电话时被调用。
关于合适的钩子方法的任何指针?谢谢:)
注意: 这将是使用私有 API 的越狱调整,因此不会提交到 App Store。
【问题讨论】:
您是否只需要在有电话打入时得到通知,还是需要真正拦截通常转到手机app,让你可以替换一些正常运行的代码?如果区别不清楚,请告诉我,正如我所描述的那样。 只要收到通知就可以了。此后,我使用[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callReceived:) name:CTCallStateIncoming object:nil];
沿着这条路线走下去,但没有调用“callReceived”方法(讽刺)。我会玩一玩,这可能是显而易见的!
你需要这个做什么?
【参考方案1】:
我没有测试您的代码,但我认为您的问题可能是您需要使用 Core Telephony 通知中心来注册该事件(不是您评论中代码中的内容)。像这样的:
// register for all Core Telephony notifications
id ct = CTTelephonyCenterGetDefault();
CTTelephonyCenterAddObserver(ct, // center
NULL, // observer
telephonyEventCallback, // callback
NULL, // event name (or all)
NULL, // object
CFNotificationSuspensionBehaviorDeliverImmediately);
你的回调函数是
static void telephonyEventCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
NSString *notifyname = (NSString*)name;
if ([notifyname isEqualToString:@"kCTCallIdentificationChangeNotification"])
NSDictionary* info = (NSDictionary*)userInfo;
CTCall* call = (CTCall*)[info objectForKey:@"kCTCall"];
NSString* caller = CTCallCopyAddress(NULL, call);
if (call.callState == CTCallStateDisconnected)
NSLog(@"Call has been disconnected");
else if (call.callState == CTCallStateConnected)
NSLog(@"Call has just been connected");
else if (call.callState == CTCallStateIncoming)
NSLog(@"Call is incoming");
else if (call.callState == CTCallStateDialing)
NSLog(@"Call is Dialing");
else
NSLog(@"None of the conditions");
我提供另一种技术in this similar question here。另外,请注意我在该问题中关于未在已放入后台的UIApplication
中收到通知的评论。
更新:请参阅下面 cud_programmer 关于在 ios 6 上使用 kCTCallStatus
而不是 kCTCall
的评论。
【讨论】:
@cud_programmer,所以如果你真的不需要执行 UI 操作,那么在我看来构建一个 Launch Daemon 更有意义,它运行所有时间。然后,您不必担心 iOS 对普通 UIApplications 施加的所有限制。指向我的其他答案的链接包含指向 Chris Alvares 的用于创建启动守护进程的在线教程的链接。 我正在使用[[[info objectForKey:@"kCTCallStatus"] stringValue] isEqualToString:@"4"]
,它可以工作。 call.callState
仍然使程序崩溃。
@nanospeck,不幸的是,CTCallCenterAddObserver()
不是公共 API,所以这可能会被拒绝。但是,CTCall
is public。因此,现在必须有一些 API 允许您使用它。
@nanospeck,看看at this documentation ... this looks like a public replacement for my code above。
@nanospeck,如果文档专门使用了“暂停”一词,请确保您理解 the different iOS app states clearly。如果您想要一个可以始终收到通知并且从不暂停的应用,有几种方法可以实现,但它们可能不会被 App Store 接受。以上是关于拦截电话 - iPhone(连接 CoreTelephony 的正确方法)的主要内容,如果未能解决你的问题,请参考以下文章