在网上搜索很多资料和帖子,也看了苹果的开发文档,iOS对系统调用的限制很严格
对于非越狱的手机,我们能做的就是监听来电的状态,但不能获取来电号码;可以拨打电话,但需要在ios 的标准用户界面下进行;可以发送短信,但仍需要通过ios的标准用户界面;对于接收到的短信,就无能为力了
对于越狱的手机,从我看到的资料来说,监听电话,获取来电号码;获取短信以及短信内容,后台发送短信都是可以实现的
虽然没有达到自己想要的结果:非越狱情况下获取来电号码以及后台发送短信,但找了几天资料,还是做一个总结:非越狱下,iOS在电话和短信方面可以被调用的方式和功能
1、调用系统tel
(1)对于来电的信息获取
在ios 4.0 的官方api中,多了Core Telephony 的framework,有5个类可供调用,CTCall\CTCallCenter\CTCarrier\CTSubscriber\CTTelephoneNetworkInfo,另外,还有两个所谓的非公开类CTCellularData和CTSubscriberInfo。
CoreTelephony框架:获得蜂窝电话的通话状态以及蜂窝服务提供商的信息,对于五个公开类:
CTCall:获得通话的一个标识符,来决定通话的状态;callID callState两个属性,前者是标识符,后者是通话状态(四种)
CTCallCenter:获得当前移动呼叫的一个列表,对呼叫的状态改变作出回应;callEventHandler currentCalls两个属性,前者呼叫状态改变时,发布该事件,后者一个数组,包含来进行中的每一个移动呼叫
总结:可以判断iphone的通话状态,但是无法获取通话人的信息。
CTCarrier:获取用户移动服务商的信息,如服务商唯一标识符,是否提供VoIP;allowsVoIP,是否允许voip,carrierName,服务商名字,isoCountryCode,服务商的国家代码,mobileCountryCode,移动国家代码MCC,mobileNetworkCode,服务商的移动网络代码MNC
CTSubscriber:提供了蜂窝网络用户的信息,carrierToken,包含有关用户授权信息的数据块,CTSubscriberTokenRefreshed,该类的相关通知
CTTelephonyNetworkInfo:该类对服务提供商变更时作出回应,例如,用户更换了其他服务商的SIM卡,同时你的应用正在运行,会发出服务商变更通知
总结:只能获取本用户的移动服务商的信息。
该函数获取电话状态,要引入与电话状态相关的两个头文件
#import <CoreTelephony/CTCallCenter.h>
#import <CoreTelephony/CTCall.h>
-(void)detectCall
{
NSLog(@"detectCall");
CTCallCenter *callCenter = [[CTCallCenter alloc] init];
callCenter.callEventHandler=^(CTCall* call)
{
NSLog(@"callEventHandler");
if (call.callState == CTCallStateDisconnected)
{
//呼叫终止的状态
NSLog(@"Call has been disconnected");
self.feedbackMsg.text = @"Call has been disconnected";
}
else if (call.callState == CTCallStateConnected)
{
//呼叫被完全建立的状态
NSLog(@"Call has just been connected");
self.feedbackMsg.text = @"Call has just been connected";
}
else if(call.callState == CTCallStateIncoming)
{
//在连接建立之前,有来电但还未被接听
NSLog(@"Call is incoming");
self.feedbackMsg.text = @"Call is incoming";
}
else if (call.callState ==CTCallStateDialing)
{
//在连接建立前,用户初始一个呼叫
NSLog(@"call is dialing");
self.feedbackMsg.text = @"Call is dialling";
}
else
{
NSLog(@"Nothing is done");
self.feedbackMsg.text = @"nothing is done";
}
};
}
(2)打电话
对于打电话,搜集到三种方式:
方法1,拨打完电话回不到原来的应用,会停留在通讯录里,而且是直接拨打,不弹出提示
- (IBAction)madeCall:(id)sender {
//1 can't return the app
if ([[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://10086"]]) {
NSLog(@"make a call to 10086");
}else{
NSLog(@"make the call failed");
}
}
方法2,打完电话后还会回到原来的程序,也会弹出提示,需要用户确认,推荐这种
- (IBAction)sendMail:(id)sender {
//2 can return the app ,show a webview,need user to chooseNSMutableString *str = [[NSMutableString alloc] initWithFormat:@"tel:%@",@"10086"];
UIWebView *callWebView = [[UIWebView alloc] init];
[callWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:str]]];
[self.view addSubview:callWebView];
}
}
方法3,这种方法也会回去到原来的程序里(注意这里的telprompt,苹果的私有协议,app无法上架),也会弹出提示,需要用户确认
//3 can return the app ,show a alert to choose
NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"telprompt://%@",@"10086"];
NSLog(@"str:%@",str);
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
}
2 系统调用SMS
(1)接收短信
获取接收短信的信息不确定,目前不能,目前了解的是没有越狱的iphone设备无法获取收到的短信信息。 越狱的iphone可以获取短信内容和发件人号码。
(2)发送短信
方法1:——URL 代码简单,但只是跳转到系统界面,可以设置发送短信的号码,但不能设置内容,也不能返回原app
//调用发短信功能,不能返回原app
- (IBAction)sendSMS:(id)sender {
if ([[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://10000"]]) {
NSLog(@"send message successful");
}else{
NSLog(@"send message failed");
}
}
方法2:——MessageUI框架
如果自定义短信,需要使用一个框架MessageUI。能返回原app;可以多人; 可以自定义消息,消息支持HTML格式的;具体的发送操作还需要用户完成
而且如果在苹果系统中,如果彼此的手机都是iOS设备,并且开通了iMessage功能,彼此之间的短信是走网络通道,而不走运营商的通道!
(1)提供了操作界面
(2)使用前必须检查canSendText方法,若返回NO则不应将这个controller展现出来,而应该提示用户不支持发送短信功能.
(3)界面不能自行定制
(4)要发送的短信的内容(body)和收件人(recipients)在展现这个controller前需初始化好,展现了之后短信内容不能通过程序来进行修改.不过用户仍然可以手工修改短信内容和选择收件人
(5)用户点了发送或者取消,或者发送失败时,MFMessageComposeViewControllerDelegate 的– messageComposeViewController:didFinishWithResult: 方法都能得到通知,在这里进行相应的处理
MessageUI框架 创建一个基于视图控制器的用户界面,用来构建email SMS信息。在这种情况下,可以使用它,即让用户在不离开应用的条件下创建email SMS信息。
该框架包含两个类和两个协议,与SMS相关的有两个,与email相关的两个,这里只介绍SMS:
MFNessageComposeViewController,为编辑信息提供了标准的系统用户接口。使用该类取配置初始的接收者和信息,如果愿意,去配置一个委托对象,来对发送短信的最终结果做出回应,无论是他们选择取消或是发送该消息。配置完初始值,使用presentModalViewController :animated方法呈现模式视图控制器,完成之后,使用dismissModalViewControllerAnimated:方法撤销该视图。
MFMessageComposeViewControllerDelegate,该协议定义了一个单一的方法,使用该方法对sms信息编辑结束后作出回应。该方法包括用户是否选择发送或是取消sms的信息,以及是否尝试发送失败。
备注:iOS4.0之后的才支持程序内发送短信,即增加该框架之后
代码示例:
- (IBAction)showSMSPicker:(id)sender
{
// You must check that the current device can send SMS messages before you
// attempt to create an instance of MFMessageComposeViewController. If the
// device can not send SMS messages,
// [[MFMessageComposeViewController alloc] init] will return nil. Your app
// will crash when it calls -presentViewController:animated:completion: with
// a nil view controller.
//NSClassFromString gain the class with the name
Class messageClass = (NSClassFromString(@"MFMessageComposeViewController"));
if (messageClass) {
if ([MFMessageComposeViewController canSendText])
// The device can send sms.
{
[self displaySMSComposerSheet];
}
else
// The device can not send SMS.
{
self.feedbackMsg.hidden = NO;//在一个label上显示结果
self.feedbackMsg.text = @"Device not configured to send SMS.";
}
}else{
self.feedbackMsg.hidden = NO;
self.feedbackMsg.text = @"iOS's version too low, sending sms in pragram is supported iOS4.0 and later";
}
}
#pragma mark - Compose Mail/SMS
// -------------------------------------------------------------------------------
// displaySMSComposerSheet
// Displays an SMS composition interface inside the application.
// -------------------------------------------------------------------------------
- (void)displaySMSComposerSheet
{
MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];
picker.messageComposeDelegate = self;
// You can specify one or more preconfigured recipients. The user has
// the option to remove or add recipients from the message composer view
// controller.
picker.recipients = @[@"10010",@"10086"];
// You can specify the initial message text that will appear in the message
// composer view controller.
picker.body = @"Hello from California!";
[self presentViewController:picker animated:YES completion:NULL];//显示系统SMS界面
// [self presentModalViewController:picker animated:YES];//老套的方法
}
#pragma mark - Delegate Methods
// -------------------------------------------------------------------------------
// messageComposeViewController:didFinishWithResult:
// Dismisses the message composition interface when users tap Cancel or Send.
// Proceeds to update the feedback message field with the result of the
// operation.
//实现该委托协议,对发送结果进行反馈
// -------------------------------------------------------------------------------
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result
{
self.feedbackMsg.hidden = NO;
// Notifies users about errors associated with the interface
switch (result)
{
case MessageComposeResultCancelled:
self.feedbackMsg.text = @"Result: SMS sending canceled";
break;
case MessageComposeResultSent:
self.feedbackMsg.text = @"Result: SMS sent";
break;
case MessageComposeResultFailed:
self.feedbackMsg.text = @"Result: SMS sending failed";
break;
default:
self.feedbackMsg.text = @"Result: SMS not sent";
break;
}
//最后解除SMS的系统发送界面,返回原app
[self dismissViewControllerAnimated:YES completion:NULL];
}
对于发送短息,可定义发送内容和接收方的号码。但有一个问题,都是调用短信发送界面,需要用户点击发送才行
由于苹果对安全性的要求很高,所以暂时无法脱离其原生viewcontroller来发送短信,即无法后台发送短信
对于网上一些实现后台发送SMS,甚至是定时发送的app,可能是设置的时候传递到后台服务器,然后后台服务器根据设置发送短信的。 目前来说,iphone上是不可能后台发送的。