1. 程式人生 > >iOS關於系統簡訊和電話的呼叫

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 ([[UIApplicationsharedApplicationopenURL:[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 choose

    NSMutableString *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方法,若返回NOcontroller出來,應該提示用不支援送簡訊功能.

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上是不可能後臺送的。