Reading NDEF Messages

This tutorial describes how to read NDEF messages using the NFC Discovery API. This API provides access to NFC tags based on the NFC tag type or the NDEF message type. The NDEF messages are then read from NFC tags.

Prerequisites

Before you begin, refer to the following header files:
  • nfcserver.h

  • ndefmessagelistener.h

  • ndefdiscovery.h

  • ndefmessage.h

Steps

  1. Create a class that inherits the MNdefMessageListener and CBase classes.

  2. Add an MNdefMessageListener object to listen to the received NDEF-message actions using the CNdefDiscovery::AddNdefMessageListener() method.

    CActiveScheduler* iScheduler = new( ELeave ) CActiveScheduler();
    CActiveScheduler::Install( iScheduler );
    RNfcServer iNfcServer;
    iNfcServer.Open();
    CNdefDiscovery* iNdefDiscovery = CNdefDiscovery::NewL( iNfcServer );
    iNdefDiscovery->AddNdefMessageListener( *this );
  3. Subscribe NDEF messages to the NFC server using the CNdefDiscovery::AddNdefSubscription() method.

    CNdefRecord::TNdefRecordTnf tnf = CNdefRecord::ENfcWellKnown;
        {
        _LIT8( KSmartPoster, "Sp" );
        TInt error = iNdefDiscovery->AddNdefSubscription( tnf, KSmartPoster, 100 );
        if( KErrNone == error )
            {
            CActiveScheduler::Start();
            }
        }
    
  4. Implement the CMyNdefHandler::MessageDetected() method to receive NDEF messages.

    void CMyNdefHandler::MessageDetected( CNdefMessage* aMessage )
        {
        if( aMessage )
            {
            //
            // NDEF handling code...
            //
            
            delete aMessage;  
            }
        CActiveScheduler::Stop();
        }
    

Example

The following example illustrates how to register for receiving NDEF messages and how to receive messages using a callback function:

#include <e32base.h>
#include <nfcserver.h>
#include <ndefmessagelistener.h>
#include <ndefdiscovery.h>
#include <ndefmessage.h>

class CMyNdefHandler : public CBase, public MNdefMessageListener
    {
    
public:
    ~CMyNdefHandler();
    void StartNdefDiscoveryL();
    
public: // from MNdefMessageListener
    void MessageDetected( CNdefMessage* aMessage );
    
private: // data
    CActiveScheduler* iScheduler;
    CNdefDiscovery* iNdefDiscovery;
    RNfcServer iNfcServer;
    
    }
// -----------------------------------------------------------------------------
// CMyNdefHandler::~CMyNdefHandler
// -----------------------------------------------------------------------------
//
CMyNdefHandler::~CMyNdefHandler()
    {
    delete iScheduler;
    delete iNdefDiscovery;
    iNfcServer.Close();
    }

// -----------------------------------------------------------------------------
// CMyNdefHandler::StartNdefDiscovery
// -----------------------------------------------------------------------------
//
void CMyNdefHandler::StartNdefDiscoveryL()
    {
    iScheduler = new( ELeave ) CActiveScheduler();
    CActiveScheduler::Install( iScheduler );
    iNfcServer.Open();
    iNdefDiscovery = CNdefDiscovery::NewL( iNfcServer );
    iNdefDiscovery->AddNdefMessageListener( *this );
    CNdefRecord::TNdefRecordTnf tnf = CNdefRecord::ENfcWellKnown;
    _LIT8( KSmartPoster, "Sp" );
    TInt error = iNdefDiscovery->AddNdefSubscription( tnf, KSmartPoster, 100 );
    if( KErrNone == error )
        {
        CActiveScheduler::Start();
        }
    }

// -----------------------------------------------------------------------------
// CMyNdefHandler::MessageDetected
// From MNdefMessageListener
// -----------------------------------------------------------------------------
//
void CMyNdefHandler::MessageDetected( CNdefMessage* aMessage )
    {
    if( aMessage )
        {
        //
        // NDEF handling code here...
        //
        delete aMessage;  
        }
    
    CActiveScheduler::Stop();
    }

void mainDoL()
    {    
    CMyNdefHandler* handler = new( ELeave ) CMyNdefHandler();
    CleanupStack::PushL( handler );
    handler->StartNdefDiscoveryL();
    CleanupStack::PopAndDestroy( handler );
    }

TInt E32Main()
    {
    CTrapCleanup* cleanup = CTrapCleanup::New();
    TRAPD( err, mainDoL() );
    delete cleanup;
    return err;
    }