This concludes the previous post on how to use RSendAsMessage to send an email.
With the first post, doing it the simple way causes lots of problems and has many corner cases that it turned out the only way to do it successfully is to do it properly - like everything else in Symbian.
One of the more annoying things is that the SMTP MTM seems to report it cannot send an email, and only when you force it does it actually load the mtm and query the capabilties, that it can in fact send emails. So this makes the AvailableAccountsL function effectivly useless to get all the mtm accounts, so we need to dig deeper and use the raw messaging API's to get the true list of accounts (uugh!)
So from a simple implementation which was supposed to utilize the RSendAs API's to hide the complexity of the messaging server we end up having to write a complex method using the the raw messaging API's....
First we create a structure to hold the name of the mtm and its account id as well as an array to hold this data struct TAccountInfo { TInt32 iId; TBuf<32> iAccountName; }; typedef RArray<TAccountInfo> RAccountInfo;
The next is the uid of the email technology group. The MTM subsystem utilizes different technology groups to define how the MTM is to appear in the messaging server and how it is generally expected to perform. const TUid KUidMsvTechnologyGroupEmail = {0x10001671};
Finally we need a dummy class to absorb the events from the messaging server. Possibly we should check from errors here and store them in case any callback fails, but for now we just ignore after all what could possibly go wrong :) class TDummyObserver: public MMsvSessionObserver { public: void HandleSessionEventL(TMsvSessionEvent, TAny*, TAny*, TAny*) {}; };
Now we have intialized the variables and classes, we can get the account information // Open a session to the messaging server TDummyObserver obs; CMsvSession* session = CMsvSession::OpenSyncL(obs); CleanupStack::PushL(session);
// Now get the list of Client MTM's installed on the device // by asking the mtm session for the list. CClientMtmRegistry* registry = CClientMtmRegistry::NewL(*session); CleanupStack::PushL(registry);
// Enumerate the client mtm's and check its an email technology mtm and it has at least one account. // Also remember to ensure the mtm can send a message!! very important! const TInt count = registry->NumRegisteredMtmDlls(); for (TInt i=0; i < count; i++) { const TUid uid = registry->MtmTypeUid(i);
// Check to see the mtm is an email mtm if (registry->TechnologyTypeUid(uid) == KUidMsvTechnologyGroupEmail) { // Create a client side MTM for the specified UID // this is so we can get whether or not the MTM // is one that can send a message CBaseMtm* mtm = registry->NewMtmL(uid); CleanupStack::PushL(mtm);
// Now check to see if the MTM can send a message TInt response = KErrNone; if (mtm->QueryCapability(KUidMtmQueryCanSendMsg, response) == KErrNone) { // As its an email mtm that can send message add all the accounts associated with the mtm // We get the root entry for the MTM and then get all children under the root // that match the mtm const TMsvSelectionOrdering order(KMsvNoGrouping, EMsvSortByDetails, ETrue); CMsvEntry* entry = CMsvEntry::NewL(*session, KMsvRootIndexEntryId, order); CleanupStack::PushL(entry); entry->SetEntryL(KMsvRootIndexEntryId); CMsvEntrySelection* selection = entry->ChildrenWithMtmL(uid); CleanupStack::PushL(selection);
// Now we can get the details for the accounts in the mtm const TInt entryCount = selection->Count(); for (TInt j=0; j < entryCount; j++) { entry->SetEntryL(selection->At(j));
// Save the id of the account in the messaging server // and its associated name TAccountInfo info; info.iId = entry->EntryId(); info.iAccountName = entry->Entry().iDetails.Left(info.iAccountName.MaxLength()); User::LeaveIfError(aAccountInfo.Append(info)); }
CleanupStack::PopAndDestroy(2, entry); // entry and selection } CleanupStack::PopAndDestroy(mtm); } }
There we have it, a way to select an email account to send a message with using the RSendAs API
Finally we can send the message, aAccountId is on of the iId field of the accounts collected above.
// Open a session RSendAs session; User::LeaveIfError(session.Connect()); CleanupClosePushL(session);
// Now create a message, using the send as API RSendAsMessage message; message.CreateL(session, aAccountId); CleanupClosePushL(message); message.SetBodyTextL(_L("Body")); message.SetSubjectL(_L("Subject")); message.AddRecipientL(_L("fred.smith@nowhere.com"), _L(""), RSendAsMessage::ESendAsRecipientTo);
// Now launch the editor and close the message // and session. message.LaunchEditorAndCloseL();