Archived:Obtaining recent calls using Symbian C++
Archived: 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
Tested with
Devices(s): Nokia E61i
Nokia E90 Communicator
Nokia N95 8GB
Nokia 6220 Classic
Nokia E90 Communicator
Nokia N95 8GB
Nokia 6220 Classic
Compatibility
Platform(s): S60 3rd Edition, MR
S60 3rd Edition, FP1
S60 3rd Edition, FP2 Beta
S60 3rd Edition, FP1
S60 3rd Edition, FP2 Beta
Article
Keywords: CActive, CLogClient, CLogViewRecent, CLogEvent, RFs, CLogViewRecent::SetRecentListL(), CLogViewRecent::Event(), CLogViewRecent::NextL()
Created: tapiolaitinen
(03 Mar 2008)
Last edited: hamishwillee
(20 Jun 2012)
Contents |
Overview
This code example demonstrates how to obtain recent calls by using the S60 active object framework. In the example, recent calls are displayed on the screen one at a time.
MMP file
The following libraries are required:
LIBRARY logcli.lib
Header file
#ifndef __LOGHANDLER_H_
#define __LOGHANDLER_H_
#include <e32base.h>
#include <logcli.h> // CLogClient
#include <logview.h> // CLogViewRecent
enum TTask
{
EGetRecent,
ESleep
};
class CLogHandler : public CActive
{
public:
/**
* Symbian OS default constructor
*/
CLogHandler();
/**
* 2nd phase constructor.
*/
static CLogHandler* NewL();
/**
* 2nd phase constructor.
*/
static CLogHandler* NewLC();
/**
* Destructor
*/
~CLogHandler();
/**
* Reads recent events from the main event database
*/
void ReadRecentEventsL();
private:
/**
* Symbian 2-phase constructor
*/
void ConstructL();
/**
* From CActive
*/
void RunL();
/**
* From CActive
*/
TInt RunError(TInt anError);
/**
* From CActive
*/
void DoCancel();
/**
* Handles a single recent event.
*/
void HandleRecentEventL(const CLogEvent& anEvent);
private: // Data
RFs iFs;
CLogClient* iLogClient;
CLogViewRecent* iLogViewRecent;
TTask iTask; // Task for RunL
};
#endif /*__LOGHANDLER_H_*/
Source file
#include <aknnotewrappers.h>
#include <e32base.h>
#include <logcli.h> // CLogClient
#include <logview.h> // CLogViewRecent
#include <logwrap.h> // CLogEvent
#include "LogHandler.h"
/**
* Constructor. Defines the priority for this active object.
*/
CLogHandler::CLogHandler() : CActive(EPriorityStandard)
{
}
/**
* 2nd phase constructor.
*/
CLogHandler* CLogHandler::NewL()
{
CLogHandler* self = CLogHandler::NewLC();
CleanupStack::Pop(self);
return self;
}
/**
* 2nd phase constructor.
*/
CLogHandler* CLogHandler::NewLC()
{
CLogHandler* self = new (ELeave) CLogHandler();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
/**
* 2nd phase constructor.
*/
void CLogHandler::ConstructL()
{
User::LeaveIfError(iFs.Connect());
// Establish connection to log engine
iLogClient = CLogClient::NewL(iFs);
iLogViewRecent = CLogViewRecent::NewL(*iLogClient);
iTask = ESleep; // Default task for RunL
CActiveScheduler::Add(this);
}
/**
* Destructor.
*/
CLogHandler::~CLogHandler()
{
Cancel();
delete iLogViewRecent;
delete iLogClient;
iFs.Close();
}
/**
* From CActive.
*/
void CLogHandler::RunL()
{
switch (iTask)
{
case EGetRecent:
{
// Retrieve the event and handle it
HandleRecentEventL(iLogViewRecent->Event());
// If there are more events in the log engine database...
if (iLogViewRecent->NextL(iStatus))
{
if (iStatus == KErrNone)
{
// ... set active to get the next one
SetActive();
}
}
else
{
// No more events. Go to sleep.
iTask = ESleep;
}
break;
}
case ESleep:
default:
{
break;
}
}
}
/**
* From CActive.
*/
TInt CLogHandler::RunError(TInt anError)
{
return anError;
}
/**
* From CActive.
*/
void CLogHandler::DoCancel()
{
// Cancel the appropriate task
switch (iTask)
{
case EGetRecent:
{
iLogViewRecent->Cancel();
}
case ESleep:
default:
{
break;
}
}
}
/**
* Reads recent events from the main event database
*/
void CLogHandler::ReadRecentEventsL()
{
if (iLogViewRecent->SetRecentListL(KLogNullRecentList, iStatus))
{
if (iStatus == KErrNone)
{
// If there are events in the log view, set this active object active
// to get the events from the main event database. See RunL().
iTask = EGetRecent;
SetActive();
}
}
else
{
_LIT(KTxt, "No recent calls.");
CAknInformationNote* note = new (ELeave)CAknInformationNote(ETrue);
note->ExecuteLD(KTxt);
}
}
/**
* Displays a recent event in an information note.
*/
void CLogHandler::HandleRecentEventL(const CLogEvent& anEvent)
{
TBuf<255> buffer;
_LIT(KTxt, "Description: %S\nNumber: %S");
buffer.Format(KTxt, &(anEvent.Description()), &(anEvent.Number()));
CAknInformationNote* note = new (ELeave)CAknInformationNote(ETrue);
note->ExecuteLD(buffer);
}
Postconditions
Recent calls are displayed on the screen one at a time.


if (iLogViewRecent->SetRecentListL(KLogNullRecentList, iStatus)) { if (iStatus == KErrNone) { // If there are events in the log view, set this active object active // to get the events from the main event database. See RunL(). iTask = EGetRecent; SetActive(); } }Why is there check "iStatus == KErrNone"? SetActive() should be called ALWAYS if SetRecentListL returns ETrue. Panic E32USER-CBase 46 (stray signal) occurs if SetActive() is not called.
Notes to get this code works
I tried to use this code using Carbide.c++ with GUI framwork and I faced some troubles to get it works ( Thanks to sincere help from vineet.jain and symbianyucca )
1- You need to add - ReadUserData, WriteUserData,UserInviroment,LocalServices and Networkservices - to get it works , other wise the application wil show you "No Recent Calls.".
2- You need to remove
if (iStatus == KerrNone) from ReadRecentEventsL and RunL functions , to avoid CBase 46 panic.
To see the discussion about this Wiki visit this page:-
http://www.developer.nokia.com/Community/Discussion/showthread.php?220560-Always-No-recent-call&p=824686#post824686