Hi,
I am developing an S60 3rd ed application for which one of the requisites is to launch a pre-installed Midlet.
I have basically been following this method to do so : http://wiki.forum.nokia.com/index.ph...60_3rd_Edition
Here is my code :
Code:/* ============================================================================ Name : MidletLaunchGUIAppUi.cpp ============================================================================ */ // INCLUDE FILES #include <avkon.hrh> #include <aknmessagequerydialog.h> #include <aknnotewrappers.h> #include <stringloader.h> #include <f32file.h> #include <s32file.h> #include <hlplch.h> #include <MidletLaunchGUI_0x2001FFC0.rsg> #include "MidletLaunchGUI_0x2001FFC0.hlp.hrh" #include "MidletLaunchGUI.hrh" #include "MidletLaunchGUI.pan" #include "MidletLaunchGUIApplication.h" #include "MidletLaunchGUIAppUi.h" #include "MidletLaunchGUIAppView.h" _LIT(KFileName, "C:\\private\\2001FFC0\\MidletLaunchGUI.txt"); _LIT(KText, "foooo!"); // midlet name _LIT(KMidletName, "HelloMIDlet"); // KVM virtual machine location on ROM drive _LIT(KMidRunROMLocation, "z:\\system\\programs\\kmidrun.exe"); // location of jad + jar _LIT(KMidletJadLocation, "c:\\system\\apps\\MidLaunch\\Hello.jad"); _LIT(KMidletJarLocation, "c:\\system\\apps\\MidLaunch\\Hello.jar"); _LIT(KMidletFakeExtension, ".fakeapp"); void CMidletLaunchGUIAppUi::FindMidletUIDL(){ //the caption we are looking for converted as a TBUF //TBuf<KApaMaxAppCaption> wantedCap; //wantedCap.Append(KMidletName); User::LeaveIfError( apaSession.Connect() ); CleanupClosePushL( apaSession ); User::LeaveIfError( apaSession.GetAllApps() ); while ( apaSession.GetNextApp( appInfo ) == KErrNone ) { // Caption of the MIDlet can be read from appInfo.iCaption // When the MIDlet to be launch is found, store its UID // (appInfo.iUid) for later use. TInt bla = appInfo.iFullName.Right(8).Compare(KMidletFakeExtension); if(bla == 0) { TBuf<KApaMaxAppCaption> appCaption; TInt found = appInfo.iCaption.Compare(KMidletName); if(found == 0){ KMidletUid = appInfo.iUid; } // _LIT(KMidletName, " " + ); } } } void CMidletLaunchGUIAppUi::LaunchMidletL() { TThreadId threadId; apaSession.StartDocument(_L(""), KMidletUid, threadId); TBuf<KMaxCommandLine> cmdLine; _LIT(KSeparator, "*"); // cmd line syntax: PortNumber*MIDletUid*MIDletName*JarLocation*JadLocation* cmdLine.AppendNum(KMidletPort); cmdLine.Append(KSeparator); // append a midlet uid in decimal format to the command line TBuf<16> uidNum; uidNum.Num(KMidletUid.iUid,EDecimal); cmdLine.Append(uidNum); cmdLine.Append(KSeparator); // append a midlet name to the command line cmdLine.Append(KMidletName); cmdLine.Append(KSeparator); // append a jar file location to the command line cmdLine.Append(KMidletJarLocation); cmdLine.Append(KSeparator); // append a jad file location to the command line cmdLine.Append(KMidletJadLocation); cmdLine.Append(KSeparator); // create a new process RProcess process; TInt error = process.Create(KMidRunROMLocation,cmdLine); User::LeaveIfError(error); // TODO: process should be renamed according to convention used with KVM process.Resume(); process.Close(); } // ============================ MEMBER FUNCTIONS =============================== // ----------------------------------------------------------------------------- // CMidletLaunchGUIAppUi::ConstructL() // Symbian 2nd phase constructor can leave. // ----------------------------------------------------------------------------- // void CMidletLaunchGUIAppUi::ConstructL() { // Initialise app UI with standard value. BaseConstructL(CAknAppUi::EAknEnableSkin); // Create view object iAppView = CMidletLaunchGUIAppView::NewL(ClientRect() ); // Create a file to write the text to TInt err = CCoeEnv::Static()->FsSession().MkDirAll(KFileName); if ( (KErrNone != err) && (KErrAlreadyExists != err)) { return; } RFile file; err = file.Replace(CCoeEnv::Static()->FsSession(), KFileName, EFileWrite); CleanupClosePushL(file); if (KErrNone != err) { CleanupStack::PopAndDestroy(1); // file return; } RFileWriteStream outputFileStream(file); CleanupClosePushL(outputFileStream); outputFileStream << KText; CleanupStack::PopAndDestroy(2); // outputFileStream, file FindMidletUIDL(); LaunchMidletL(); } // ----------------------------------------------------------------------------- // CMidletLaunchGUIAppUi::CMidletLaunchGUIAppUi() // C++ default constructor can NOT contain any code, that might leave. // ----------------------------------------------------------------------------- // CMidletLaunchGUIAppUi::CMidletLaunchGUIAppUi() { // No implementation required } // ----------------------------------------------------------------------------- // CMidletLaunchGUIAppUi::~CMidletLaunchGUIAppUi() // Destructor. // ----------------------------------------------------------------------------- // CMidletLaunchGUIAppUi::~CMidletLaunchGUIAppUi() { if (iAppView) { delete iAppView; iAppView = NULL; } } // ----------------------------------------------------------------------------- // CMidletLaunchGUIAppUi::HandleCommandL() // Takes care of command handling. // ----------------------------------------------------------------------------- // void CMidletLaunchGUIAppUi::HandleCommandL(TInt aCommand) { switch (aCommand) { case EEikCmdExit: case EAknSoftkeyExit: Exit(); break; case ECommand1: { // Load a string from the resource file and display it HBufC* textResource = StringLoader::LoadLC(R_COMMAND1_TEXT); CAknInformationNote* informationNote; informationNote = new ( ELeave ) CAknInformationNote; // Show the information Note with // textResource loaded with StringLoader. informationNote->ExecuteLD( *textResource); // Pop HBuf from CleanUpStack and Destroy it. CleanupStack::PopAndDestroy(textResource); } break; case ECommand2: { RFile rFile; //Open file where the stream text is User::LeaveIfError(rFile.Open(CCoeEnv::Static()->FsSession(), KFileName, EFileStreamText));//EFileShareReadersOnly));// EFileStreamText)); CleanupClosePushL(rFile); // copy stream from file to RFileStream object RFileReadStream inputFileStream(rFile); CleanupClosePushL(inputFileStream); // HBufC descriptor is created from the RFileStream object. HBufC* fileData = HBufC::NewLC(inputFileStream, 32); CAknInformationNote* informationNote; informationNote = new ( ELeave ) CAknInformationNote; // Show the information Note informationNote->ExecuteLD( *fileData); // Pop loaded resources from the cleanup stack CleanupStack::PopAndDestroy(3); // filedata, inputFileStream, rFile } break; case EHelp: { CArrayFix<TCoeHelpContext>* buf = CCoeAppUi::AppHelpContextL(); HlpLauncher::LaunchHelpApplicationL(iEikonEnv->WsSession(), buf); } break; case EAbout: { CAknMessageQueryDialog* dlg = new (ELeave)CAknMessageQueryDialog(); dlg->PrepareLC(R_ABOUT_QUERY_DIALOG); HBufC* title = iEikonEnv->AllocReadResourceLC(R_ABOUT_DIALOG_TITLE); dlg->QueryHeading()->SetTextL(*title); CleanupStack::PopAndDestroy(); //title HBufC* msg = iEikonEnv->AllocReadResourceLC(R_ABOUT_DIALOG_TEXT); dlg->SetMessageTextL(*msg); CleanupStack::PopAndDestroy(); //msg dlg->RunLD(); } break; default: Panic(EMidletLaunchGUIUi); break; } } // ----------------------------------------------------------------------------- // Called by the framework when the application status pane // size is changed. Passes the new client rectangle to the // AppView // ----------------------------------------------------------------------------- // void CMidletLaunchGUIAppUi::HandleStatusPaneSizeChange() { iAppView->SetRect(ClientRect() ); } CArrayFix<TCoeHelpContext>* CMidletLaunchGUIAppUi::HelpContextL() const { #warning "Please see comment about help and UID3..." // Note: Help will not work if the application uid3 is not in the // protected range. The default uid3 range for projects created // from this template (0xE0000000 - 0xEFFFFFFF) are not in the protected range so that they // can be self signed and installed on the device during testing. // Once you get your official uid3 from Symbian Ltd. and find/replace // all occurrences of uid3 in your project, the context help will // work. CArrayFixFlat<TCoeHelpContext>* array = new(ELeave)CArrayFixFlat<TCoeHelpContext>(1); CleanupStack::PushL(array); array->AppendL(TCoeHelpContext(KUidMidletLaunchGUIApp, KGeneral_Information)); CleanupStack::Pop(array); return array; } // End of File
The application automatically launches the midlet as expected but then silently dies and I need it to stay alive after the midlet was launched.
Moreover, if I comment out the LaunchMidlet() call in ConstructL() the application doesn't even seem to start.
So I guess the problem should be inside FindMidletUIDL() or somewhere nearby but I can't find where !
So any help appreciated. This is difficult for me to debug as I can't test it on the emulator and as I can't do on-device debugging ...
Thanks in advance

Reply With Quote



