iOS關於系統簡訊和電話的呼叫
在網上搜索很多資料和帖子,也看了蘋果的開發文件,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";
}
elseif (call.callState == CTCallStateConnected)
{
//呼叫被完全建立的狀態
NSLog(@"Call has just been connected");
self.feedbackMsg.text = @"Call has just been connected";
}
elseif(call.callState == CTCallStateIncoming)
{
//在連線建立之前,有來電但還未被接聽
NSLog(@"Call is incoming");
self.feedbackMsg.text = @"Call is incoming";
}
elseif (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 ([[UIApplicationsharedApplication] openURL:[NSURLURLWithString:@"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 = [[NSMutableStringalloc] initWithFormat:@"tel:%@",@"10086"];
UIWebView *callWebView = [[UIWebView alloc] init];
[callWebView loadRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:str]]];
[self.view addSubview:callWebView];
}
}
方法3,這種方法也會回去到原來的程式裡(注意這裡的telprompt,蘋果的私有協議,app無法上架),也會彈出提示,需要使用者確認
- (IBAction)sendMail:(id)sender {//3 can return the app ,show a alert to choose
NSMutableString *str = [[NSMutableStringalloc] initWithFormat:@"telprompt://%@",@"10086"];
NSLog(@"str:%@",str);
[[UIApplicationsharedApplication] openURL:[NSURLURLWithString:str]];
}
2 系統呼叫SMS
(1)接收簡訊
獲取接收簡訊的資訊不確定,目前不能,目前瞭解的是沒有越獄的iphone裝置無法獲取收到的簡訊資訊。 越獄的iphone可以獲取簡訊內容和發件人號碼。
(2)傳送簡訊
方法1:——URL 程式碼簡單,但只是跳轉到系統介面,可以設定傳送簡訊的號碼,但不能設定內容,也不能返回原app
//呼叫發簡訊功能,不能返回原app
- (IBAction)sendSMS:(id)sender {
if ([[UIApplicationsharedApplication] openURL:[NSURLURLWithString:@"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 ([MFMessageComposeViewControllercanSendText])
// The device can send sms.
{
[selfdisplaySMSComposerSheet];
}
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 = [[MFMessageComposeViewControlleralloc] 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!";
[selfpresentViewController:picker animated:YEScompletion: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)
{
caseMessageComposeResultCancelled:
self.feedbackMsg.text = @"Result: SMS sending canceled";
break;
caseMessageComposeResultSent:
self.feedbackMsg.text = @"Result: SMS sent";
break;
caseMessageComposeResultFailed:
self.feedbackMsg.text = @"Result: SMS sending failed";
break;
default:
self.feedbackMsg.text = @"Result: SMS not sent";
break;
}
//最後解除SMS的系統傳送介面,返回原app
[selfdismissViewControllerAnimated:YEScompletion:NULL];
}
對於傳送短息,可定義傳送內容和接收方的號碼。但有一個問題,都是呼叫簡訊傳送介面,需要使用者點擊發送才行
由於蘋果對安全性的要求很高,所以暫時無法脫離其原生viewcontroller來發送簡訊,即無法後臺傳送簡訊
對於網上一些實現後臺傳送SMS,甚至是定時傳送的app,可能是設置的時候傳遞到後臺服務器,然後後臺服務器根據設置發送簡訊的。 目前來說,iphone上是不可能後臺發送的。