How to launch a browser from Symbian C++
Preamble / Rant
So you want to launch a browser from your nifty Symbian C++ app. And you hit the brick wall. Symbian doesn't provide an API. Series 60 doesn't provide an API. UIQ doesn't provide an API. You're all alone, lost in the wilderness with only feeble or non-existent documentation to help you. I spent months doing this so now, you don't have to.
Read this
No URL resolution service
As far as I know there is no ultra-clean way to do this. Symbian should have a system wide setting for "favorite browser" and a URL resolution service. But they don't.
No preferences
My code doesn't include the ability to set a preference. You could probably do that.
No checking the presence of different apps
My code doesn't check if Opera or whatever is actually there. I should probably do that. I probably will for my next version. I don't know how or if it's possible but it probably is possible to check the app registry or something to test for the apps.
On Series 60, I always choose Opera
My needs are for a real HTML browser. At the time I last changed this code none of the phones had a good built-in browser. So I would always default to Opera. I test to see if the phone is an old 3650-style device, which don't consistently have the memory to run Opera -- in that case I run Doris Browser, which is now archaic but was good for its time and place.
Times are changing. The latest Nokias (e.g. 6630) seem to have a good browser.
On UIQ, I always choose built-in browser
The built-in browser on the UIQ phones (e.g. P900) was good enough for me from the get-go so I just launch it.
Download Doris SDK
In order to launch the Doris Browser you'll need these source files:
Copy my code
For Series 60
Now we get to write some code.
First, we need a mechanism to choose browsers based on what hardware we're running on. We'll call them "WmlBrowser" (the built in browser which also sort-of does HTML); DorisBrowser; and OperaBrowser.
// UIDs of Browser applications const TInt KWmlBrowserUid = 0x10008D39; const TInt KOperaBrowserUid = 0x101F4DED; //const TInt KDorisBrowserUid = 0x101f81a8; // define this ONLY to OVERRIDE automatic browser selection // comment it out otherwise #define BROWSER_OVERRIDE EWmlBrowser //EOperaBrowser //EDorisBrowser //EWmlBrowser // from http://www.newlc.com/article.php3?id_article=161 const TInt K360036503660PhoneUid = 0x101f466a; TBrowser BestBrowser() { #ifdef BROWSER_OVERRIDE return BROWSER_OVERRIDE; #else TInt mUid = 0; HAL::Get(HALData::EMachineUid, mUid); if( mUid == K360036503660PhoneUid ) return EDorisBrowser; else return EOperaBrowser; #endif }
Now we have the method that starts the browser.
/* * MyStartBrowser(); * Start the correct browser and load the given URL into * that browser. */ void CMyClass::MyStartBrowser(const TDesC& aUrl) { HBufC* param = HBufC::NewL( 1024 ); TBrowser browser = BestBrowser(); TInt browserUid; switch( browser ) { case EWmlBrowser: browserUid = KWmlBrowserUid; break; case EOperaBrowser: browserUid = KOperaBrowserUid; break; } switch( browser ) { case EWmlBrowser: { // use the StartDocument api param->Des().Format( _L( "4 %S" ),&aUrl ); TUid id( TUid::Uid( browserUid ) ); TApaTaskList taskList( CEikonEnv::Static()->WsSession() ); TApaTask task = taskList.FindApp( id ); if ( task.Exists() ) { HBufC8* param8 = HBufC8::NewL( param->Length() ); param8->Des().Append( *param ); task.SendMessage( TUid::Uid( 0 ), *param8 ); // Uid is not used // CleanupStack::PopAndDestroy(); // param8 } else { RApaLsSession appArcSession; User::LeaveIfError( appArcSession.Connect() ); // connect to AppArc server TThreadId id; appArcSession.StartDocument( *param, TUid::Uid(browserUid), id ); appArcSession.Close(); } break; } case EOperaBrowser: { param->Des().Format( _L("%S"), &aUrl ); HBufC8* param8 = HBufC8::NewL( param->Length() ); param8->Des().Append( *param ); TUid KMyUidOperaBrowser = {0x101F4DED}; TVwsViewId viewId(KMyUidOperaBrowser, TUid::Uid(0)); (STATIC_CAST(CAknAppUi*, CEikonEnv::Static()->AppUi()))-> ActivateViewL(viewId, TUid::Uid(0), param8->Des() ); break; } case EDorisBrowser: { //use the Doris browser interface param->Des().Format( _L("%S"), &aUrl ); CUtility::DebugPrint(_L("using EDorisBrowser")); CDorisBrowserInterface *ido = CDorisBrowserInterface::NewLC(); ido->AppendL( CDorisBrowserInterface::EOpenURL_STRING, param->Des() ); CUtility::DebugPrint(param->Des()); ido->ExecuteL(); CleanupStack::PopAndDestroy(ido); break; } } }
After calling that, you might want to call this:
CBaActiveScheduler::Exit();
UIQ
This is really easy and uncomplicated.
void CTCamAppUi::OpenBrowserL(const TDesC& aURL) { TQWebDNLUrlEntry url; url.iUrl = aURL; TQWebDNLUrlEntryBuf urlBuf( url ); TVwsViewId viewId( KUidQWebApp, KUidQWebPageView ); (STATIC_CAST(CEikAppUi*, CEikonEnv::Static()-> AppUi()))->ActivateViewL( viewId, KQWebCustomMsgId, urlBuf ); }
Launches the built in browser.