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

时间:2022-10-24 21:05:33

With ios4.x I can use code below to get the message when get the "kCTMessageReceivedNotification" notification

使用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];}

But with ios5 I can't do it as incMsg is nil,so what can i do to get the message?

但是对于ios5我不能这样做,因为incMsg是零,所以我能做些什么来获取消息?

Thanks

3 个解决方案

#1


8  

Here's what I found ...

这是我发现的......

Just looking at the dumped private APIs, it looks like ChatKit.framework could help. Take a look at CKSMSService.h

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

or CKMadridService.h for iMessage messages.

或者用于iMessage消息的CKMadridService.h。

I did quickly attempt to swizzle my own method in, for a couple methods in CKSMSService:

对于CKSMSService中的几个方法,我很快就尝试了自己的方法:

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

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

but on iOS 5.0.1 I didn't see either of those get called (maybe my error?). So, I tried to just get the message directly from the sqlite SMS database. Note ... I didn't build the full app, to register for notifications. I'm assuming your code to get the kCTMessageReceivedNotification is ok ... it just doesn't give you the SMS content anymore. So, if you put the following code in your notification handler, you should be able to see the message text:

但在iOS 5.0.1上,我没有看到其中任何一个被调用(也许是我的错误?)。所以,我试图直接从sqlite SMS数据库中获取消息。注意...我没有构建完整的应用程序,注册通知。我假设你的代码让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;
}    

Now, make sure this app is installed in /Applications/. If you just build this app, and install normally with Xcode, you'll get a permission denied error opening the sqlite database, because of app sandboxing.

现在,确保此应用程序安装在/ Applications /中。如果您只是构建此应用程序,并使用Xcode正常安装,那么由于应用程序沙盒,您将获得打开sqlite数据库的权限被拒绝错误。

My code snippet just gets the most recent text content. Here's an example of doing a little more with the database. Look at the QuerySMS method.

我的代码段只是获取最新的文本内容。以下是使用数据库进行更多操作的示例。查看QuerySMS方法。

Also, here's a link on the database format of sms.db. You can find what else you need in there. Or, just copy the sms.db to your computer, and browse it with something like the Firefox SQLiteManager plugin. Good luck!

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

Update: some information from a question I posted on multi-process SQLite thread safety on iOS

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

#2


1  

You can refer below links

您可以参考以下链接

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

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

  3. How to block incoming SMS in iPhone jailbreak + code

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

  4. IOS Jailbreak How do intercept SMS / Text Messages

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

#3


1  

I manged to get the last message on a non-jailbroken iOS8 device:

我想在非越狱的iOS8设备上获取最后一条消息:

  1. Get CKDBMessage.h from ChatKit headers and add the file to your project.
  2. 从ChatKit头获取CKDBMessage.h并将该文件添加到项目中。

  3. Sign up to kCTMessageReceivedNotification through CTTelephonyCenterAddObserver
  4. 通过CTTelephonyCenterAddObserver注册kCTMessageReceivedNotification

  5. Use this function to get the info of the last received message:

    使用此函数可获取上次收到的消息的信息:

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

#1


8  

Here's what I found ...

这是我发现的......

Just looking at the dumped private APIs, it looks like ChatKit.framework could help. Take a look at CKSMSService.h

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

or CKMadridService.h for iMessage messages.

或者用于iMessage消息的CKMadridService.h。

I did quickly attempt to swizzle my own method in, for a couple methods in CKSMSService:

对于CKSMSService中的几个方法,我很快就尝试了自己的方法:

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

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

but on iOS 5.0.1 I didn't see either of those get called (maybe my error?). So, I tried to just get the message directly from the sqlite SMS database. Note ... I didn't build the full app, to register for notifications. I'm assuming your code to get the kCTMessageReceivedNotification is ok ... it just doesn't give you the SMS content anymore. So, if you put the following code in your notification handler, you should be able to see the message text:

但在iOS 5.0.1上,我没有看到其中任何一个被调用(也许是我的错误?)。所以,我试图直接从sqlite SMS数据库中获取消息。注意...我没有构建完整的应用程序,注册通知。我假设你的代码让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;
}    

Now, make sure this app is installed in /Applications/. If you just build this app, and install normally with Xcode, you'll get a permission denied error opening the sqlite database, because of app sandboxing.

现在,确保此应用程序安装在/ Applications /中。如果您只是构建此应用程序,并使用Xcode正常安装,那么由于应用程序沙盒,您将获得打开sqlite数据库的权限被拒绝错误。

My code snippet just gets the most recent text content. Here's an example of doing a little more with the database. Look at the QuerySMS method.

我的代码段只是获取最新的文本内容。以下是使用数据库进行更多操作的示例。查看QuerySMS方法。

Also, here's a link on the database format of sms.db. You can find what else you need in there. Or, just copy the sms.db to your computer, and browse it with something like the Firefox SQLiteManager plugin. Good luck!

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

Update: some information from a question I posted on multi-process SQLite thread safety on iOS

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

#2


1  

You can refer below links

您可以参考以下链接

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

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

  3. How to block incoming SMS in iPhone jailbreak + code

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

  4. IOS Jailbreak How do intercept SMS / Text Messages

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

#3


1  

I manged to get the last message on a non-jailbroken iOS8 device:

我想在非越狱的iOS8设备上获取最后一条消息:

  1. Get CKDBMessage.h from ChatKit headers and add the file to your project.
  2. 从ChatKit头获取CKDBMessage.h并将该文件添加到项目中。

  3. Sign up to kCTMessageReceivedNotification through CTTelephonyCenterAddObserver
  4. 通过CTTelephonyCenterAddObserver注册kCTMessageReceivedNotification

  5. Use this function to get the info of the last received message:

    使用此函数可获取上次收到的消息的信息:

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