[Update by Artem: This code example has been submitted by Michele. I included the code excerpt into the post. Artem]
The following example allows for using the text to speech in Nokia S60 3rd edition phones. See also the 2nd edition text to speech example
...
void CTtsPlayer::ConstructL()
{
iPlayer = CMdaAudioPlayerUtility::NewL( *this );
iWaiter = new (ELeave) CActiveSchedulerWait;
}
void CTtsPlayer::PlayTextL( TDesC& aText )
{
__ASSERT_ALWAYS( iPlaybackInProgress == EFalse,
User::Leave( KErrNotReady ) );
HBufC8* playableText = HBufC8::NewLC( aText.Length() +
KTtsPrefix().Length() );
playableText->Des().Append( KTtsPrefix );
playableText->Des().Append( aText );
iPlayer->OpenDesL( *playableText );
iPlaybackInProgress = ETrue;
iWaiter->Start();
// At this point playback is already completed or failed
User::LeaveIfError( iErr );
CleanupStack::PopAndDestroy( playableText );
}
...
Hi there,
You can use this code to run EXE files from your application:
RProcess server;
server.Create(KServerName, KNullDesC);
CApaCommandLine* commandLine = CApaCommandLine::NewL();
commandLine->SetExecutableNameL(KExecutableName);
commandLine->SetProcessEnvironmentL(server);
RApaLsSession ApaSession;
ApaSession.Connect();
ApaSession.StartApp(*commandLine);
ApaSession.Close();
delete commandLine;
Every object allocated on the heap should be protected by pushing its pointer to the cleanup stack via CleanupStack::PushL. Kernel resources used by the R-objects like RPointerArray are protected via CleanupClosePushL.
Sometimes you’d like or have to protect all the RPointerArray content without pushing all the individual items to the cleanup stack. There are custom solutions for this purpose, but there is also a built-in facility – CleanupResetAndDestroyPushL. It is not well known and not widely used only because it is defined in a quite an unusual place - \epoc32\include\mmf\common\mmfcontrollerpluginresolver.h
Here is how you can programmatically create a new phonebook contact. This code example is the universal ExeDll – it can be compiled both for S60 2nd edition and for S60 3rd edition. Note that for 3rd edition the WriteUserData capability is needed to add the contact to the phonebook. If the program didn’t have this capability, the CPbkContactEngine::AddNewContactL would leave with KErrWrite.
Update: "new (ELeave) RStringArray" was missing the "ELeave" (thanks to Tote)
Lately I worked with the API that required passing the RPointerArray allocated on the heap so that ownership was passed to that API. It is quite a rare case, but demonstrates nicely how tricky the CleanupStack protection can sometimes be. Note the order of pushing to the cleanup stack. If CleanupClosePushL was called first and leave happened during the CleanupStack::PushL, memory leak would occur.
// Local Functions
typedef RPointerArray RStringArray;
...
HBufC* element1 = HBufC::NewLC( 10 );
HBufC* element2 = HBufC::NewLC( 20 );
RStringArray* array = new (ELeave) RStringArray;
// Protect the allocated heap mem
CleanupStack::PushL( array );
// Protect the kernel handle/array contents
CleanupClosePushL( *array );
array->AppendL( element1 );
array->AppendL( element2 );
CleanupStack::PopAndDestroy( array ); // Close the array
CleanupStack::PopAndDestroy( array ); // And free the heap mem
...
Compilable code example of using the Symbian Streaming API. Demonstrates how to store the whole object with the boolean, integer and descriptor data fields to and from stream.
// Let the data format be:
//
//
// Note, that when dealing with packaged data, we have to be careful about
// the concrete size in bytes. Descriptors will be saved using Symbian
// default format for descriptors. For TBool we use the default conversion
// to TInt
void CEmployee::ExternalizeL( RWriteStream &aStream ) const
{
// Write the used protocol version first
aStream << KEmployeeProtocolVersion;
aStream << static_cast ( iAge );
aStream << static_cast ( iFired );
aStream << static_cast ( iName->Length() );
aStream << *iName;
aStream << static_cast ( iSurname->Length() );
aStream << *iSurname;
}
ExeDlls are the targets for Symbian projects that make the projects compile into EXE for the hardware platform and into a special DLL, that can be launched as an EXE from the WINS emulator.
For S60 3rd edition EXEs can be started from the fully loaded emulator and some system interfaces have been changed. Universal HelloExeDll uses a bit of preprocessor magic and can be compiled both for S60 3rd and 2nd edition. On the 3rd edition the project will be built as an EXE; on the 2nd edition it will be built as a usual ExeDll - as an EXE for hardware and as a DLL for WINS.
The 3rd edition of Nokia's S60 platform is all cool and new, but there are a lot of older devices you would still like to support.
The introduction of platform security in the 3rd edition changed the internals of the system a lot. However, from the point of view of the regular application programmer, changes are not that big and are mostly related to the configuration-like issues. We have to rewrite the MMP file, declare couple of things differently, use different type of icons, etc. - a lot of small things that you just have to carefully do once. As the end result of these small differences you'll have two projects with a bit different structure, a bit different set of files and minor changes in the application code.