Вопрос по ios5, iphone – как получить сообщение при получении уведомления «kCTMessageReceivedNotification» на IOS5

7

С 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 равен нулю, так что я могу сделать, чтобы получить сообщение?

Благодарност

yeah, я вижу это сообщение "unknown CommCenter [31] <Notice>: удаление полученного сообщения 2147483648", всплывающее перед тем, как мой обработчик уведомлений запускается. Это похоже на то, что сообщения очищаются, как только (новый iOS 5) центр уведомлений получает их. Я тоже пробовал звонить[mc allIncomingMessages] и там было совершенно пусто. Nate
Тогда ты знаешь, как я могу получить сообщение? Я не решил это. Спасибо. dustdn

Ваш Ответ

3   ответа
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 все в порядке ... просто не дает тебе смс Содержание больше. Таким образом, если вы добавите следующий код в обработчик уведомлений, вы сможете увидеть текст сообщения:

- (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 из-за изолированной среды приложения.

Мой фрагмент кода получает только самый последний текстовый контент. Вот пример немного больше с базой данных. Посмотрите наQuerySMS метод.

Также вот вам ссылка на формат базы данных of Sms.db. Вы можете найти то, что вам нужно там. Или просто скопируйте файл sms.db на свой компьютер и найдите что-то вродеFirefox плагин SQLiteManager. Удачи

Обновить некоторая информация от вопрос, который я написал о многопроцессной безопасности потоков SQLite на iOS

Большое спасибо. Я попробую. dustdn
@ dustdn, Кроме того, так как я создал только половину приложения, которое не работало для вас (получение смс-контента), я не уверен на 100%, есть ли проблемы с синхронизацией, если вы используете этот код сразу после получения уведомление. Я до сих пор не уверен на 100%, является ли sqlite поточно-ориентированным на iOS. Я запустил кодint safe = sqlite3_threadsafe(); и вернул ненулевой результат (2), но я не уверен, что это означает, что он потокобезопасен. В любом случае, вам может потребоваться небольшая задержка или просмотр возвращаемого значения вызовов sqlite для проверки наSQLITE_MISUSE, который, я думаю, будет указывать на проблемы безопасности потоков. Nate
Если это полезно, я полагаю, что вы можете активировать этот код, используя эквивалент iOS. из опции «WatchPaths» в Mac OS X для launchdaemon и запуска только содержимого в каталоге (то есть в каталоге SMS). Я не проверял это (я использовал задание cron), но нашел ссылку с примером кода: Developer.apple.com / библиотека / ИОС / # samplecode / DocInteraction / ... Orwellophile
@ Нейт, хороший ответ, быстрый вопрос, хотя полиция Apple разрешит приложению, которое может читать тексты пользователей на рынке, предполагая, что это только часть большего приложения, а не целое приложение? Dnaso
@ Dnaso,е @ нет, но это даже не имеет значения. Это даже не будет работать должным образом в приложении App Store, потому что приложения магазина приложений являются Песочницы, установлен в/var/mobile/Applications. Они не смогут прочитать файл sms.db. Так что дело не только в том, что позволят обозреватели Apple. Ограничение является техническим. Nate
1

рейка:

ПолучитьCKDBMessage.h отChatKit заголовки и добавьте файл в ваш проект. Зарегистрируйтесь доkCTMessageReceivedNotification черезCTTelephonyCenterAddObserver

Используйте эту функцию, чтобы получить информацию о последнем полученном сообщении:

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);
}
Можете ли вы поделиться проектом на git hub? Где найти CKDBMessage.h и как подписаться на "kCTMessageReceivedNotification" Durgaprasad
Это все еще работает на iOS 7, но я обнаружил, что вам нужна небольшая задержка после получения уведомления kCTMessageReceivedNotification. В противном случае вы пропустите полученное SMS. Я использую задержку в 0,1 сек с [self executeSelector .. afterDelay: 0.1]; RickJansen

Похожие вопросы