如何在IOS5上收到“kCTMessageReceivedNotification”通知时获取消息

使用ios4.x,我可以使用下面的代码来获取消息,当得到“kCTMessageReceivedNotification”通知

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是零,所以我能做些什么来获得消息?

谢谢

这是我发现的…

只要看看转储的私有API,它看起来像ChatKit.framework可以帮助。 看看CKSMSService.h

或用于iMessage消息的CKMadridService.h 。

我确实很快尝试在CKSMSServiceCKSMSService我自己的方法:

 - (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数据库中获取消息。 请注意…我没有构build完整的应用程序,以注册通知。 我假设你的代码得到kCTMessageReceivedNotification是好的…它只是不会给你的短信内容了。 因此,如果将以下代码放入通知处理程序中,则应该能够看到消息文本:

 - (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; } 

现在,确保这个应用程序安装在/ Applications /中 。 如果你只是build立这个应用程序,并正常安装与Xcode,你会得到一个权限拒绝打开sqlite数据库的错误,因为应用程序沙箱。

我的代码片段只是获取最新的文本内容。 这里是一个用数据库做更多的例子 。 查看QuerySMS方法。

另外,这里是sms.db 数据库格式的链接 。 你可以在那里find你需要的东西。 或者,只需将sms.db复制到您的计算机上,然后使用Firefox SQLiteManager插件进行浏览即可 。 祝你好运!

更新: 我发布在iOS上的多进程SQLite线程安全问题的一些信息

你可以参考下面的链接

  1. http://tech.ruimaninfo.com/?p=83

  2. http://www.ifans.com/forums/threads/coretelephony-cttelephonycenterremoveobserver.232745/

  3. 如何在iPhone越狱+代码中阻止传入的短信

  4. IOS越狱如何拦截短信/短信

我pipe理一个非越狱的iOS8设备上的最后一条消息:

  1. ChatKit标题获取CKDBMessage.h并将该文件添加到您的项目。
  2. 通过CTTelephonyCenterAddObserver注册到CTTelephonyCenterAddObserver
  3. 使用此function获取最后收到的消息的信息:

     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); }