Archived:Prompting the user to select a Bluetooth device using RNotifier
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 N95
Compatibility
Platform(s): S60 3rd Edition, FP1
Article
Keywords: RNotifier,TBTDeviceSelectionParamsPckg,
Created: aknyman
(16 Apr 2008)
Last edited: hamishwillee
(20 Jun 2012)
Contents |
Overview
This code snippet describes the Bluetooth device discovery mechanism provided by the S60 UI platform. The RNotifier class can be used to perform device discoveries where user interaction is required. By using the TBTDeviceSelectionParams class it is also possible to restrict the search to a more specific subset of devices.
This snippet can be self-signed.
MMP file
The following libraries are required:
LIBRARY bluetooth.lib
LIBRARY btextnotifiers.lib
LIBRARY btdevice.lib
Header file
#ifndef BTDEVICEFINDER_H_
#define BTDEVICEFINDER_H_
#include <e32base.h>
#include <BTExtNotifiers.h> //TBTDeviceSelectionParamsPckg,TBTDeviceResponseParamsPckg
class MBTDeviceFinderNotify
{
public:
virtual void BTDeviceSelected() = 0;
};
class CBTDeviceFinder: public CActive
{
public:
static CBTDeviceFinder* NewL(const TInt aPriority,
MBTDeviceFinderNotify& aNotify);
~CBTDeviceFinder();
public:
void DiscoverDevicesL();
void SetSelectionParams(const TBTDeviceSelectionParams& aFilter);
const TBTDeviceResponseParams& ResponseParams();
protected:
void RunL();
void DoCancel();
private:
CBTDeviceFinder(const TInt aPriority,MBTDeviceFinderNotify& aNotify);
void ConstructL(void);
private:
RNotifier iSelectorNotifier;
MBTDeviceFinderNotify& iNotify;
TBTDeviceSelectionParamsPckg iSelectParamsBuf;
TBTDeviceResponseParamsPckg iResponseParamsBuf;
TBool iConnected;
};
#endif /*BTDEVICEFINDER_H_*/
Source file
#include "BTDeviceFinder.h"
CBTDeviceFinder::CBTDeviceFinder(const TInt aPriority,
MBTDeviceFinderNotify& aNotify)
:CActive(aPriority),iNotify(aNotify),iConnected(EFalse)
{
}
CBTDeviceFinder::~CBTDeviceFinder()
{
Cancel();
if (iConnected)
{
iSelectorNotifier.CancelNotifier( KDeviceSelectionNotifierUid );
iSelectorNotifier.Close();
}
}
CBTDeviceFinder* CBTDeviceFinder::NewL(const TInt aPriority,
MBTDeviceFinderNotify& aNotify)
{
CBTDeviceFinder* self = new (ELeave) CBTDeviceFinder(aPriority,aNotify);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
void CBTDeviceFinder::ConstructL(void)
{
CActiveScheduler::Add(this);
}
void CBTDeviceFinder::DoCancel()
{
iSelectorNotifier.CancelNotifier( KDeviceSelectionNotifierUid );
}
void CBTDeviceFinder::RunL()
{
//the user has selected some device
if(iStatus.Int() == KErrNone)
{
iNotify.BTDeviceSelected();
}
else //an error has occurred
{
User::Leave(iStatus.Int());
}
}
void CBTDeviceFinder::DiscoverDevicesL()
{
if (!iConnected)
{
User::LeaveIfError(iSelectorNotifier.Connect());
iConnected = ETrue;
}
iSelectorNotifier.StartNotifierAndGetResponse(iStatus,
KDeviceSelectionNotifierUid,
iSelectParamsBuf,
iResponseParamsBuf);
SetActive();
}
void CBTDeviceFinder::SetSelectionParams(const TBTDeviceSelectionParams& aFilter)
{
iSelectParamsBuf = aFilter;
}
const TBTDeviceResponseParams& CBTDeviceFinder::ResponseParams()
{
return iResponseParamsBuf();
}
Using CBTDeviceFinder class
- In the header file:
class CBTDeviceFinder;
class CTestingAppUi : public CAknAppUi, MBTDeviceFinderNotify
{
public:
//...
//from MBTDeviceFinderNotify
void BTDeviceSelected();
//...
private:
//...
CBTDeviceFinder* iFinder;
};
- In the source file:
#include "btdevicefinder.h"
#include <btdevice.h> //TBTDeviceClass, TBTDeviceName
#include <bttypes.h> //TBTDevAddr
void CTestingAppUi::ConstructL()
{
CActive::TPriority priority(CActive::EPriorityUserInput);
iFinder = CBTDeviceFinder::NewL(priority, *this);
}
CTestingAppUi::~CTestingAppUi()
{
delete iFinder;
}
void CTestingAppUi::SelectDeviceL()
{
/* search only within a specific subset of devices
TBTDeviceSelectionParams selectionFilter;
TBTDeviceClass deviceFilter(EMajorServiceObjectTransfer, EMajorDevicePhone,
EMinorDevicePhoneUnclassified |
EMinorDevicePhoneCellular |
EMinorDevicePhoneCordless |
EMinorDevicePhoneSmartPhone |
EMinorDevicePhoneWiredModem |
EMinorDevicePhoneCommonISDNAccess );
selectionFilter.SetDeviceClass(deviceFilter);
iFinder->SetSelectionParams(selectionFilter);
*/
iFinder->DiscoverDevicesL();
}
void CTestingAppUi::BTDeviceSelected()
{
//Do something when BT device is selected
//e.g. get details of the device the user selected
//TBTDeviceResponseParams response = iFinder->ResponseParams();
//TBTDevAddr deviceAddress = response.BDAddr();
//TBTDeviceName deviceName = response.DeviceName();
//TBTDeviceClass deviceClass = response.DeviceClass();
}
Postconditions
The Bluetooth device selection dialog is shown to the user through the notifier framework.


possible bug
I tested this example while playing with bluetooth and Qt. The problem I found is when I try to discover devices, the first time goes ok, but the second try (and onwards) does not work because I get an error "bluetooth is in use". Bluetooth then keeps "locked" forever, and I have to reboot the device.
A solution I found is to delete the iFinder instance (in CTestingAppUi) before doing a new search (e.g. in SelectDeviceL()). This way, it works correctly.
I tested it with the S60 5th Ed SDK, Nokia 5800 and Qt 4.6.2.
lpvalente