Программное создание SMS в Inbox на Symbian C++


Symbian C++ позволяет
создавать произвольные SMS сообщения не только в папках Outgoing, Sent и Draft, но и в папке Inbox службы
сообщений. Как может показаться, необходимость в подобной операции может возникнуть
лишь в том случае, если Вы создаете программу шутку, создающую входящие SMS с заданным текстом от
абонентов, которые на самом деле вам ничего не посылали. Это не так. Главной
причиной необходимости применения программного создания SMS является использование SMS Utilities API. Это API позволяет
перехватывать все поступающие сообщения на уровне сокета, до того как они
попадут в службу сообщений. Таким образом, удается реализовать абсолютно “невидимый”
пользователю обмен сообщениями и даже программный файерволл для входящих
сообщений. К сожалению, перехваченные сообщения вне зависимости от того,
пригодились они вам или нет, уже не попадут в службу сообщений, а значит
ответственность за их создание на устройстве ложится на плечи разработчика.

 

Приведенный ниже пример позволяет создать SMS сообщение в
папке Inbox с заданным содержимым, временем поступления и отправителем.

 

Нам понадобятся два класса: CSMSHandler – создающий
сообщение и CPhoneBookHandler – класс, единственной функцией которого является поиск имени
отправителя в контактной книге по его номеру (ведь если сообщение пришло с
известного номера – в качестве отправителя отображается имя из контактной
книги).

 

Рассмотрим CSMSHandler.
Для начала нам нужно создать канал связи с сервером сообщений, поэтому мы
объявим членом класса CMsvSession* iSession. Устанавливать связь можно
синхронным и асинхронным способом с помощью методов OpenSyncL() и OpenAsyncL().
На практике обычно используется асинхронный способ, его мы и рассмотрим.
Несмотря на то, что открытие сессии происходит асинхронно, механизм активных
объектов при этом не используется. Поэтому наш класс будет порожден от CBase, а не от CActive. Оба OpenXXX метода
требуют в качестве аргумента ссылку на объект MMsvSessionObserver. Этот обозреватель (Примесь, Mixin-класс) имеет метод для получения уведомления о событиях от сервера сообщений, и мы
добавим ее в наш класс CSMSHandler. Об успешном открытии сессии с сервером
сообщений нас уведомят, вызвав метод класса MMsvSessionObserver
с параметром
TMsvSessionEvent::EMsvServerReady.

 

После того, как сессия будет успешно открыта, мы создадим
экземпляры классов CClientMtmRegistry (реестр MTM-клиентов) и CSmsClientMtm (SMS MTM-клиент) следующим образом:

 

iMtmRegistry
= CClientMtmRegistry::NewL( *iSession );

iSmsMtm =
STATIC_CAST( CSmsClientMtm*, iMtmRegistry->NewMtmL( KUidMsgTypeSMS ) );

 

iMtmRegistry
и iSmsMtm должны быть
членами класса.

Это все, что нужно для инициализации CSMSHandler. Теперь наш класс должен
выглядеть следующим образом:

 

Объявление класса

 

 

class
CSmsHandler : public CBase, public MmsvSessionObserver

{

    public: // Двухфазный конструктор и
деструктор

 

        static CSmsHandler* NewL();

 

 

        static CSmsHandler* NewLC();

 

 

        virtual ~CSmsHandler();

 

    public:

   

        void HandleSessionEventL(
TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3 );

    private: // Конструкторы

 

        CSmsHandler();

 

        void ConstructL();

 

  

    private:

        void AccessMtmL();  

 

    private: // Члены класса

 

        CMsvSession* iSession;

        CClientMtmRegistry* iMtmRegistry;

        CSmsClientMtm* iSmsMtm;

    };

 

И реализация:

 

#include
"smshandler.h"

 

 

CSmsHandler::CSmsHandler()

{

}

 

void
CSmsHandler::ConstructL()

{

    iSession = CMsvSession::OpenAsyncL( *this
);

}

 

CSmsHandler*
CSmsHandler::NewL()

{

    CSmsHandler* self = NewLC();

    CleanupStack::Pop( self );

    return self;

}

 

CSmsHandler*
CSmsHandler::NewLC()

{

    CSmsHandler* self = new ( ELeave )
CSmsHandler();

    CleanupStack::PushL( self );

    self->Const