2012-05-21 75 views
7

收到「kCTMessageReceivedNotification」通知時,隨着ios4.x我可以使用下面的代碼來獲取消息時得到了「kCTMessageReceivedNotification」通知得到的消息如何在IOS5

CTTelephonyCenterAddObserver(ct, NULL, callback,NULL,NULL, CFNotificationSuspensionBehaviorHold); 

if ([notifyname isEqualToString:@"kCTMessageReceivedNotification"])//receive message 
    { 

     NSDictionary *info = (NSDictionary *)userInfo; 
     CFNumberRef msgID = (CFNumberRef)[info objectForKey:@"kCTMessageIdKey"]; 
     int result; 
     CFNumberGetValue((CFNumberRef)msgID, kCFNumberSInt32Type, &result); 
     Class CTMessageCenter = NSClassFromString(@"CTMessageCenter"); 
     id mc = [CTMessageCenter sharedMessageCenter]; 
     id incMsg = [mc incomingMessageWithId: result];} 

但隨着iOS5的,我可以」因爲incMsg是零,所以我能做些什麼來獲得消息?

感謝

+0

是的,我看到這條消息「未知CommCenter [31] :刪除收到的消息2147483648「在我的通知處理程序運行之前彈出。它就像(新的iOS 5)通知中心獲取它們時消息一樣被清除。我也試着調用'[mc allIncomingMessages]',它完全是空的。 – Nate

+0

那你知道我怎麼能得到這個消息嗎?我沒有解決它。謝謝。 – dustdn

回答

8

這裏是我的發現......

只看傾銷私有的API,它看起來像ChatKit.framework可能會有幫助。看看 CKSMSService.h

CKMadridService.h爲iMessage消息。

我也趕緊嘗試調酒我自己的方法,爲CKSMSService幾個方法:

- (void)_receivedMessage: (id)arg1 replace:(BOOL)arg2 replacedRecordIdentifier:(int)arg3 postInternalNotification:(BOOL)arg4; 

- (void)_receivedMessage: (id)arg1 replace:(BOOL)arg2 postInternalNotification:(BOOL)arg3; 

但在iOS 5.0.1,我沒有看到任何那些被調用(也許我的錯誤? )。所以,我試圖直接從sqlite SMS數據庫中獲取消息。請注意...我沒有構建完整的應用程序以註冊通知。我假設你的代碼得到kCTMessageReceivedNotification是好的...它只是不會給你SMS 內容了。所以,如果你把下面的代碼在您的通知處理程序,你應該能夠看到消息文本:

- (NSString *) mostRecentSMS { 
    NSString *text = @""; 

    sqlite3 *database; 
    if(sqlite3_open([@"/private/var/mobile/Library/SMS/sms.db" UTF8String], &database) == SQLITE_OK) { 
     sqlite3_stmt *statement; 

     // iOS 4 and 5 may require different SQL, as the .db format may change 
     const char *sql4 = "SELECT text from message ORDER BY rowid DESC"; // TODO: different for iOS 4.* ??? 
     const char *sql5 = "SELECT text from message ORDER BY rowid DESC"; 

     NSString *osVersion =[[UIDevice currentDevice] systemVersion];   
     if([osVersion hasPrefix:@"5"]) { 
      // iOS 5.* -> tested 
      sqlite3_prepare_v2(database, sql5, -1, &statement, NULL); 
     } else { 
      // iOS != 5.* -> untested!!! 
      sqlite3_prepare_v2(database, sql4, -1, &statement, NULL); 
     } 

     // Use the while loop if you want more than just the most recent message 
     //while (sqlite3_step(statement) == SQLITE_ROW) { 
     if (sqlite3_step(statement) == SQLITE_ROW) { 
      char *content = (char *)sqlite3_column_text(statement, 0); 
      text = [NSString stringWithCString: content encoding: NSUTF8StringEncoding]; 
      sqlite3_finalize(statement); 
     } 

     sqlite3_close(database); 
    } 
    return text; 
}  

現在,確保這個程序是安裝在/應用/。如果你只是建立這個應用程序,並正常使用Xcode進行安裝,由於應用程序沙盒,你將會得到一個權限拒絕打開sqlite數據庫的錯誤。

我的代碼片段只是獲取最新的文本內容。 Here's an example of doing a little more with the database。看看QuerySMS方法。

另外,這裏是link on the database formatsms.db。你可以在那裏找到你需要的東西。或者,只需將sms.db複製到您的計算機上,然後像Firefox SQLiteManager plugin一樣瀏覽它。祝你好運!

更新:question I posted on multi-process SQLite thread safety on iOS

+0

非常感謝。我會試一試。 – dustdn

+0

@dustdn此外,由於我只構建了一半不適合您的應用程序(獲取短信內容),因此如果您在收到電子郵件後立即使用此代碼,我不能100%確定是否存在計時問題通知。我仍然沒有100%清楚sqlite是否在iOS上是線程安全的。我運行了代碼'int safe = sqlite3_threadsafe();'並返回了一個非零的結果(2),但我不確定這意味着它是線程安全的。無論如何,您可能需要使用一點延遲,或者觀察sqlite調用的返回值以檢查「SQLITE_MISUSE」,我認爲這會表示線程安全問題。 – Nate

+1

如果有幫助,我相信你可以使用iOS equiv來觸發該代碼。用於launchdaemon的Mac OS X的「WatchPaths」選項,並且僅啓動目錄中的內容(即SMS目錄)被更改。我沒有測試過它(我使用了一個cron作業),但是我找到了一些示例代碼的鏈接:http://developer.apple.com/library/ios/#samplecode/DocInteraction/Listings/Classes_DirectoryWatcher_m.html – Orwellophile

1

一些信息,我manged得到一個非越獄iOS8上的設備上的最後一條消息:

  1. 獲取CKDBMessage.hChatKit頭和文件添加到您的項目。
  2. 註冊到kCTMessageReceivedNotification通過CTTelephonyCenterAddObserver
  3. 使用此功能來獲得最後收到的消息的信息:

    void SmsReceived() 
    { 
        NSLog(@"GOT SMS"); 
    
        //open IMDPersistence framework 
        void *libHandle =  dlopen("/System/Library/PrivateFrameworks/IMDPersistence.framework/IMDPersistence", RTLD_NOW); 
    
        //make/get symbol from framework + name 
        IMDMessageRecordGetMessagesSequenceNumber = (int (*)())dlsym(libHandle, "IMDMessageRecordGetMessagesSequenceNumber"); 
    
        // get id of last SMS from symbol 
        int lastID = IMDMessageRecordGetMessagesSequenceNumber(); 
        NSLog(@"%d", lastID); 
    
        // close (release?) framework -> needed?? 
        dlclose(libHandle); 
    
    
        // get message object 
        dlopen("/System/Library/PrivateFrameworks/ChatKit.framework/ChatKit", RTLD_LAZY); 
        Class CKDBMessageClass = NSClassFromString(@"CKDBMessage");// objc_getClass("CKDBMessage"); 
        CKDBMessage *msg = [[CKDBMessageClass alloc] initWithRecordID:lastID]; 
    
        NSString *text = msg.text; 
        NSLog(@"text: %@", text); 
    } 
    
+0

你可以請共享項目在git樞紐?在哪裏可以找到CKDBMessage.h以及如何註冊「kCTMessageReceivedNotification」 – Durgaprasad

+0

這仍然適用於iOS 7,但是我發現您在收到kCTMessageReceivedNotification通知後需要稍微延遲。否則你會錯過剛收到的短信。我使用0.1秒的延遲,[self performSelector .. afterDelay:0.1]; – RickJansen