以编程方式断开或连接iPhone呼叫

编程入门 行业动态 更新时间:2024-10-24 14:25:08
本文介绍了以编程方式断开或连接iPhone呼叫的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在为iOS进行个人调整。我想在电话显示任何内容之前断开/连接电话。我正在进入类 SBUIFullscreenAlertAdapter 的 initWithAlertController:方法。当我只显示一条显示来电号码及其姓名的消息时,一切都还可以,但是当我尝试接听电话或以编程方式断开电话时,它会崩溃并进入安全模式。

I'm working on a personal tweak for iOS. I want to disconnect/connect a phone call before the phone would show anything. I'm hooking into the initWithAlertController: method of class SBUIFullscreenAlertAdapter. Everything is okay when I just show a message that shows the incoming phone number and its name, but when i try to answer the phone call or disconnect it programmatically, it will crash and go to safe mode.

这是我的代码:

@interface SBUIFullscreenAlertAdapter - (id)initWithAlertController:(id)arg1; @end @interface MPIncomingPhoneCallController { struct __CTCall *_incomingCall; } - (id) incomingCallNumber; - (void)stopRingingOrVibrating; - (void)answerCall:(struct __CTCall *)arg1; @end %hook SBUIFullscreenAlertAdapter - (id)initWithAlertController:(id)arg1 { MPIncomingPhoneCallController *phoneCall = (MPIncomingPhoneCallController*)arg1; [phoneCall stopRingingOrVibrating]; if([phoneCall.incomingCallNumber isEqualToString:@"+98.........."]) { [phoneCall answerCall:_incomingCall]; } %orig; return self; } %end

错误是它说:使用未声明的标识符'_incomingCall'。

The error is that it says: "Use of undeclared identifier '_incomingCall'".

如何解决问题?有没有办法在挂钩方法时使用私有实例变量?是否有一个函数返回来电的 CTCallRef * ?有没有其他方法可以实现这一目标?

How can I solve the problem? Is there a way to use a private instance variable while hooking a method? Is there a function which returns a CTCallRef* of the incoming call? Is there some other way to accomplish this?

很明显,我正在为越狱的iOS设备编码,因此使用私有框架没有问题。

It should be obvious that I'm coding for jailbroken iOS devices, so there is no problem with the use of private frameworks.

推荐答案

还有更好的地方 - MPTelephonyManager - (void)displayAlertForCall:(id)调用。此方法位于 IncomingCall.servicebundle 二进制文件中,而不是SpringBoard本身。当有来电时,这个二进制文件在运行时被加载到SpringBoard中。在此之前 IncomingCall.servicebundle 未加载,因此您无法挂钩它的方法。

There is much better place to do that - MPTelephonyManager -(void)displayAlertForCall:(id)call. This method is located in IncomingCall.servicebundle binary, not in SpringBoard itself. This binary is being loaded at runtime into SpringBoard when there is an incoming call. Before that IncomingCall.servicebundle is not loaded thus you can't hook it's methods.

为了挂钩方法,首先,请阅读如何挂钩MPIncomingPhoneCallController的方法? SBPluginManager 正在加载* .servicebundle运行时的二进制文件。你需要挂钩它的 - (类)loadPluginBundle:(id)bundle 方法。它看起来像这样:

In order to hook the method, first, read this How to hook methods of MPIncomingPhoneCallController? SBPluginManager is loading *.servicebundle binaries at runtime. You need to hook it's -(Class)loadPluginBundle:(id)bundle method. It's gonna look something like this:

void displayAlertForCall_hooked(id self, SEL _cmd, id arg1); void(*displayAlertForCall_orig)(id, SEL, id) = NULL; %hook SBPluginManager -(Class)loadPluginBundle:(NSBundle*)bundle { Class ret = %orig; if ([[bundle bundleIdentifier] isEqualToString:@"com.apple.mobilephone.incomingcall"] && [bundle isLoaded]) { MSHookMessageEx(objc_getClass("MPTelephonyManager"), @selector(displayAlertForCall:), (IMP)displayAlertForCall_hooked, (IMP*)&displayAlertForCall_orig); } return ret; } %end

如你所见,挂钩延迟到 IncomingCall.servicebundle 。我不太了解徽标/ theos,但我认为它不能那样做。这就是我使用CydiaSubstrate(MobileSubstrate)API的原因。

As you can see, hooking is deferred until IncomingCall.servicebundle is loaded. I don't know logos/theos that well but I think it can't do that. That's why I used CydiaSubstrate (MobileSubstrate) API.

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) typedef void* CTCallRef; void CTCallDisconnect(CTCallRef); void CTCallAnswer(CTCallRef); void displayAlertForCall_hooked(id self, SEL _cmd, id arg1) { CTCallRef call = NULL; if (SYSTEM_VERSION_LESS_THAN(@"7.0")) { //On iOS 6 and below arg1 has CTCallRef type call = arg1; } else { //On iOS 7 arg1 has TUTelephonyCall* type call = [arg1 call]; } NSString *callNumber = (NSString*)CFBridgingRelease(CTCallCopyAddress(NULL, call)); if ([callNumber isEqualToString:@"+98.........."]) { CTCallAnswer(call); //CTCallDisconnect(call); } %orig; }

更多推荐

以编程方式断开或连接iPhone呼叫

本文发布于:2023-11-27 20:15:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1639450.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方式   iPhone

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!