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.

Archived:How to write an extended notifier to get a response from the user using Symbian C++

From Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

Article Metadata
Code ExampleTested with
Devices(s): Tested on: Nokia N78, 6210 Navigator
Compatibility
Platform(s): S60 3rd Edition FP2
S60 3rd Edition FP2
Article
Keywords: RNotifier, MEikSrvNotifierBase2
Created: User:Kbwiki (02 Nov 2009)
Last edited: hamishwillee (29 Jun 2012)

Contents

Overview

This article demonstrates how to customize the notifier to take input from the client (user).

Description

This solution describes how to use CAknTextQueryDialog inside a customized notifier to take input from the user and pass it to the client using this customized notifier.

Writing an extended notifier

To write a notifier, you need to implement a class derived from MEikSrvNotifierBase2. The code for the new notifier is placed in an ECom plug-in. The notifier server loads all the notifiers when it boots. The customize notifier is also derived from CActive.


Required capabilities

TrustedUI ProtServ


Customised Notifier class declaration

 class CNotifier1 : public CActive, public MEikSrvNotifierBase2
{
public:
static CNotifier1* NewLC();
~CNotifier1();
 
private:
CNotifier1();
void ConstructL();
 
public: // from MEikSrvNotifierBase2
void Release();
TNotifierInfo RegisterL();
TNotifierInfo Info() const;
void StartL( const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage );
TPtrC8 StartL( const TDesC8& aBuffer );
void Cancel();
TPtrC8 UpdateL( const TDesC8& aBuffer );
void UpdateL( const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage );
// Needed to support multiple screen orientations/modes
TInt NotifierCapabilites();
 
public: // from CActive
void RunL();
void DoCancel();
 
private: // data
TNotifierInfo iInfo;
TBuf<128> iBuffer;
TInt iReplySlot;
RMessagePtr2 iMessage;
CAknTextQueryDialog* iPwdQueryDlg;
CEikonEnv* iEikEnv;
TInt iOffset;
TBuf<256> iTempPasskeyBuffer;
TBuf8<256> iTempPasskeyBuffer8;
};


Implementation of CNotifier1::ConstructL()

 void CNotifier1::ConstructL()
{
iEikEnv = CEikonEnv::Static();
 
_LIT( KResourceFile, "\\resource\\apps\\Notifier1Dialog.rsc" );
TFileName resourceFileName( KResourceFile );
 
// Add the resource file to the list maintained by CCoeEnv
BaflUtils::NearestLanguageFile( iEikEnv->FsSession(), resourceFileName );
iOffset = iEikEnv->AddResourceFileL( resourceFileName );
}


Password query resource definition

 RESOURCE DIALOG R_ASK_PWORD_DIALOG
{
flags = EGeneralQueryFlags;
buttons = R_AVKON_SOFTKEYS_OK_CANCEL;
items =
{
DLG_LINE
{
type = EAknCtQuery;
id = EGeneralQuery;
control = AVKON_DATA_QUERY
{
layout = EDataLayout;
control = EDWIN
{
flags = EEikEdwinNoHorizScrolling | EEikEdwinResizable;
maxlength = 250;
width = 4;
lines = 1;
};
};
}
};
}


Implementation of StartL() (asynchronous version)

This is called as a result of a client-side call to the asynchronous function RNotifier::StartNotifierAndGetResponse(). This means that the client is waiting, asynchronously, for the notifier to tell the client that it has finished its work. It is important to return from this function as soon as possible, so we call SetActive() after copying aReplySlot and aMessage.

 void CNotifier1::StartL( const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage )
{
iMessage = aMessage;
iReplySlot = aReplySlot;
SetActive();
 
iStatus = KRequestPending;
TRequestStatus* stat = &iStatus;
User::RequestComplete( stat, KErrNone );
}


Implementation of RunL()

 void CNotifier1::RunL()
{
// This will hold the password entered by the user
iTempPasskeyBuffer.Zero();
 
// Constructing the text query dialog
iPwdQueryDlg = CAknTextQueryDialog::NewL( iTempPasskeyBuffer, CAknQueryDialog::EConfirmationTone );
 
// Setting the prompt
iPwdQueryDlg->SetPromptL( _L( "Enter Password" ) );
// Preparing with the user defined resource R_ASK_PWORD_DIALOG
iPwdQueryDlg->PrepareLC( R_ASK_PWORD_DIALOG );
iPwdQueryDlg->SetFocus( ETrue );
 
// Running the query dialog
if ( iPwdQueryDlg->RunLD() ) // OK pressed
{
// Copy the user entered value into a TBuf8
iTempPasskeyBuffer8.Copy( iTempPasskeyBuffer );
 
/* Writes data from the specified source descriptor to the specified offset
* within the 8-bit descriptor argument. Possible return values:
* KErrNone if successful
* KErrArgument if aParam is outside the valid range, or if aOffset < 0
* KErrBadDescriptor if the message argument is not an 8-bit descriptor
* KErrOverflow if the target descriptor is too small to contain data
*/

TInt err = iMessage.Write( iReplySlot, iTempPasskeyBuffer8 );
 
// Now free the message with KErrNone as reason
if ( !iMessage.IsNull() )
{
iMessage.Complete( KErrNone );
}
 
iReplySlot = NULL;
}
else // Cancel pressed
{
// Free the message with KErrCancel
if ( !iMessage.IsNull() )
{
iMessage.Complete( KErrCancel );
}
iReplySlot = NULL;
}
 
iPwdQueryDlg = NULL;
}


Cancelling the notifier

This is called as a result of a client-side call to RNotifier::CancelNotifier(). An implementation should free any relevant resources and complete any outstanding messages, if relevant.

  //delete the text query dialog
if( iPwdQueryDlg )
{
delete iPwdQueryDlg;
}
 
iPwdQueryDlg = NULL;
// Now free the message with KErrCancel as reason
if(!iMessage.IsNull())
{
iMessage.Complete(KErrCancel);
}
iReplySlot = NULL;
CActive::Cancel();


Using an extended notifier

Now, with the notifier UID, we can use the notifier. Note that we need to use RNotifier::StartNotifierAndGetResponse() in order to start the notifier and get a response from the user. Also note that we need to make sure the descriptor that we are passing to the notifier server as reference does not go out of scope while the server writes data into it. This can be achieved by using a data member of a class or by packaging the buffer using TPcgBuf.

 RNotifier notifierSession;
User::LeaveIfError(notifierSession.Connect());
CleanupClosePushL(notifierSession);
 
_LIT8( KNotifier1StartText, "Notifier1 Launched" );
 
// myapp is a pointer to a dummy class which contains member variables,-
// TRequestStatus notifStat;
// TBuf8<225> pinCode;
// TBuf8<225> dummy;
// TUid uid;
 
myapp->dummy.Copy( KNotifier1StartText );
// UID of the custom notifier
myapp->uid.iUid = 0x102826DC;
 
// Requests the extended notifier server to start the notifier identified by
// the specified UID. This is an asynchronous request - on return,
// myapp->pinCode will hold the value passed by the server, i.e. the value
// entered by the user.
 
notifierSession.StartNotifierAndGetResponse( myapp->notifStat,
myapp->uid,
myapp->dummy,
myapp->pinCode );
User::WaitForRequest( myapp->notifStat );
 
if( myapp->notifStat == KErrNone )
{
// The notifier server has successfully passed the data to the client as
// myapp->pinCode
}


Sample Code

File:CustomNotifier.zip

Related article

This page was last modified on 29 June 2012, at 05:13.
119 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.

×