Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

How to create a customised URI Scheme using Symbian C++

From Wiki
Jump to: navigation, search
Article Metadata
Tested with
Devices(s): Nokia N97 mini
Compatibility
Platform(s): S60 3rd edition FP1 and FP2, S60 5th Edition
Article
Keywords: SchemeHandler API, CSchemeHandler
Created: User:Kbwiki (23 Mar 2011)
Last edited: hamishwillee (14 Jun 2012)

Description

The scheme handler basically inspects the scheme type (eg. http, https, file, wtai, tel, cti,localapp, default types) and locates the appropriate application to handle the scheme (unknown schemes are ignored).

We can create a customised URI scheme handler to handle non-default scheme types. The following code demonstrates how to create a customised scheme "smart", detect the scheme, and get a handling request for it. When the user clicks on a string such as "smart:contacts" or "smart:messaging", the corresponding application is launched.

In the following code, the class SmartHandler is derived from the class BaseHandler. The BaseHandler class handles the launching of SchemeApp which loads and executes the correct implementation for an URL. It is also used when Scheme Handler is utilised in standalone mode.

The BaseHandler class is in turn derived from the SchemeHandler class. The Scheme Handler is an ECOM module which has the implementation for the schemes and is responsible for finding the correct implementation of URLs.


Source code

Resource file

RESOURCE REGISTRY_INFO theInfo
   {
   dll_uid = 0xE3B61A5B;
   interfaces = 
      {
      INTERFACE_INFO
         {
         interface_uid = SCHEME_INTERFACE_DEF;
         implementations = 
             {
             IMPLEMENTATION_INFO
                {
                implementation_uid = 0xE3B61A5B;
                version_no = 2;
                display_name = "URL handler for smarthandler:// scheme";
                default_data = "smart";//name should be small letters.
                opaque_data = "";
                }
             };
          }
       };
    }

MMP file

TARGET SmartDispatcher.dll
TARGETTYPE PLUGIN
UID 0x10009D8D 0xE3B61A5B
VENDORID 0
SOURCEPATH ../data
START RESOURCE 201f8531.rss
TARGET SmartDispatcher.rsc
END
CAPABILITY ALL -TCB
SOURCEPATH  ../src
SOURCE DllEntryPoint.cpp
SOURCE SchemeProxy.cpp
SOURCE BaseHandler.cpp
SOURCE SmartHandler.cpp
USERINCLUDE     ../inc
SYSTEMINCLUDE   /epoc32/include
SYSTEMINCLUDE   /epoc32/include/middleware
SYSTEMINCLUDE   /epoc32/include/ecom
SYSTEMINCLUDE   /epoc32/include/libc
SYSTEMINCLUDE   /epoc32/include/stdapis
LIBRARY ECOM.LIB
LIBRARY euser.lib
LIBRARY apgrfx.lib
LIBRARY apparc.lib
LIBRARY INETPROTUTIL.LIB
LIBRARY estor.lib
LIBRARY ServiceHandler.lib efsrv.lib
LIBRARY libc.lib
LIBRARY flogger.lib eikcore.lib

BaseHandler.h

#include <schemehandler.h>
#include <AknServerApp.h>
#include <centralrepository.h>
// UID of Scheme App.
LOCAL_D const TUid KUidSchemeApp = { SCHEME_APP_UID };
class CBaseHandler : public CSchemeHandler
   {
   public:    
     //Url Handler with embedding
     virtual void HandleUrlEmbeddedL() = 0;
     //Url Handler without embedding
     virtual void HandleUrlStandaloneL() = 0;
     //Observer
     void Observer( MAknServerAppExitObserver* aSchemeDoc );
   protected:
     //Constructor and Destructor
     CBaseHandler();
     virtual ~CBaseHandler();
     //Second phase constructor. Leaves on failure.
     void BaseConstructL( const TDesC& aUrl );
   protected:
     //Remove scheme from the begining of Url.
     TPtrC RemoveSchemeFromUrlL( const TDesC& aScheme );
     //Launch SchemeApp passing Generic Params List
     void LaunchSchemeAppWithCommandLineL();
   protected: 
     MAknServerAppExitObserver* iSchemeDoc; 
     HBufC* iParsedUrl;
   };

BaseHandler.cpp

CBaseHandler::CBaseHandler() : CSchemeHandler()
   {
    iSchemeDoc = NULL;
    } 
CBaseHandler::~CBaseHandler()
   {
    delete iParsedUrl;
    }
void CBaseHandler::BaseConstructL( const TDesC& aUrl )
   {
    iParsedUrl = EscapeUtils::EscapeDecodeL( aUrl );
    }
void CBaseHandler::Observer( MAknServerAppExitObserver* aSchemeDoc )
   {
    iSchemeDoc = aSchemeDoc;
    }
TPtrC CBaseHandler::RemoveSchemeFromUrlL( const TDesC& aScheme )
   {
    // Search the beginning of the Url 
    TInt schPos;
    schPos = iParsedUrl->Des().FindF( aScheme );
    if( schPos == KErrNotFound )
       {
       User::Leave( KErrNotFound );
       }
    // Get the Url without scheme 
    TPtrC path = iParsedUrl->Des().Right
    ( iParsedUrl->Des().Length() - ( schPos + aScheme.Length()) );
    if( 0 == path.Length() )
       {
       User::Leave( KErrArgument );
       }
    return path;
    }
void CBaseHandler::LaunchSchemeAppWithCommandLineL()
   {
   // Try launching...
   RApaLsSession appArcSession;
   User::LeaveIfError( appArcSession.Connect() );
   CleanupClosePushL<RApaLsSession>( appArcSession );
   TThreadId dummyId;
   TApaAppInfo aInfo;
   appArcSession.GetAppInfo( aInfo, KUidSchemeApp );
   CApaCommandLine* cmdLine = CApaCommandLine::NewL();
   CleanupStack::PushL( cmdLine );
   cmdLine->SetDocumentNameL( *iParsedUrl );
   cmdLine->SetCommandL( EApaCommandCreate );
   cmdLine->SetExecutableNameL( aInfo.iFullName );
   // Get the whole parameter list and put to the command line
   if ( iParamList )
     {
     TInt size = iParamList->Size();
     CBufFlat* store = CBufFlat::NewL( size );
     CleanupStack::PushL( store );
     RBufWriteStream outStream;
     outStream.Open( *store );
     CleanupClosePushL<RBufWriteStream>( outStream );
     iParamList->ExternalizeL( outStream );
     cmdLine->SetTailEndL( store->Ptr( 0 ) );
     CleanupStack::PopAndDestroy( 2 );  // store, close outStream
     }
   User::LeaveIfError( appArcSession.StartApp( *cmdLine,dummyId) );
   CleanupStack::PopAndDestroy( 2 ); // close appArcSession, cmdLine
   }

SmartHandler.h

#include <ecom/ecom.h>	
#include <apparc.h>
#include "BaseHandler.h"
//Scheme Handler implementation class for "smart" scheme
class CSmartHandler : public CBaseHandler
   {
   public:     
     // Constructors and destructor
     static CSmartHandler* NewL( const TDesC& aUrl );
     virtual ~CSmartHandler();
   private: 
     // Constructors   
     CSmartHandler(); 
     void ConstructL( const TDesC& aUrl );
   private: 
     // Functions from base classes
     // Url Handler with embedding
     void HandleUrlEmbeddedL();
     //Url Handler without embedding	
     void HandleUrlStandaloneL();     
     void NotifyClient();
   };

SmartHandler.cpp

_LIT( KPattern,"smart:");
CSmartHandler::CSmartHandler() : CBaseHandler()
   {
   // Deliberately do nothing here : See ConstructL() for initialisation 
   // completion.
   }
void CSmartHandler::ConstructL( const TDesC& aUrl )
   {
    BaseConstructL( aUrl );
   }
// Processes Url in embedded mode 
void CSmartHandler::HandleUrlEmbeddedL()
   {
    CEikonEnv::InfoWinL(_L("HandleUrlEmbeddedL "),_L("Entered"));
    TPtrC path;
    TInt err;
    TRAP( err, path.Set( RemoveSchemeFromUrlL( KPattern ) ) );
    if( err ==  KErrNone )
      {
       err = KErrCancel;
      }
    NotifyClient();
    ErrorHandlerL( err );
   }
//Process the Url in standalone mode
void CSmartHandler::HandleUrlStandaloneL()
   {
    CEikonEnv::InfoWinL(_L("HandleUrlStandaloneL "),_L("Entered"));
    LaunchSchemeAppWithCommandLineL();
   }
void CSmartHandler::NotifyClient()
   {
    if( NULL !=iSchemeDoc )
      {
        iSchemeDoc->HandleServerAppExit( KErrNone );
      }
   }


Sample application

File:SmartDispatcher.zip

This page was last modified on 14 June 2012, at 07:59.
73 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×